dimanche 20 août 2017

Efficient Value type

I want to create efficient and easy to use value type. Base of the Value is a boost::variant (and std::variant in the future), but I'm new in it. And I have some questions:

  • In the code below, is it necessary to use recursive variant?
  • Is it possible to not inherit from the boost::variant? Maybe more efficient way exists?
  • Do you have any comments or suggestions on the code below (it's not fully completed code, but only a draft)?

    class Value;

    typedef std::string                 String;
    typedef std::vector<char>           BinData;
    typedef String                      URL;
    typedef unsigned long long          UID;
    TSW_STRONG_TYPEDEF(std::time_t, Time)

    typedef std::vector<Value>          ValueArray;
    typedef std::vector<String>         StringArray;
    //typedef std::pair<String, Value>    NameValue;

    typedef std::list<Value>            ValueList;
    typedef std::list<String>           StringList;
    typedef std::map<String, String>    StringStringMap;
    typedef std::map<String, Value>     NameValueMap;

    struct monostate
    {
        monostate() = default;
    };

    constexpr bool operator<(monostate, monostate) noexcept { return false; }
    constexpr bool operator>(monostate, monostate) noexcept { return false; }
    constexpr bool operator<=(monostate, monostate) noexcept { return true; }
    constexpr bool operator>=(monostate, monostate) noexcept { return true; }
    constexpr bool operator==(monostate, monostate) noexcept { return true; }
    constexpr bool operator!=(monostate, monostate) noexcept { return false; }


    typedef monostate Null;


    struct Object
    {
        Object() = default;
        Object(const Object &other) = default;
        Object(Object &&other);
        Object &operator=(const Object &other) = default;
        Object &operator=(Object &&other);

        String name;
        NameValueMap fields;

        bool operator<(const Object &other) const noexcept;
        bool operator>(const Object &other) const noexcept;
        bool operator<=(const Object &other) const noexcept;
        bool operator>=(const Object &other) const noexcept;
        bool operator==(const Object &other) const noexcept;
        bool operator!=(const Object &other) const noexcept;
    };


    enum class ValueType
    {
        Null = 1, Array, BinData, Boolean, DoubleNumber, Int64Number, String, Time, Object, Undefined
    };

    // Types ordnung need to be same with ValueType ordnung.
    typedef boost::variant<monostate, ValueArray, BinData, bool, double, int64_t, String, Time, Object> ValueBase;

    class Value : public ValueBase
    {
    public:
        using ValueBase::ValueBase;
        Value() = default;
    public:
        bool        can_convert(ValueType targetTypeId) const;
        bool        is_array() const;
        bool        is_bool() const;
        bool        is_double() const;
        bool        is_int64() const;
        bool        is_null() const;
        bool        is_object() const;
        bool        is_string() const;
        bool        is_bindata() const;
        bool        is_time() const;
        bool        is_undefined() const;
    public:
        ValueArray    &to_value_array();
        bool          to_bool() const;
        double        to_double() const;
        int           to_int() const;
        int64_t       to_int64() const;
        Object        &to_object();
        String        &to_string();
        BinData       &to_bindata();
        Time          &to_time();
        ValueType     type() const;
    public:
        template <typename T>
        const T& as() const { return boost::get<T> (*this); }
        template <typename T>
        T& as() { return boost::get<T> (*this); }
    private:
        // force compile error, prevent Variant(bool) to be called
        Value(void *) = delete;
    };



Aucun commentaire:

Enregistrer un commentaire