51class JsonValue final :
public IJson {
52#ifdef P4C_GTEST_ENABLED
53 FRIEND_TEST(Util, Json);
57 enum Kind { String, Integer, Float, True, False, Null };
58 JsonValue() : tag(Kind::Null) {}
59 JsonValue(
bool b) : tag(b ? Kind::True : Kind::False) {}
60 JsonValue(big_int v) : tag(Kind::Integer), intValue(v) {}
61 JsonValue(
int v) : tag(Kind::Integer), intValue(v) {}
62 JsonValue(
long v) : tag(Kind::Integer), intValue(v) {}
63 JsonValue(
long long v);
64 JsonValue(
unsigned v) : tag(Kind::Integer), intValue(v) {}
65 JsonValue(
unsigned long v) : tag(Kind::Integer), intValue(v) {}
66 JsonValue(
unsigned long long v);
67 JsonValue(
double v) : tag(Kind::Float), floatValue(v) {}
68 JsonValue(
float v) : tag(Kind::Float), floatValue(v) {}
69 JsonValue(
cstring s) : tag(Kind::String), str(s) {}
72 JsonValue(
const char *s) : tag(Kind::String), str(s) {}
73 JsonValue(
const std::string &s) : tag(Kind::String), str(s) {}
74 void serialize(std::ostream &out)
const override;
76 bool operator==(
const big_int &v)
const;
78 template <
typename T,
typename std::enable_if_t<std::is_
integral_v<T>,
int> = 0>
79 bool operator==(
const T &v)
const {
80 if (tag == Kind::Integer)
return intValue == v;
84 template <
typename T,
typename std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
85 bool operator==(
const T &v)
const {
86 if (tag == Kind::Integer)
return static_cast<double>(intValue) ==
static_cast<double>(v);
87 if (tag == Kind::Float)
return floatValue ==
static_cast<double>(v);
90 bool operator==(
const double &v)
const;
91 bool operator==(
const float &v)
const;
92 bool operator==(
const cstring &s)
const;
95 bool operator==(
const char *s)
const;
96 bool operator==(
const std::string &s)
const;
97 bool operator==(
const JsonValue &other)
const;
99 bool isNumber()
const {
return tag == Kind::Integer || tag == Kind::Float; }
100 bool isBool()
const {
return tag == Kind::True || tag == Kind::False; }
101 bool isString()
const {
return tag == Kind::String; }
102 bool isNull()
const {
return tag == Kind::Null; }
103 bool isInteger()
const {
return tag == Kind::Integer; }
104 bool isFloat()
const {
return tag == Kind::Float; }
106 bool getBool()
const;
108 big_int getIntValue()
const;
109 double getFloatValue()
const;
112 static JsonValue *null;
115 JsonValue(Kind kind) : tag(kind) {
116 if (kind == Kind::String || kind == Kind::Integer || kind == Kind::Float)
117 throw std::logic_error(
"Incorrect constructor called");
121 const big_int intValue = 0;
122 const double floatValue = 0.0;
123 const cstring str = cstring::empty;
125 DECLARE_TYPEINFO(JsonValue,
IJson);
128class JsonArray final :
public IJson,
public std::vector<IJson *> {
129 friend class Test::TestJson;
132 void serialize(std::ostream &out)
const override;
133 JsonArray *clone()
const {
return new JsonArray(*
this); }
134 JsonArray *append(
IJson *value);
135 JsonArray *append(big_int v) {
139 template <typename T, typename std::enable_if<std::is_integral<T>::value,
int>::type = 0>
140 JsonArray *append(T v) {
144 JsonArray *append(
double v) {
148 JsonArray *append(
float v) {
158 JsonArray *append(
const char *s) {
162 JsonArray *append(
const std::string &s) {
167 for (
auto v : *other) append(v);
170 JsonArray(std::initializer_list<IJson *> data) : std::vector<IJson *>(data) {}
171 JsonArray() =
default;
172 JsonArray(std::vector<IJson *> &data) : std::vector<IJson *>(data) {}
174 DECLARE_TYPEINFO(JsonArray,
IJson);
177class JsonObject final :
public IJson,
public string_map<IJson *> {
178 friend class Test::TestJson;
180 using base = string_map<IJson *>;
183 JsonObject() =
default;
184 void serialize(std::ostream &out)
const override;
185 JsonObject *emplace_non_null(
cstring label,
IJson *value);
188 JsonObject *emplace(std::string_view label,
IJson *value);
190 template <
class T,
class String>
191 auto emplace(String label,
192 T &&s) -> std::enable_if_t<!std::is_convertible_v<T, IJson *>, JsonObject *> {
193 emplace(label,
new JsonValue(std::forward<T>(s)));
197 IJson *get(
cstring label)
const { return ::P4::get(*
this, label); }
198 IJson *get(std::string_view label)
const { return ::P4::get(*
this, label); }
199 template <
class T,
class S>
200 T *getAs(S label)
const {
201 return get(label)->template
to<T>();
204 DECLARE_TYPEINFO(JsonObject,
IJson);