This commit is contained in:
Niels 2015-10-03 13:16:59 +02:00
parent 2550d29ded
commit 57de1d602e
6 changed files with 49 additions and 53 deletions

View file

@ -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. - [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. - [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators.
- [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling. - [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! Thanks a lot for helping out!

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/fdsMCtY67vLJrlzv"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/OQ6W9gVosCWDgJHS"><b>online</b></a>

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/Ka7Efl5Jo2FTDy69"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/Onaz3FY3sow5TEwH"><b>online</b></a>

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/kQKYwNmQRJAJhCTe"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/wArBhgANa8p39v92"><b>online</b></a>

View file

@ -584,6 +584,20 @@ class basic_json
private: private:
/// helper for exception-safe object creation
template<typename T, typename... Args>
static T* create( Args&& ... args )
{
AllocatorType<T> alloc;
auto deleter = [&](T * object)
{
alloc.deallocate(object, 1);
};
std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
alloc.construct(object.get(), std::forward<Args>(args)...);
return object.release();
}
//////////////////////// ////////////////////////
// JSON value storage // // JSON value storage //
//////////////////////// ////////////////////////
@ -625,25 +639,19 @@ class basic_json
case (value_t::object): case (value_t::object):
{ {
AllocatorType<object_t> alloc; object = create<object_t>();
object = alloc.allocate(1);
alloc.construct(object);
break; break;
} }
case (value_t::array): case (value_t::array):
{ {
AllocatorType<array_t> alloc; array = create<array_t>();
array = alloc.allocate(1);
alloc.construct(array);
break; break;
} }
case (value_t::string): case (value_t::string):
{ {
AllocatorType<string_t> alloc; string = create<string_t>("");
string = alloc.allocate(1);
alloc.construct(string, "");
break; break;
} }
@ -670,25 +678,19 @@ class basic_json
/// constructor for strings /// constructor for strings
json_value(const string_t& value) json_value(const string_t& value)
{ {
AllocatorType<string_t> alloc; string = create<string_t>(value);
string = alloc.allocate(1);
alloc.construct(string, value);
} }
/// constructor for objects /// constructor for objects
json_value(const object_t& value) json_value(const object_t& value)
{ {
AllocatorType<object_t> alloc; object = create<object_t>(value);
object = alloc.allocate(1);
alloc.construct(object, value);
} }
/// constructor for arrays /// constructor for arrays
json_value(const array_t& value) json_value(const array_t& value)
{ {
AllocatorType<array_t> alloc; array = create<array_t>(value);
array = alloc.allocate(1);
alloc.construct(array, value);
} }
}; };
@ -892,11 +894,9 @@ class basic_json
basic_json(const CompatibleObjectType& value) basic_json(const CompatibleObjectType& value)
: m_type(value_t::object) : m_type(value_t::object)
{ {
AllocatorType<object_t> alloc;
m_value.object = alloc.allocate(1);
using std::begin; using std::begin;
using std::end; using std::end;
alloc.construct(m_value.object, begin(value), end(value)); m_value.object = create<object_t>(begin(value), end(value));
} }
/*! /*!
@ -953,11 +953,9 @@ class basic_json
basic_json(const CompatibleArrayType& value) basic_json(const CompatibleArrayType& value)
: m_type(value_t::array) : m_type(value_t::array)
{ {
AllocatorType<array_t> alloc;
m_value.array = alloc.allocate(1);
using std::begin; using std::begin;
using std::end; using std::end;
alloc.construct(m_value.array, begin(value), end(value)); m_value.array = create<array_t>(begin(value), end(value));
} }
/*! /*!
@ -1315,9 +1313,7 @@ class basic_json
{ {
// the initializer list describes an array -> create array // the initializer list describes an array -> create array
m_type = value_t::array; m_type = value_t::array;
AllocatorType<array_t> alloc; m_value.array = create<array_t>(std::move(init));
m_value.array = alloc.allocate(1);
alloc.construct(m_value.array, std::move(init));
} }
} }
@ -1416,9 +1412,7 @@ class basic_json
basic_json(size_type count, const basic_json& value) basic_json(size_type count, const basic_json& value)
: m_type(value_t::array) : m_type(value_t::array)
{ {
AllocatorType<array_t> alloc; m_value.array = create<array_t>(count, value);
m_value.array = alloc.allocate(1);
alloc.construct(m_value.array, count, value);
} }
/*! /*!
@ -1514,17 +1508,13 @@ class basic_json
case value_t::object: case value_t::object:
{ {
AllocatorType<object_t> alloc; m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
m_value.object = alloc.allocate(1);
alloc.construct(m_value.object, first.m_it.object_iterator, last.m_it.object_iterator);
break; break;
} }
case value_t::array: case value_t::array:
{ {
AllocatorType<array_t> alloc; m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
m_value.array = alloc.allocate(1);
alloc.construct(m_value.array, first.m_it.array_iterator, last.m_it.array_iterator);
break; break;
} }
@ -1658,8 +1648,8 @@ class basic_json
) )
{ {
using std::swap; using std::swap;
std::swap(m_type, other.m_type); swap(m_type, other.m_type);
std::swap(m_value, other.m_value); swap(m_value, other.m_value);
return *this; return *this;
} }
@ -1683,7 +1673,6 @@ class basic_json
AllocatorType<object_t> alloc; AllocatorType<object_t> alloc;
alloc.destroy(m_value.object); alloc.destroy(m_value.object);
alloc.deallocate(m_value.object, 1); alloc.deallocate(m_value.object, 1);
m_value.object = nullptr;
break; break;
} }
@ -1692,7 +1681,6 @@ class basic_json
AllocatorType<array_t> alloc; AllocatorType<array_t> alloc;
alloc.destroy(m_value.array); alloc.destroy(m_value.array);
alloc.deallocate(m_value.array, 1); alloc.deallocate(m_value.array, 1);
m_value.array = nullptr;
break; break;
} }
@ -1701,7 +1689,6 @@ class basic_json
AllocatorType<string_t> alloc; AllocatorType<string_t> alloc;
alloc.destroy(m_value.string); alloc.destroy(m_value.string);
alloc.deallocate(m_value.string, 1); alloc.deallocate(m_value.string, 1);
m_value.string = nullptr;
break; break;
} }
@ -2598,9 +2585,7 @@ class basic_json
if (m_type == value_t::null) if (m_type == value_t::null)
{ {
m_type = value_t::array; m_type = value_t::array;
AllocatorType<array_t> alloc; m_value.array = create<array_t>();
m_value.array = alloc.allocate(1);
alloc.construct(m_value.array);
} }
// [] only works for arrays // [] only works for arrays
@ -2670,9 +2655,7 @@ class basic_json
if (m_type == value_t::null) if (m_type == value_t::null)
{ {
m_type = value_t::object; m_type = value_t::object;
AllocatorType<object_t> alloc; m_value.object = create<object_t>();
m_value.object = alloc.allocate(1);
alloc.construct(m_value.object);
} }
// [] only works for objects // [] only works for objects
@ -4471,6 +4454,11 @@ class basic_json
return parser(i, cb).parse(); 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 @brief deserialize from stream
@ -6903,7 +6891,7 @@ basic_json_parser_59:
@brief return number value for number tokens @brief return number value for number tokens
This function translates the last token into a floating point number. 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 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 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 m_cursor, then either more or less characters have been used during the

View file

@ -586,10 +586,13 @@ class basic_json
private: private:
/// helper for exception-safe object creation /// helper for exception-safe object creation
template<typename T, typename... Args> template<typename T, typename... Args>
static T* create( Args&&... args ) static T* create(Args&& ... args)
{ {
AllocatorType<T> alloc; AllocatorType<T> alloc;
auto deleter = [&](T* object) { alloc.deallocate(object, 1); }; auto deleter = [&](T* object)
{
alloc.deallocate(object, 1);
};
std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter); std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
alloc.construct(object.get(), std::forward<Args>(args)...); alloc.construct(object.get(), std::forward<Args>(args)...);
return object.release(); return object.release();