diff --git a/README.md b/README.md index 01d65929..d27b78a7 100644 --- a/README.md +++ b/README.md @@ -374,6 +374,11 @@ I deeply appreciate the help of the following people. - [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual studio. - [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators. - [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling. +- [dariomt](https://github.com/dariomt) fixed some typos in the examples. +- [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation. +- [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue. +- [Huu Nguyen](https://github.com/whoshuu) correct a variable name in the documentation. +- [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference. Thanks a lot for helping out! diff --git a/doc/examples/get__PointerType.link b/doc/examples/get__PointerType.link index f9411820..7dd011cb 100644 --- a/doc/examples/get__PointerType.link +++ b/doc/examples/get__PointerType.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/get_ptr.link b/doc/examples/get_ptr.link index aeaf460d..265ebb04 100644 --- a/doc/examples/get_ptr.link +++ b/doc/examples/get_ptr.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/object.link b/doc/examples/object.link index 048be388..b41ff5a3 100644 --- a/doc/examples/object.link +++ b/doc/examples/object.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/src/json.hpp b/src/json.hpp index bdea958f..7e174d72 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -584,6 +584,20 @@ 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 +639,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 +678,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 +894,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 +953,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 +1313,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 +1412,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 +1508,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; } @@ -1658,8 +1648,8 @@ class basic_json ) { using std::swap; - std::swap(m_type, other.m_type); - std::swap(m_value, other.m_value); + swap(m_type, other.m_type); + swap(m_value, other.m_value); return *this; } @@ -1683,7 +1673,6 @@ class basic_json AllocatorType alloc; alloc.destroy(m_value.object); alloc.deallocate(m_value.object, 1); - m_value.object = nullptr; break; } @@ -1692,7 +1681,6 @@ class basic_json AllocatorType alloc; alloc.destroy(m_value.array); alloc.deallocate(m_value.array, 1); - m_value.array = nullptr; break; } @@ -1701,7 +1689,6 @@ class basic_json AllocatorType alloc; alloc.destroy(m_value.string); alloc.deallocate(m_value.string, 1); - m_value.string = nullptr; break; } @@ -2598,9 +2585,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 @@ -2670,9 +2655,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 @@ -4471,6 +4454,11 @@ class basic_json return parser(i, cb).parse(); } + static basic_json parse(std::istream&& i, parser_callback_t cb = nullptr) + { + return parser(i, cb).parse(); + } + /*! @brief deserialize from stream @@ -6903,7 +6891,7 @@ basic_json_parser_59: @brief return number value for number tokens This function translates the last token into a floating point number. - The pointer m_begin points to the beginning of the parsed number. We + The pointer m_start points to the beginning of the parsed number. We pass this pointer to std::strtod which sets endptr to the first character past the converted number. If this pointer is not the same as m_cursor, then either more or less characters have been used during the diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index b7048333..0ffddd50 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -586,10 +586,13 @@ class basic_json private: /// helper for exception-safe object creation template - static T* create( Args&&... args ) + static T* create(Args&& ... args) { AllocatorType alloc; - auto deleter = [&](T* object) { alloc.deallocate(object, 1); }; + 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();