diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 787df045..b7048333 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -584,6 +584,17 @@ class basic_json private: + /// helper for exception-safe object creation + template + static T* create( Args&&... args ) + { + AllocatorType alloc; + auto deleter = [&](T* object) { alloc.deallocate(object, 1); }; + std::unique_ptr object(alloc.allocate(1), deleter); + alloc.construct(object.get(), std::forward(args)...); + return object.release(); + } + //////////////////////// // JSON value storage // //////////////////////// @@ -625,25 +636,19 @@ class basic_json case (value_t::object): { - AllocatorType alloc; - object = alloc.allocate(1); - alloc.construct(object); + object = create(); break; } case (value_t::array): { - AllocatorType alloc; - array = alloc.allocate(1); - alloc.construct(array); + array = create(); break; } case (value_t::string): { - AllocatorType alloc; - string = alloc.allocate(1); - alloc.construct(string, ""); + string = create(""); break; } @@ -670,25 +675,19 @@ class basic_json /// constructor for strings json_value(const string_t& value) { - AllocatorType alloc; - string = alloc.allocate(1); - alloc.construct(string, value); + string = create(value); } /// constructor for objects json_value(const object_t& value) { - AllocatorType alloc; - object = alloc.allocate(1); - alloc.construct(object, value); + object = create(value); } /// constructor for arrays json_value(const array_t& value) { - AllocatorType alloc; - array = alloc.allocate(1); - alloc.construct(array, value); + array = create(value); } }; @@ -892,11 +891,9 @@ class basic_json basic_json(const CompatibleObjectType& value) : m_type(value_t::object) { - AllocatorType alloc; - m_value.object = alloc.allocate(1); using std::begin; using std::end; - alloc.construct(m_value.object, begin(value), end(value)); + m_value.object = create(begin(value), end(value)); } /*! @@ -953,11 +950,9 @@ class basic_json basic_json(const CompatibleArrayType& value) : m_type(value_t::array) { - AllocatorType alloc; - m_value.array = alloc.allocate(1); using std::begin; using std::end; - alloc.construct(m_value.array, begin(value), end(value)); + m_value.array = create(begin(value), end(value)); } /*! @@ -1315,9 +1310,7 @@ class basic_json { // the initializer list describes an array -> create array m_type = value_t::array; - AllocatorType alloc; - m_value.array = alloc.allocate(1); - alloc.construct(m_value.array, std::move(init)); + m_value.array = create(std::move(init)); } } @@ -1416,9 +1409,7 @@ class basic_json basic_json(size_type count, const basic_json& value) : m_type(value_t::array) { - AllocatorType alloc; - m_value.array = alloc.allocate(1); - alloc.construct(m_value.array, count, value); + m_value.array = create(count, value); } /*! @@ -1514,17 +1505,13 @@ class basic_json case value_t::object: { - AllocatorType alloc; - m_value.object = alloc.allocate(1); - alloc.construct(m_value.object, first.m_it.object_iterator, last.m_it.object_iterator); + m_value.object = create(first.m_it.object_iterator, last.m_it.object_iterator); break; } case value_t::array: { - AllocatorType alloc; - m_value.array = alloc.allocate(1); - alloc.construct(m_value.array, first.m_it.array_iterator, last.m_it.array_iterator); + m_value.array = create(first.m_it.array_iterator, last.m_it.array_iterator); break; } @@ -2595,9 +2582,7 @@ class basic_json if (m_type == value_t::null) { m_type = value_t::array; - AllocatorType alloc; - m_value.array = alloc.allocate(1); - alloc.construct(m_value.array); + m_value.array = create(); } // [] only works for arrays @@ -2667,9 +2652,7 @@ class basic_json if (m_type == value_t::null) { m_type = value_t::object; - AllocatorType alloc; - m_value.object = alloc.allocate(1); - alloc.construct(m_value.object); + m_value.object = create(); } // [] only works for objects