exception-safe object creation, fixes #118
This commit is contained in:
parent
0a81353989
commit
f7fb405564
1 changed files with 25 additions and 42 deletions
|
@ -584,6 +584,17 @@ class basic_json
|
|||
|
||||
|
||||
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 //
|
||||
////////////////////////
|
||||
|
@ -625,25 +636,19 @@ class basic_json
|
|||
|
||||
case (value_t::object):
|
||||
{
|
||||
AllocatorType<object_t> alloc;
|
||||
object = alloc.allocate(1);
|
||||
alloc.construct(object);
|
||||
object = create<object_t>();
|
||||
break;
|
||||
}
|
||||
|
||||
case (value_t::array):
|
||||
{
|
||||
AllocatorType<array_t> alloc;
|
||||
array = alloc.allocate(1);
|
||||
alloc.construct(array);
|
||||
array = create<array_t>();
|
||||
break;
|
||||
}
|
||||
|
||||
case (value_t::string):
|
||||
{
|
||||
AllocatorType<string_t> alloc;
|
||||
string = alloc.allocate(1);
|
||||
alloc.construct(string, "");
|
||||
string = create<string_t>("");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -670,25 +675,19 @@ class basic_json
|
|||
/// constructor for strings
|
||||
json_value(const string_t& value)
|
||||
{
|
||||
AllocatorType<string_t> alloc;
|
||||
string = alloc.allocate(1);
|
||||
alloc.construct(string, value);
|
||||
string = create<string_t>(value);
|
||||
}
|
||||
|
||||
/// constructor for objects
|
||||
json_value(const object_t& value)
|
||||
{
|
||||
AllocatorType<object_t> alloc;
|
||||
object = alloc.allocate(1);
|
||||
alloc.construct(object, value);
|
||||
object = create<object_t>(value);
|
||||
}
|
||||
|
||||
/// constructor for arrays
|
||||
json_value(const array_t& value)
|
||||
{
|
||||
AllocatorType<array_t> alloc;
|
||||
array = alloc.allocate(1);
|
||||
alloc.construct(array, value);
|
||||
array = create<array_t>(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -892,11 +891,9 @@ class basic_json
|
|||
basic_json(const CompatibleObjectType& value)
|
||||
: m_type(value_t::object)
|
||||
{
|
||||
AllocatorType<object_t> 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<object_t>(begin(value), end(value));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -953,11 +950,9 @@ class basic_json
|
|||
basic_json(const CompatibleArrayType& value)
|
||||
: m_type(value_t::array)
|
||||
{
|
||||
AllocatorType<array_t> 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<array_t>(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<array_t> alloc;
|
||||
m_value.array = alloc.allocate(1);
|
||||
alloc.construct(m_value.array, std::move(init));
|
||||
m_value.array = create<array_t>(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<array_t> alloc;
|
||||
m_value.array = alloc.allocate(1);
|
||||
alloc.construct(m_value.array, count, value);
|
||||
m_value.array = create<array_t>(count, value);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1514,17 +1505,13 @@ class basic_json
|
|||
|
||||
case value_t::object:
|
||||
{
|
||||
AllocatorType<object_t> 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<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
AllocatorType<array_t> 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<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2598,9 +2585,7 @@ class basic_json
|
|||
if (m_type == value_t::null)
|
||||
{
|
||||
m_type = value_t::array;
|
||||
AllocatorType<array_t> alloc;
|
||||
m_value.array = alloc.allocate(1);
|
||||
alloc.construct(m_value.array);
|
||||
m_value.array = create<array_t>();
|
||||
}
|
||||
|
||||
// [] only works for arrays
|
||||
|
@ -2670,9 +2655,7 @@ class basic_json
|
|||
if (m_type == value_t::null)
|
||||
{
|
||||
m_type = value_t::object;
|
||||
AllocatorType<object_t> alloc;
|
||||
m_value.object = alloc.allocate(1);
|
||||
alloc.construct(m_value.object);
|
||||
m_value.object = create<object_t>();
|
||||
}
|
||||
|
||||
// [] only works for objects
|
||||
|
|
Loading…
Reference in a new issue