aboutsummaryrefslogtreecommitdiff
path: root/gcc/json.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/json.h')
-rw-r--r--gcc/json.h82
1 files changed, 82 insertions, 0 deletions
diff --git a/gcc/json.h b/gcc/json.h
index c706f2a..c53715e 100644
--- a/gcc/json.h
+++ b/gcc/json.h
@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_JSON_H
#define GCC_JSON_H
+#include "label-text.h"
+
/* Implementation of JSON, a lightweight data-interchange format.
See http://www.json.org/
@@ -116,6 +118,41 @@ struct token
} // namespace json::pointer
+/* Typesafe way to work with properties in JSON objects. */
+
+template <typename Traits>
+struct property
+{
+ explicit property (const char *key)
+ : m_key (label_text::borrow (key))
+ {}
+
+ explicit property (const char *key_prefix, const char *key)
+ : m_key (label_text::take (concat (key_prefix, key, nullptr)))
+ {}
+
+ label_text m_key;
+};
+
+using string_property = property<string>;
+using integer_property = property<integer_number>;
+using bool_property = property<literal>;
+using json_property = property<value>;
+using array_of_string_property = property<array>;
+
+template <typename EnumType>
+struct enum_traits
+{
+ typedef EnumType enum_t;
+
+ static enum_t get_unknown_value ();
+ static bool maybe_get_value_from_string (const char *, enum_t &out);
+ static const char *get_string_for_value (enum_t value);
+};
+
+template <typename EnumType>
+using enum_property = property<enum_traits<EnumType>>;
+
/* Base class of JSON value. */
class value
@@ -130,6 +167,8 @@ class value
void DEBUG_FUNCTION dump () const;
virtual object *dyn_cast_object () { return nullptr; }
+ virtual array *dyn_cast_array () { return nullptr; }
+ virtual integer_number *dyn_cast_integer_number () { return nullptr; }
virtual string *dyn_cast_string () { return nullptr; }
static int compare (const json::value &val_a, const json::value &val_b);
@@ -183,6 +222,19 @@ class object : public value
/* Set to literal true/false. */
void set_bool (const char *key, bool v);
+ /* Typesafe access to properties by name (such as from a schema). */
+ void set_string (const string_property &property, const char *utf8_value);
+ void set_integer (const integer_property &property, long value);
+ void set_bool (const bool_property &property, bool value);
+ void set_array_of_string (const array_of_string_property &property,
+ std::unique_ptr<json::array> value);
+ template <typename EnumType>
+ bool maybe_get_enum (const enum_property<EnumType> &property,
+ EnumType &out) const;
+ template <typename EnumType>
+ void set_enum (const enum_property<EnumType> &property,
+ EnumType value);
+
static int compare (const json::object &obj_a, const json::object &obj_b);
size_t get_num_keys () const { return m_keys.length (); }
@@ -210,6 +262,8 @@ class array : public value
void print (pretty_printer *pp, bool formatted) const final override;
std::unique_ptr<value> clone () const final override;
+ array *dyn_cast_array () final override { return this; }
+
void append (value *v);
void append_string (const char *utf8_value);
@@ -269,6 +323,8 @@ class integer_number : public value
void print (pretty_printer *pp, bool formatted) const final override;
std::unique_ptr<value> clone () const final override;
+ integer_number *dyn_cast_integer_number () final override { return this; }
+
long get () const { return m_value; }
private:
@@ -317,6 +373,32 @@ class literal : public value
enum kind m_kind;
};
+
+template <typename EnumType>
+inline bool
+object::maybe_get_enum (const enum_property<EnumType> &property,
+ EnumType &out) const
+{
+ if (value *jv = get (property.m_key.get ()))
+ if (string *jstr = jv->dyn_cast_string ())
+ {
+ if (enum_traits<EnumType>::maybe_get_value_from_string
+ (jstr->get_string (), out))
+ return true;
+ }
+ return false;
+}
+
+template <typename EnumType>
+inline void
+object::set_enum (const enum_property<EnumType> &property,
+ EnumType value)
+{
+ const char *str
+ = json::enum_traits<EnumType>::get_string_for_value (value);
+ set_string (property.m_key.get (), str);
+}
+
} // namespace json
template <>