File indexing completed on 2024-04-28 03:40:46

0001 /*************************************************************************************
0002  *  Copyright (C) 2007 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #ifndef VALUE_H
0020 #define VALUE_H
0021 
0022 #include "object.h"
0023 #include "analitzaexport.h"
0024 
0025 #include <cmath>
0026 #include <complex>
0027 
0028 class QDomElement;
0029 
0030 namespace Analitza
0031 {
0032 
0033 /**
0034  * \class Cn
0035  * 
0036  * \ingroup AnalitzaModule
0037  *
0038  * \brief Cn is a value in MathML.
0039  *
0040  * The Cn class is the one that represents a value in the expression trees.
0041  */
0042 
0043 class ANALITZA_EXPORT Cn : public Object
0044 {
0045     public:
0046         enum ValueFormat { Char=8, Real=7, Integer=3, Boolean=1, Complex=0x10|Real };
0047         /** Copy constructor. Creates a Cn from another one. */
0048         Cn(const Cn& v) : Object(v), m_value(v.m_value), m_imaginaryPart(v.m_imaginaryPart), m_format(v.m_format) { Q_ASSERT(m_type==Object::value); }
0049 
0050         /** Constructor. Creates a boolean value with @p b. */
0051         explicit Cn(const double &b=0.) : Object(Object::value), m_value(b), m_imaginaryPart(0), m_format(Real) {}
0052 
0053         /** Constructor. Creates an integer value with @p i. */
0054         explicit Cn(int i) : Object(Object::value), m_value(i), m_imaginaryPart(0), m_format(Integer) {}
0055 
0056         /** @copydoc */
0057         explicit Cn(uint i) : Object(Object::value), m_value(i), m_imaginaryPart(0), m_format(Integer) {}
0058 
0059         /** Constructor. Creates a boolean value with value @p b. */
0060         explicit Cn(bool b) : Object(Object::value), m_value(b?1.:0.), m_imaginaryPart(0), m_format(Boolean) {}
0061 
0062         /** Constructor. Creates a value that represents a character. */
0063         explicit Cn(const QChar& c) : Object(Object::value), m_char(c.unicode()), m_imaginaryPart(0), m_format(Char) {}
0064 
0065         /** Constructor. Creates a value that represents a complex. */
0066         explicit Cn(double value, double imaginaryPart) : Object(Object::value), m_value(value), m_imaginaryPart(imaginaryPart), m_format(Complex) {}
0067         
0068         /**
0069          *    Extracts the number from the @p e Dom element and saves it.
0070          */
0071         bool setValue(const QDomElement& e);
0072 
0073         /**
0074          *    Sets the new value of this function
0075          *    @param v the new value
0076          */
0077         void setValue(const double& v);
0078         void setValue(int v);
0079         void setValue(uint v);
0080         void setValue(bool v);
0081         void setValue(std::complex<double> v);
0082 
0083         /**
0084          *    Returns the value.
0085          */
0086         inline double value() const { return m_value; }
0087         inline double& rvalue() { return m_value; }
0088 
0089         /**
0090          *    @returns the value as an int.
0091          */
0092         int intValue() const { return static_cast<int>(std::floor(m_value)); }
0093 
0094         /**
0095          *    @returns whether it is a boolean value or not.
0096          */
0097         bool isBoolean() const { return m_format==Boolean; }
0098 
0099         /**
0100          *    @returns whether it is a character value or not.
0101          */
0102         bool isCharacter() const { return m_format==Char; }
0103 
0104         ValueFormat format() const { return m_format; }
0105 
0106         /**
0107          *    @return If it is a boolean value, returns if it is true or not, otherwise retuns false.
0108          */
0109         bool isTrue() const { Q_ASSERT(m_format==Boolean); return m_value!=0.; }
0110 
0111 //         static double toNum(const QString& num, const QString& type, int base);
0112 //         static enum ValueFormat whatValueFormat(const QDomElement&);
0113 
0114         /**
0115          *    @returns whether it is an integer value or not.
0116          */
0117         bool isInteger() const { return m_format&Integer && std::floor(m_value)==m_value; }
0118 
0119         /**
0120          *    @returns whether @p d is equal than this object.
0121          */
0122         bool operator==(const Cn& d) const;
0123 
0124         /**
0125          *    @returns whether @p d is less than this object.
0126          */
0127         bool operator<(const Cn& d) const { return m_value<d.m_value; }
0128 
0129         /**
0130          *    @returns whether @p d is less than this object's value.
0131          */
0132         bool operator<(double d) const { return m_value<d; }
0133 
0134         /**
0135          *    @returns whether @p d is less or equal than this object.
0136          */
0137         bool operator<=(const Cn& d) const { return m_value<=d.m_value; }
0138 
0139         /**
0140          *    @returns whether @p d is less or equal than this object's value.
0141          */
0142         bool operator<=(double d) const { return m_value<=d; }
0143 
0144         /**
0145          *    Sets the new value to @p d.
0146          */
0147         Cn operator=(double d) { m_value=d; m_format=Real; return *this; }
0148 
0149         QChar character() const { Q_ASSERT(m_format==Char); return QChar(m_char); }
0150 
0151         /** @returns whether the value has an imaginary part */
0152         bool isComplex() const { return m_format == Complex && m_imaginaryPart!=0.; }
0153 
0154         virtual QVariant accept(AbstractExpressionVisitor*) const override;
0155         virtual bool isZero() const override { return m_value==0. && m_imaginaryPart==0.; }
0156 
0157         virtual bool matches(const Object* exp, QMap< QString, const Object* >* found) const override;
0158         /*/** Sets whether it is a correct Cn.
0159         void setCorrect(bool b) {m_correct = b; }*/
0160 
0161         std::complex<double> complexValue() const;
0162 
0163         virtual Object* copy() const override;
0164 
0165         static Cn pi();
0166         static Cn e();
0167         static Cn euler();
0168     private:
0169         union { double m_value; ushort m_char; };
0170         double m_imaginaryPart = 0.;
0171         enum ValueFormat m_format;
0172 };
0173 
0174 }
0175 
0176 #endif