43 using Array = std::vector<SValue>;
44 using Object = std::map<std::string, SValue, std::less<>>;
46 enum Type { kNull, kBool, kInt, kDouble, kString, kArray, kObject };
49 SValue() : data_(
nullptr) {}
51 SValue(std::nullptr_t) : data_(
nullptr) {}
53 SValue(
bool b) : data_(b) {}
55 template <
typename T, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
56 SValue(T int_num) : data_(
static_cast<i64>(int_num)) {}
58 template <
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
59 SValue(T real_num) : data_(
static_cast<double>(real_num)) {}
61 template <
typename T, std::enable_if_t<std::is_constructible_v<std::
string, T>>* =
nullptr>
62 SValue(T&& str) : data_(std::string(std::forward<T>(str))) {}
64 SValue(
const Array& a) : data_(a) {}
65 SValue(Array&& a) noexcept : data_(std::move(a)) {}
67 SValue(
const Object& o) : data_{o} {}
68 SValue(Object&& o) noexcept : data_(std::move(o)) {}
70 SValue(std::initializer_list<SValue> init);
74 SValue(
const SValue&) =
default;
76 SValue(SValue&&)
noexcept =
default;
78 SValue& operator=(
const SValue&) =
default;
80 SValue& operator=(SValue&&)
noexcept =
default;
83 operator bool()
const {
return this->AsBool(); }
85 template <
typename T, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
87 return static_cast<T
>(this->AsInt());
90 template <
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
92 return static_cast<T
>(this->AsDouble());
95 operator std::string()
const {
return this->AsString(); }
99 Type GetType()
const noexcept {
return static_cast<Type
>(data_.index()); }
101 bool IsNull()
const noexcept {
return GetType() == kNull; };
103 bool IsBool()
const noexcept {
return GetType() == kBool; }
105 bool IsInt()
const noexcept {
return GetType() == kInt; }
107 bool IsDouble()
const noexcept {
return GetType() == kDouble; }
109 bool IsNumber()
const noexcept {
return IsInt() || IsDouble(); }
111 bool IsString()
const noexcept {
return GetType() == kString; }
113 bool IsArray()
const noexcept {
return GetType() == kArray; }
115 bool IsObject()
const noexcept {
return GetType() == kObject; }
117 bool IsEmpty()
const noexcept {
return Size() == 0; }
119 bool Has(std::string_view key)
const noexcept;
121 std::size_t Size()
const noexcept;
123 const SValue* Find(std::string_view key)
const noexcept;
125 SValue* Find(std::string_view key)
noexcept;
129 const Object& Items()
const;
133 const Array& Values()
const;
137 bool AsBool()
const noexcept;
139 double AsDouble()
const;
143 std::string AsString()
const;
145 std::string DumpJson()
const;
147 SValue& operator[](std::string_view key);
149 SValue& operator[](
const char* key);
151 const SValue& operator[](std::string_view key)
const;
153 const SValue& operator[](
const char* key)
const;
155 template <
typename T, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
156 SValue& operator[](T ind) {
157 if (this->IsNull()) {
158 *
this = SValue::Array{};
163 auto& array_ = std::get<Array>(data_);
165 if (
static_cast<std::size_t
>(ind) >= array_.size()) {
166 array_.resize(ind + 1);
172 template <
typename T, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
173 const SValue& operator[](T ind)
const {
175 auto& array_ = std::get<Array>(data_);
180 template <
typename T>
181 const T& Get()
const {
183 return std::get<T>(data_);
186 template <
typename T>
189 return std::get<T>(data_);
192 template <
typename T>
193 const T* GetIf()
const noexcept {
194 return std::get_if<T>(&data_);
197 template <
typename T>
198 T* GetIf()
noexcept {
199 return std::get_if<T>(&data_);
202 const SValue& At(std::size_t ind)
const;
204 SValue& At(std::size_t ind);
206 const SValue& At(std::string_view key)
const;
208 SValue& At(std::string_view key);
212 SValue& Push(SValue val);
216 SValue& Insert(std::size_t pos, SValue val);
218 std::pair<SValue&, bool> Insert(std::string_view key, SValue val);
220 bool Erase(std::size_t pos);
222 bool Erase(std::string_view key);
226 bool operator==(
const SValue& rhs)
const noexcept;
228 bool operator!=(
const SValue& rhs)
const noexcept;
230 friend inline std::ostream& operator<<(std::ostream& os,
const SValue& v) {
236 using value_type = std::variant<std::nullptr_t, bool, i64, double, std::string, Array, Object>;
239 void DumpJsonImp(std::ostream& scout,
int indent_level = 0)
const;