123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #ifndef HM_JSON_VALUE_H
- #define HM_JSON_VALUE_H
- #define IS_TYPE(type_a, type_b) std::is_same<type_a, type_b>::value
- #define GET_VALUE(type, pointer) *((type *) pointer)
- #define DIFFERENT_TYPE_ERR(type_name) std::logic_error("Error: expected type is <" + type_name + ">")
- #include <string>
- #include <vector>
- #include <map>
- #include <variant>
- #include <stdexcept>
- namespace json {
- class Value;
- enum TYPE {
- NullType, BoolType, IntType, DecimalType, StringType, ListType, DictType
- };
- std::string const _typeIdToName[] = {"Null", "Bool", "Int", "Decimal", "String", "List", "Dict"}; // NOLINT
- using null_type = char;
- using bool_type = bool;
- using int_type = long;
- using decimal_type = double;
- using string_type = std::string;
- using list_type = std::vector<Value>;
- using dict_type = std::map<std::string, Value>;
- class Value {
- public:
- Value();
- explicit Value(bool_type const &value);
- explicit Value(int const &value);
- explicit Value(int_type const &value);
- explicit Value(decimal_type const &value);
- explicit Value(string_type const &value);
- explicit Value(const char *value);
- explicit Value(list_type const &value);
- explicit Value(dict_type const &value);
- template<class T>
- [[nodiscard]] T &value();
- [[nodiscard]] constexpr TYPE type_id() const;
- [[nodiscard]] std::string type_name() const;
- [[nodiscard]] constexpr bool is_basic() const;
- [[nodiscard]] std::string str(bool const &format_need = false, int const &indent = 2, int layer = 1);
- void push_back(Value const &value);
- void pop_back();
- void erase(int const &index);
- void erase(std::string const &key);
- Value &operator[](int const &index);
- Value &operator[](std::string const &key);
- private:
- // null: string
- using data_type = std::variant<bool_type, int_type, decimal_type, string_type, list_type, dict_type>;
- TYPE _type;
- data_type _data;
- void *_value();
- };
- template<class T>
- T &Value::value() {
- if constexpr (IS_TYPE(T, null_type)) {
- if (_type != NullType) throw DIFFERENT_TYPE_ERR(_typeIdToName[NullType]);
- } else if constexpr (IS_TYPE(T, bool_type)) {
- if (_type != BoolType) throw DIFFERENT_TYPE_ERR(_typeIdToName[BoolType]);
- } else if constexpr (IS_TYPE(T, int_type)) {
- if (_type != IntType) throw DIFFERENT_TYPE_ERR(_typeIdToName[IntType]);
- } else if constexpr (IS_TYPE(T, decimal_type)) {
- if (_type != DecimalType) throw DIFFERENT_TYPE_ERR(_typeIdToName[DecimalType]);
- } else if constexpr (IS_TYPE(T, string_type)) {
- if (_type != StringType) throw DIFFERENT_TYPE_ERR(_typeIdToName[StringType]);
- } else if constexpr (IS_TYPE(T, list_type)) {
- if (_type != ListType) throw DIFFERENT_TYPE_ERR(_typeIdToName[ListType]);
- } else if constexpr (IS_TYPE(T, dict_type)) {
- if (_type != DictType) throw DIFFERENT_TYPE_ERR(_typeIdToName[DictType]);
- }
- return *((T *) _value());
- }
- }
- #endif //HM_JSON_VALUE_H
|