value.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #ifndef HM_JSON_VALUE_H
  2. #define HM_JSON_VALUE_H
  3. #define IS_TYPE(type_a, type_b) std::is_same<type_a, type_b>::value
  4. #define GET_VALUE(type, pointer) *((type *) pointer)
  5. #define DIFFERENT_TYPE_ERR(type_name) std::logic_error("Error: expected type is <" + type_name + ">")
  6. #include <string>
  7. #include <vector>
  8. #include <map>
  9. #include <variant>
  10. #include <stdexcept>
  11. namespace json {
  12. class Value;
  13. enum TYPE {
  14. NullType, BoolType, IntType, DecimalType, StringType, ListType, DictType
  15. };
  16. std::string const _typeIdToName[] = {"Null", "Bool", "Int", "Decimal", "String", "List", "Dict"}; // NOLINT
  17. using null_type = char;
  18. using bool_type = bool;
  19. using int_type = long;
  20. using decimal_type = double;
  21. using string_type = std::string;
  22. using list_type = std::vector<Value>;
  23. using dict_type = std::map<std::string, Value>;
  24. class Value {
  25. public:
  26. Value();
  27. explicit Value(bool_type const &value);
  28. explicit Value(int const &value);
  29. explicit Value(int_type const &value);
  30. explicit Value(decimal_type const &value);
  31. explicit Value(string_type const &value);
  32. explicit Value(const char *value);
  33. explicit Value(list_type const &value);
  34. explicit Value(dict_type const &value);
  35. template<class T>
  36. [[nodiscard]] T &value();
  37. [[nodiscard]] constexpr TYPE type_id() const;
  38. [[nodiscard]] std::string type_name() const;
  39. [[nodiscard]] constexpr bool is_basic() const;
  40. [[nodiscard]] std::string str(bool const &format_need = false, int const &indent = 2, int layer = 1);
  41. void push_back(Value const &value);
  42. void pop_back();
  43. void erase(int const &index);
  44. void erase(std::string const &key);
  45. Value &operator[](int const &index);
  46. Value &operator[](std::string const &key);
  47. private:
  48. // null: string
  49. using data_type = std::variant<bool_type, int_type, decimal_type, string_type, list_type, dict_type>;
  50. TYPE _type;
  51. data_type _data;
  52. void *_value();
  53. };
  54. template<class T>
  55. T &Value::value() {
  56. if constexpr (IS_TYPE(T, null_type)) {
  57. if (_type != NullType) throw DIFFERENT_TYPE_ERR(_typeIdToName[NullType]);
  58. } else if constexpr (IS_TYPE(T, bool_type)) {
  59. if (_type != BoolType) throw DIFFERENT_TYPE_ERR(_typeIdToName[BoolType]);
  60. } else if constexpr (IS_TYPE(T, int_type)) {
  61. if (_type != IntType) throw DIFFERENT_TYPE_ERR(_typeIdToName[IntType]);
  62. } else if constexpr (IS_TYPE(T, decimal_type)) {
  63. if (_type != DecimalType) throw DIFFERENT_TYPE_ERR(_typeIdToName[DecimalType]);
  64. } else if constexpr (IS_TYPE(T, string_type)) {
  65. if (_type != StringType) throw DIFFERENT_TYPE_ERR(_typeIdToName[StringType]);
  66. } else if constexpr (IS_TYPE(T, list_type)) {
  67. if (_type != ListType) throw DIFFERENT_TYPE_ERR(_typeIdToName[ListType]);
  68. } else if constexpr (IS_TYPE(T, dict_type)) {
  69. if (_type != DictType) throw DIFFERENT_TYPE_ERR(_typeIdToName[DictType]);
  70. }
  71. return *((T *) _value());
  72. }
  73. }
  74. #endif //HM_JSON_VALUE_H