Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r16-2210-gd7c1e9b37caad5.
gcc/ChangeLog: * json.cc (json::object::clone): New. (json::object::clone_as_object): New. (json::array::clone): New. (json::float_number::clone): New. (json::integer_number::clone): New. (json::string::clone): New. (json::literal::clone): New. (selftest::test_cloning): New test. (selftest::json_cc_tests): Call it. * json.h (json::value::clone): New vfunc. (json::object::clone): New decl. (json::object::clone_as_object): New decl. (json::array::clone): New decl. (json::float_number::clone): New decl. (json::integer_number::clone): New decl. (json::string::clone): New decl. (json::literal::clone): New decl. --- gcc/json.cc | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/json.h | 9 +++++ 2 files changed, 118 insertions(+) diff --git a/gcc/json.cc b/gcc/json.cc index df0702f8e6c5..7153f087a001 100644 --- a/gcc/json.cc +++ b/gcc/json.cc @@ -289,6 +289,30 @@ object::print (pretty_printer *pp, bool formatted) const pp_character (pp, '}'); } +std::unique_ptr<value> +object::clone () const +{ + return clone_as_object (); +} + +std::unique_ptr<object> +object::clone_as_object () const +{ + auto result = std::make_unique<object> (); + + /* Iterate in the order that the keys were inserted. */ + unsigned i; + const char *key; + FOR_EACH_VEC_ELT (m_keys, i, key) + { + map_t &mut_map = const_cast<map_t &> (m_map); + value *value = *mut_map.get (key); + result->set (key, value->clone ()); + } + + return result; +} + /* Set the json::value * for KEY, taking ownership of V (and taking a copy of KEY if necessary). */ @@ -443,6 +467,17 @@ array::print (pretty_printer *pp, bool formatted) const pp_character (pp, ']'); } +std::unique_ptr<value> +array::clone () const +{ + auto result = std::make_unique<array> (); + unsigned i; + value *v; + FOR_EACH_VEC_ELT (m_elements, i, v) + result->append (v->clone ()); + return result; +} + /* Append non-NULL value V to a json::array, taking ownership of V. */ void @@ -473,6 +508,12 @@ float_number::print (pretty_printer *pp, pp_string (pp, tmp); } +std::unique_ptr<value> +float_number::clone () const +{ + return std::make_unique<float_number> (m_value); +} + /* class json::integer_number, a subclass of json::value, wrapping a long. */ /* Implementation of json::value::print for json::integer_number. */ @@ -486,6 +527,11 @@ integer_number::print (pretty_printer *pp, pp_string (pp, tmp); } +std::unique_ptr<value> +integer_number::clone () const +{ + return std::make_unique<integer_number> (m_value); +} /* class json::string, a subclass of json::value. */ @@ -516,6 +562,12 @@ string::print (pretty_printer *pp, print_escaped_json_string (pp, m_utf8, m_len); } +std::unique_ptr<value> +string::clone () const +{ + return std::make_unique<string> (m_utf8, m_len); +} + /* class json::literal, a subclass of json::value. */ /* Implementation of json::value::print for json::literal. */ @@ -540,6 +592,12 @@ literal::print (pretty_printer *pp, } } +std::unique_ptr<value> +literal::clone () const +{ + return std::make_unique<literal> (m_kind); +} + #if CHECKING_P @@ -924,6 +982,56 @@ test_strcmp () ASSERT_EQ (strcmp (str.get_string (), "foo"), 0); } +static void +test_cloning () +{ + // Objects + { + object obj; + obj.set_string ("foo", "bar"); + + auto obj_clone = obj.clone (); + ASSERT_JSON_EQ (obj, *obj_clone); + } + + // Arrays + { + array arr; + arr.append (std::make_unique<string> ("foo")); + + auto arr_clone = arr.clone (); + ASSERT_JSON_EQ (arr, *arr_clone); + } + + // float_number + { + float_number f_one (1.0); + auto f_clone = f_one.clone (); + ASSERT_JSON_EQ (f_one, *f_clone); + } + + // integer_number + { + integer_number num (42); + auto num_clone = num.clone (); + ASSERT_JSON_EQ (num, *num_clone); + } + + // string + { + string str ("foo"); + auto str_clone = str.clone (); + ASSERT_JSON_EQ (str, *str_clone); + } + + // literal + { + literal lit (JSON_TRUE); + auto lit_clone = lit.clone (); + ASSERT_JSON_EQ (lit, *lit_clone); + } +} + /* Run all of the selftests within this file. */ void @@ -939,6 +1047,7 @@ json_cc_tests () test_formatting (); test_comparisons (); test_strcmp (); + test_cloning (); } } // namespace selftest diff --git a/gcc/json.h b/gcc/json.h index da4da852a1ed..156c086d2cfd 100644 --- a/gcc/json.h +++ b/gcc/json.h @@ -124,6 +124,7 @@ class value virtual ~value () {} virtual enum kind get_kind () const = 0; virtual void print (pretty_printer *pp, bool formatted) const = 0; + virtual std::unique_ptr<value> clone () const = 0; void dump (FILE *, bool formatted) const; void DEBUG_FUNCTION dump () const; @@ -150,6 +151,7 @@ class object : public value enum kind get_kind () const final override { return JSON_OBJECT; } void print (pretty_printer *pp, bool formatted) const final override; + std::unique_ptr<value> clone () const final override; object *dyn_cast_object () final override { return this; } @@ -182,6 +184,8 @@ class object : public value static int compare (const json::object &obj_a, const json::object &obj_b); + std::unique_ptr<object> clone_as_object () const; + private: typedef hash_map <char *, value *, simple_hashmap_traits<nofree_string_hash, value *> > map_t; @@ -200,6 +204,7 @@ class array : public value enum kind get_kind () const final override { return JSON_ARRAY; } void print (pretty_printer *pp, bool formatted) const final override; + std::unique_ptr<value> clone () const final override; void append (value *v); void append_string (const char *utf8_value); @@ -241,6 +246,7 @@ class float_number : public value enum kind get_kind () const final override { return JSON_FLOAT; } void print (pretty_printer *pp, bool formatted) const final override; + std::unique_ptr<value> clone () const final override; double get () const { return m_value; } @@ -257,6 +263,7 @@ class integer_number : public value enum kind get_kind () const final override { return JSON_INTEGER; } void print (pretty_printer *pp, bool formatted) const final override; + std::unique_ptr<value> clone () const final override; long get () const { return m_value; } @@ -276,6 +283,7 @@ class string : public value enum kind get_kind () const final override { return JSON_STRING; } void print (pretty_printer *pp, bool formatted) const final override; + std::unique_ptr<value> clone () const final override; const char *get_string () const { return m_utf8; } size_t get_length () const { return m_len; } @@ -298,6 +306,7 @@ class literal : public value enum kind get_kind () const final override { return m_kind; } void print (pretty_printer *pp, bool formatted) const final override; + std::unique_ptr<value> clone () const final override; private: enum kind m_kind; -- 2.26.3