Program Listing for File constvariant.h#

Return to documentation for file (sdv_idl_compiler\constvariant.h)

#ifndef VARIANT_H
#define VARIANT_H

#include <variant>
#include <string>
#include <type_traits>
#include <limits>
#include <cstdint>

struct fixed
{
    double dValue;
    template <typename TType>
    constexpr fixed(TType tValue) : dValue(static_cast<double>(tValue)) {}
    template <typename TType>
    constexpr fixed& operator=(TType tValue) { dValue = tValue; return *this; }
    constexpr operator double() const {return dValue;}
    constexpr operator const double&() const {return dValue;}
    constexpr operator double&() {return dValue;}
    fixed constexpr operator+() const {return *this;}
    fixed constexpr operator-() const {return fixed(-dValue);}
};

inline fixed operator+(fixed val1, fixed val2) { return val1.dValue + val2.dValue; }
inline fixed operator-(fixed val1, fixed val2) { return val1.dValue - val2.dValue; }
inline fixed operator*(fixed val1, fixed val2) { return val1.dValue * val2.dValue; }
inline fixed operator/(fixed val1, fixed val2) { return val1.dValue / val2.dValue; }
inline bool operator<(fixed val1, fixed val2) { return val1.dValue < val2.dValue; }
inline bool operator<(fixed val1, double val2) { return val1.dValue < val2; }
inline bool operator<(double val1, fixed val2) { return val1 < val2.dValue; }
inline bool operator<=(fixed val1, fixed val2) { return val1.dValue <= val2.dValue; }
inline bool operator<=(fixed val1, double val2) { return val1.dValue <= val2; }
inline bool operator<=(double val1, fixed val2) { return val1 <= val2.dValue; }
inline bool operator>(fixed val1, fixed val2) { return val1.dValue > val2.dValue; }
inline bool operator>(fixed val1, double val2) { return val1.dValue > val2; }
inline bool operator>(double val1, fixed val2) { return val1 > val2.dValue; }
inline bool operator>=(fixed val1, fixed val2) { return val1.dValue >= val2.dValue; }
inline bool operator>=(fixed val1, double val2) { return val1.dValue >= val2; }
inline bool operator>=(double val1, fixed val2) { return val1 >= val2.dValue; }
inline bool operator==(fixed val1, fixed val2) { return val1.dValue == val2.dValue; }
inline bool operator==(fixed val1, double val2) { return val1.dValue == val2; }
inline bool operator==(double val1, fixed val2) { return val1 == val2.dValue; }
inline bool operator!=(fixed val1, fixed val2) { return val1.dValue != val2.dValue; }
inline bool operator!=(fixed val1, double val2) { return val1.dValue != val2; }
inline bool operator!=(double val1, fixed val2) { return val1 != val2.dValue; }
namespace std
{
#ifndef DOXYGEN_IGNORE
    template <>
    inline constexpr bool is_floating_point_v<::fixed> = true;

    template <>
    inline constexpr bool is_signed_v<::fixed> = true;

    template <>
    inline constexpr bool is_arithmetic_v<::fixed> = true;
#endif

    template <>
    struct numeric_limits<::fixed> : numeric_limits<double>
    {
        [[nodiscard]] static constexpr ::fixed(min)() noexcept
        {
            return 1.0 / static_cast<double>(max());
        }

        [[nodiscard]] static constexpr ::fixed(max)() noexcept
        {
            // 31 bits available
            return 1ll << 31ll;
        }

        [[nodiscard]] static constexpr ::fixed lowest() noexcept
        {
            return -(max)();
        }
    };
}

class CConstVariant
{
    using TVariant = std::variant<bool, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, fixed, float,
    double, long double, std::string, std::u16string, std::u32string, std::wstring>;
public:
    enum ETypeMapping
    {
        type_bool = 0, type_int8_t, type_uint8_t, type_int16_t, type_uint16_t, type_int32_t, type_uint32_t, type_int64_t,
        type_uint64_t, type_fixed, type_float, type_double, type_long_double, type_string, type_u16string, type_u32string,
        type_wstring,
    };

    CConstVariant() = default;

    CConstVariant(const CConstVariant& rvar);

    CConstVariant(CConstVariant&& rvar) noexcept;

    CConstVariant(bool bValue);

    CConstVariant(int8_t iValue);

    CConstVariant(uint8_t uiValue);

    CConstVariant(int16_t iValue);

    CConstVariant(uint16_t uiValue);

#ifdef _WIN32
    CConstVariant(long int iValue);

    CConstVariant(unsigned long int uiValue);
#endif

    CConstVariant(int32_t iValue);

    CConstVariant(uint32_t uiValue);

    CConstVariant(int64_t iValue);

#if defined(__GNUC__) && !defined(_WIN32)
     CConstVariant(long long int iValue);

     CConstVariant(unsigned long long int uiValue);
 #endif

    CConstVariant(uint64_t uiValue);

    CConstVariant(fixed fixValue);

    CConstVariant(float fValue);

    CConstVariant(double dValue);

    CConstVariant(long double ldValue);

    CConstVariant(const std::string& rssValue);

    CConstVariant(const std::u16string& rssValue);

    CConstVariant(const std::u32string& rssValue);

    CConstVariant(const std::wstring& rssValue);

    CConstVariant& operator=(const CConstVariant& rvar);

    CConstVariant& operator=(CConstVariant&& rvar) noexcept;

    template <typename TType>
    CConstVariant& operator=(const TType& rtValue);

    template <typename TTargetType>
    TTargetType Get() const;

    std::string GetAsString() const;

    bool IsArithmetic() const;
    bool IsIntegral() const;
    bool IsFloatingPoint() const;
    bool IsBoolean() const;
    bool IsSigned() const;
    bool IsUnsigned() const;
    size_t Ranking() const;
    template <typename TType> bool IsSame() const;
    void Convert(size_t nRank);

    template <typename TType>
    void Convert();

    CConstVariant operator!() const;
    CConstVariant operator~() const;
    CConstVariant operator+() const;
    CConstVariant operator-() const;
    template <typename TFunction>
    static CConstVariant UnaryOperation(const CConstVariant& rvarOperand, TFunction tOperation);
    template <typename TFunction>
    static CConstVariant UnaryOperationIntegral(const CConstVariant& rvarOperand, TFunction tOperation);
    template <typename TFunction>
    static CConstVariant BinaryOperation(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2,
        TFunction tOperation);
    template <typename TFunction>
    static CConstVariant BinaryOperationIntegral(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2,
        TFunction tOperation);
private:
    template <typename TTargetType, typename TVariantType>
    TTargetType InternalGet() const;

    TVariant    m_varValue;

};

void Equalize(CConstVariant& rvar1, CConstVariant& rvar2);

CConstVariant operator*(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator/(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator+(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator-(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator<(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator<=(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator>(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator>=(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator+(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator==(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator!=(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator%(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator<<(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator>>(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator&(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator^(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator|(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator&&(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
CConstVariant operator||(const CConstVariant& rvarOperand1, const CConstVariant& rvarOperand2);
#endif // !defined(VARIANT_H)