NSUNI/NSLAR Library a250670
Loading...
Searching...
No Matches
svalue.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
8#include <ostream>
9#include <map>
10#include <string>
11#include <variant>
12#include <vector>
13
15#include "NNL/common/contract.hpp" // IWYU pragma: export
16#include "NNL/common/exception.hpp" // IWYU pragma: export
17
18namespace nnl {
19
26
41class SValue {
42 public:
43 using Array = std::vector<SValue>;
44 using Object = std::map<std::string, SValue, std::less<>>;
45
46 enum Type { kNull, kBool, kInt, kDouble, kString, kArray, kObject };
47
48 // --- Construction (Converting) ---
49 SValue() : data_(nullptr) {}
50
51 SValue(std::nullptr_t) : data_(nullptr) {}
52
53 SValue(bool b) : data_(b) {}
54
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)) {}
57
58 template <typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
59 SValue(T real_num) : data_(static_cast<double>(real_num)) {}
60
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))) {}
63
64 SValue(const Array& a) : data_(a) {}
65 SValue(Array&& a) noexcept : data_(std::move(a)) {}
66
67 SValue(const Object& o) : data_{o} {}
68 SValue(Object&& o) noexcept : data_(std::move(o)) {}
69
70 SValue(std::initializer_list<SValue> init);
71
72 ~SValue() = default;
73
74 SValue(const SValue&) = default;
75
76 SValue(SValue&&) noexcept = default;
77
78 SValue& operator=(const SValue&) = default;
79
80 SValue& operator=(SValue&&) noexcept = default;
81
82 // --- Implicit Conversions ---
83 operator bool() const { return this->AsBool(); }
84
85 template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
86 operator T() const {
87 return static_cast<T>(this->AsInt());
88 }
89
90 template <typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
91 operator T() const {
92 return static_cast<T>(this->AsDouble());
93 }
94
95 operator std::string() const { return this->AsString(); }
96
97 // --- Inspection ---
98
99 Type GetType() const noexcept { return static_cast<Type>(data_.index()); }
100
101 bool IsNull() const noexcept { return GetType() == kNull; };
102
103 bool IsBool() const noexcept { return GetType() == kBool; }
104
105 bool IsInt() const noexcept { return GetType() == kInt; }
106
107 bool IsDouble() const noexcept { return GetType() == kDouble; }
108
109 bool IsNumber() const noexcept { return IsInt() || IsDouble(); }
110
111 bool IsString() const noexcept { return GetType() == kString; }
112
113 bool IsArray() const noexcept { return GetType() == kArray; }
114
115 bool IsObject() const noexcept { return GetType() == kObject; }
116
117 bool IsEmpty() const noexcept { return Size() == 0; }
118
119 bool Has(std::string_view key) const noexcept;
120
121 std::size_t Size() const noexcept;
122
123 const SValue* Find(std::string_view key) const noexcept;
124
125 SValue* Find(std::string_view key) noexcept;
126
127 // --- Data Access ---
128
129 const Object& Items() const;
130
131 Object& Items();
132
133 const Array& Values() const;
134
135 Array& Values();
136
137 bool AsBool() const noexcept;
138
139 double AsDouble() const;
140
141 i64 AsInt() const;
142
143 std::string AsString() const;
144
145 std::string DumpJson() const;
146
147 SValue& operator[](std::string_view key);
148
149 SValue& operator[](const char* key);
150
151 const SValue& operator[](std::string_view key) const;
152
153 const SValue& operator[](const char* key) const;
154
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{};
159 }
160
161 NNL_EXPECTS(this->IsArray());
162
163 auto& array_ = std::get<Array>(data_);
164
165 if (static_cast<std::size_t>(ind) >= array_.size()) {
166 array_.resize(ind + 1);
167 }
168
169 return array_[ind];
170 }
171
172 template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
173 const SValue& operator[](T ind) const {
174 NNL_EXPECTS(this->IsArray());
175 auto& array_ = std::get<Array>(data_);
176 NNL_EXPECTS_DBG(static_cast<std::size_t>(ind) < array_.size());
177 return array_[ind];
178 }
179
180 template <typename T>
181 const T& Get() const {
182 NNL_EXPECTS(std::holds_alternative<T>(data_));
183 return std::get<T>(data_);
184 }
185
186 template <typename T>
187 T& Get() {
188 NNL_EXPECTS(std::holds_alternative<T>(data_));
189 return std::get<T>(data_);
190 }
191
192 template <typename T>
193 const T* GetIf() const noexcept {
194 return std::get_if<T>(&data_);
195 }
196
197 template <typename T>
198 T* GetIf() noexcept {
199 return std::get_if<T>(&data_);
200 }
201
202 const SValue& At(std::size_t ind) const;
203
204 SValue& At(std::size_t ind);
205
206 const SValue& At(std::string_view key) const;
207
208 SValue& At(std::string_view key);
209
210 // --- Modification ---
211
212 SValue& Push(SValue val);
213
214 SValue Pop();
215
216 SValue& Insert(std::size_t pos, SValue val);
217
218 std::pair<SValue&, bool> Insert(std::string_view key, SValue val);
219
220 bool Erase(std::size_t pos);
221
222 bool Erase(std::string_view key);
223
224 void Clear();
225
226 bool operator==(const SValue& rhs) const noexcept;
227
228 bool operator!=(const SValue& rhs) const noexcept;
229
230 friend inline std::ostream& operator<<(std::ostream& os, const SValue& v) {
231 os << v.AsString();
232 return os;
233 }
234
235 protected:
236 using value_type = std::variant<std::nullptr_t, bool, i64, double, std::string, Array, Object>;
237 value_type data_;
238
239 void DumpJsonImp(std::ostream& scout, int indent_level = 0) const;
240};
241
242} // namespace nnl
Defines macros for Design-by-Contract verification.
Defines the library-wide exception hierarchy and error handling macros.
Contains macros and definitions for fixed-width types.
#define NNL_EXPECTS_DBG(precondition)
Debug-only precondition check.
Definition contract.hpp:59
#define NNL_EXPECTS(precondition)
A precondition check.
Definition contract.hpp:45
std::int64_t i64
64-bit signed integer
Definition fixed_type.hpp:58
Definition exception.hpp:56