File indexing completed on 2024-06-16 04:23:16

0001 /*
0002     SPDX-FileCopyrightText: 2002-2005 Roberto Raggi <roberto@kdevelop.org>
0003     SPDX-FileCopyrightText: 2006 Adam Treat <treat@kde.org>
0004     SPDX-FileCopyrightText: 2006-2008 Hamish Rodda <rodda@kde.org>
0005     SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-only
0008 */
0009 
0010 #ifndef KDEVPLATFORM_CONSTANTINTEGRALTYPE_H
0011 #define KDEVPLATFORM_CONSTANTINTEGRALTYPE_H
0012 
0013 #include "integraltype.h"
0014 #include "typesystemdata.h"
0015 
0016 namespace KDevelop {
0017 template <typename T>
0018 T constant_value(const qint64* realval)
0019 {
0020     T value;
0021     memcpy(&value, realval, sizeof(T));
0022     return value;
0023 }
0024 
0025 class KDEVPLATFORMLANGUAGE_EXPORT ConstantIntegralType
0026     : public IntegralType
0027 {
0028 public:
0029     ConstantIntegralType(const ConstantIntegralType& rhs);
0030 
0031     explicit ConstantIntegralType(ConstantIntegralTypeData& data);
0032 
0033     explicit ConstantIntegralType(uint type = TypeNone);
0034 
0035     ConstantIntegralType& operator=(const ConstantIntegralType& rhs) = delete;
0036 
0037     using Ptr = TypePtr<ConstantIntegralType>;
0038 
0039     /**The types and modifiers are not changed!
0040      * The values are casted internally to the local representation, so you can lose precision.
0041      * */
0042     template <class ValueType>
0043     void setValue(ValueType value)
0044     {
0045         if (AbstractType::modifiers() & UnsignedModifier)
0046             setValueInternal<quint64>(value);
0047         else if (IntegralType::dataType() == TypeHalf)
0048             setValueInternal<float>(value);
0049         else if (IntegralType::dataType() == TypeFloat)
0050             setValueInternal<float>(value);
0051         else if (IntegralType::dataType() == TypeDouble)
0052             setValueInternal<double>(value);
0053         else
0054             setValueInternal<qint64>(value);
0055     }
0056 
0057     /**
0058      * For booleans, the value is 1 for true, and 0 for false.
0059      * All signed values should be retrieved and set through value(),
0060      *
0061      * */
0062     template <class ValueType>
0063     ValueType value() const
0064     {
0065         if (modifiers() & UnsignedModifier) {
0066             return constant_value<quint64>(&d_func()->m_value);
0067         } else if (dataType() == TypeHalf) {
0068             return constant_value<float>(&d_func()->m_value);
0069         } else if (dataType() == TypeFloat) {
0070             return constant_value<float>(&d_func()->m_value);
0071         } else if (dataType() == TypeDouble) {
0072             return constant_value<double>(&d_func()->m_value);
0073         } else {
0074             return constant_value<qint64>(&d_func()->m_value);
0075         }
0076     }
0077 
0078     qint64 plainValue() const;
0079 
0080     QString toString() const override;
0081 
0082     QString valueAsString() const;
0083 
0084     bool equals(const KDevelop::AbstractType* rhs) const override;
0085 
0086     KDevelop::AbstractType* clone() const override;
0087 
0088     uint hash() const override;
0089 
0090     enum {
0091         Identity = 14
0092     };
0093 
0094     using Data = ConstantIntegralTypeData;
0095 
0096 protected:
0097     TYPE_DECLARE_DATA(ConstantIntegralType);
0098 
0099 private:
0100     //Sets the value without casting
0101     template <class ValueType>
0102     void setValueInternal(ValueType value);
0103 };
0104 }
0105 
0106 #endif // KDEVPLATFORM_CONSTANTINTEGRALTYPE_H