parent
47e3a3ed24
commit
5199382c91
4 changed files with 248 additions and 59 deletions
|
@ -140,7 +140,7 @@ class json
|
||||||
/// create an object according to given type
|
/// create an object according to given type
|
||||||
json(const value_t);
|
json(const value_t);
|
||||||
/// create a null object
|
/// create a null object
|
||||||
json() = default;
|
json() noexcept;
|
||||||
/// create a null object
|
/// create a null object
|
||||||
json(std::nullptr_t) noexcept;
|
json(std::nullptr_t) noexcept;
|
||||||
/// create a string object from a C++ string
|
/// create a string object from a C++ string
|
||||||
|
@ -160,7 +160,7 @@ class json
|
||||||
/// create an object (move)
|
/// create an object (move)
|
||||||
json(object_t&&);
|
json(object_t&&);
|
||||||
/// create from an initializer list (to an array or object)
|
/// create from an initializer list (to an array or object)
|
||||||
json(list_init_t);
|
json(list_init_t, bool = true, value_t = value_t::array);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a number object (integer)
|
@brief create a number object (integer)
|
||||||
|
@ -171,7 +171,7 @@ class json
|
||||||
std::numeric_limits<T>::is_integer, T>::type
|
std::numeric_limits<T>::is_integer, T>::type
|
||||||
= 0>
|
= 0>
|
||||||
json(const T n) noexcept
|
json(const T n) noexcept
|
||||||
: type_(value_t::number),
|
: final_type_(0), type_(value_t::number),
|
||||||
value_(static_cast<number_t>(n))
|
value_(static_cast<number_t>(n))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ class json
|
||||||
std::is_floating_point<T>::value>::type
|
std::is_floating_point<T>::value>::type
|
||||||
>
|
>
|
||||||
json(const T n) noexcept
|
json(const T n) noexcept
|
||||||
: type_(value_t::number_float),
|
: final_type_(0), type_(value_t::number_float),
|
||||||
value_(static_cast<number_float_t>(n))
|
value_(static_cast<number_float_t>(n))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -229,6 +229,11 @@ class json
|
||||||
/// destructor
|
/// destructor
|
||||||
~json() noexcept;
|
~json() noexcept;
|
||||||
|
|
||||||
|
/// explicit keyword to force array creation
|
||||||
|
static json array(list_init_t = list_init_t());
|
||||||
|
/// explicit keyword to force object creation
|
||||||
|
static json object(list_init_t = list_init_t());
|
||||||
|
|
||||||
/// create from string representation
|
/// create from string representation
|
||||||
static json parse(const std::string&);
|
static json parse(const std::string&);
|
||||||
/// create from string representation
|
/// create from string representation
|
||||||
|
@ -404,9 +409,10 @@ class json
|
||||||
const_reverse_iterator crend() const noexcept;
|
const_reverse_iterator crend() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// whether the type is final
|
||||||
|
unsigned final_type_ : 1;
|
||||||
/// the type of this object
|
/// the type of this object
|
||||||
value_t type_ = value_t::null;
|
value_t type_ = value_t::null;
|
||||||
|
|
||||||
/// the payload
|
/// the payload
|
||||||
value value_ {};
|
value value_ {};
|
||||||
|
|
||||||
|
@ -654,6 +660,9 @@ json::json(const value_t t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json::json() noexcept : final_type_(0), type_(value_t::null)
|
||||||
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Construct a null JSON object.
|
Construct a null JSON object.
|
||||||
*/
|
*/
|
||||||
|
@ -666,35 +675,35 @@ Construct a string JSON object.
|
||||||
@param s a string to initialize the JSON object with
|
@param s a string to initialize the JSON object with
|
||||||
*/
|
*/
|
||||||
json::json(const std::string& s)
|
json::json(const std::string& s)
|
||||||
: type_(value_t::string), value_(new string_t(s))
|
: final_type_(0), type_(value_t::string), value_(new string_t(s))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(std::string&& s)
|
json::json(std::string&& s)
|
||||||
: type_(value_t::string), value_(new string_t(std::move(s)))
|
: final_type_(0), type_(value_t::string), value_(new string_t(std::move(s)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const char* s)
|
json::json(const char* s)
|
||||||
: type_(value_t::string), value_(new string_t(s))
|
: final_type_(0), type_(value_t::string), value_(new string_t(s))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const bool b) noexcept
|
json::json(const bool b) noexcept
|
||||||
: type_(value_t::boolean), value_(b)
|
: final_type_(0), type_(value_t::boolean), value_(b)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const array_t& a)
|
json::json(const array_t& a)
|
||||||
: type_(value_t::array), value_(new array_t(a))
|
: final_type_(0), type_(value_t::array), value_(new array_t(a))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(array_t&& a)
|
json::json(array_t&& a)
|
||||||
: type_(value_t::array), value_(new array_t(std::move(a)))
|
: final_type_(0), type_(value_t::array), value_(new array_t(std::move(a)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const object_t& o)
|
json::json(const object_t& o)
|
||||||
: type_(value_t::object), value_(new object_t(o))
|
: final_type_(0), type_(value_t::object), value_(new object_t(o))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(object_t&& o)
|
json::json(object_t&& o)
|
||||||
: type_(value_t::object), value_(new object_t(std::move(o)))
|
: final_type_(0), type_(value_t::object), value_(new object_t(std::move(o)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -711,33 +720,90 @@ as is to create an array.
|
||||||
|
|
||||||
@bug With the described approach, we would fail to recognize an array whose
|
@bug With the described approach, we would fail to recognize an array whose
|
||||||
first element is again an arrays as array.
|
first element is again an arrays as array.
|
||||||
|
|
||||||
|
@param a an initializer list to create from
|
||||||
|
@param type_deduction whether the type (array/object) shall eb deducted
|
||||||
|
@param manual_type if type deduction is switched of, pass a manual type
|
||||||
*/
|
*/
|
||||||
json::json(list_init_t a)
|
json::json(list_init_t a, bool type_deduction, value_t manual_type) : final_type_(0)
|
||||||
{
|
{
|
||||||
|
// the initializer list could describe an object
|
||||||
|
bool is_object = true;
|
||||||
|
|
||||||
// check if each element is an array with two elements whose first element
|
// check if each element is an array with two elements whose first element
|
||||||
// is a string
|
// is a string
|
||||||
for (const auto& element : a)
|
for (const auto& element : a)
|
||||||
{
|
{
|
||||||
if (element.type_ != value_t::array or
|
if ((element.final_type_ == 1 and element.type_ == value_t::array)
|
||||||
element.size() != 2 or
|
or (element.type_ != value_t::array or element.size() != 2 or element[0].type_ != value_t::string))
|
||||||
element[0].type_ != value_t::string)
|
|
||||||
{
|
{
|
||||||
|
// we found an element that makes it impossible to use the
|
||||||
// the initializer list describes an array
|
// initializer list as object
|
||||||
type_ = value_t::array;
|
is_object = false;
|
||||||
value_ = new array_t(a);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the initializer list is a list of pairs
|
// adjust type if type deduction is not wanted
|
||||||
type_ = value_t::object;
|
if (not type_deduction)
|
||||||
value_ = new object_t();
|
|
||||||
for (const json& element : a)
|
|
||||||
{
|
{
|
||||||
const std::string k = element[0];
|
// mark this object's type as final
|
||||||
value_.object->emplace(std::make_pair(std::move(k),
|
final_type_ = 1;
|
||||||
std::move(element[1])));
|
|
||||||
|
// if array is wanted, do not create an object though possible
|
||||||
|
if (manual_type == value_t::array)
|
||||||
|
{
|
||||||
|
is_object = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if object is wanted but impossible, throw an exception
|
||||||
|
if (manual_type == value_t::object and not is_object)
|
||||||
|
{
|
||||||
|
throw std::logic_error("cannot create JSON object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_object)
|
||||||
|
{
|
||||||
|
// the initializer list is a list of pairs -> create object
|
||||||
|
type_ = value_t::object;
|
||||||
|
value_ = new object_t();
|
||||||
|
for (auto& element : a)
|
||||||
|
{
|
||||||
|
value_.object->emplace(std::make_pair(std::move(element[0]), std::move(element[1])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the initializer list describes an array -> create array
|
||||||
|
type_ = value_t::array;
|
||||||
|
value_ = new array_t(std::move(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@param a initializer list to create an array from
|
||||||
|
@return array
|
||||||
|
*/
|
||||||
|
json json::array(list_init_t a)
|
||||||
|
{
|
||||||
|
return json(a, false, value_t::array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@param a initializer list to create an object from
|
||||||
|
@return object
|
||||||
|
*/
|
||||||
|
json json::object(list_init_t a)
|
||||||
|
{
|
||||||
|
// if more than one element is in the initializer list, wrap it
|
||||||
|
if (a.size() > 1)
|
||||||
|
{
|
||||||
|
return json({a}, false, value_t::object);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return json(a, false, value_t::object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
108
src/json.cc
108
src/json.cc
|
@ -84,6 +84,9 @@ json::json(const value_t t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json::json() noexcept : final_type_(0), type_(value_t::null)
|
||||||
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Construct a null JSON object.
|
Construct a null JSON object.
|
||||||
*/
|
*/
|
||||||
|
@ -96,35 +99,35 @@ Construct a string JSON object.
|
||||||
@param s a string to initialize the JSON object with
|
@param s a string to initialize the JSON object with
|
||||||
*/
|
*/
|
||||||
json::json(const std::string& s)
|
json::json(const std::string& s)
|
||||||
: type_(value_t::string), value_(new string_t(s))
|
: final_type_(0), type_(value_t::string), value_(new string_t(s))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(std::string&& s)
|
json::json(std::string&& s)
|
||||||
: type_(value_t::string), value_(new string_t(std::move(s)))
|
: final_type_(0), type_(value_t::string), value_(new string_t(std::move(s)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const char* s)
|
json::json(const char* s)
|
||||||
: type_(value_t::string), value_(new string_t(s))
|
: final_type_(0), type_(value_t::string), value_(new string_t(s))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const bool b) noexcept
|
json::json(const bool b) noexcept
|
||||||
: type_(value_t::boolean), value_(b)
|
: final_type_(0), type_(value_t::boolean), value_(b)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const array_t& a)
|
json::json(const array_t& a)
|
||||||
: type_(value_t::array), value_(new array_t(a))
|
: final_type_(0), type_(value_t::array), value_(new array_t(a))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(array_t&& a)
|
json::json(array_t&& a)
|
||||||
: type_(value_t::array), value_(new array_t(std::move(a)))
|
: final_type_(0), type_(value_t::array), value_(new array_t(std::move(a)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(const object_t& o)
|
json::json(const object_t& o)
|
||||||
: type_(value_t::object), value_(new object_t(o))
|
: final_type_(0), type_(value_t::object), value_(new object_t(o))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json::json(object_t&& o)
|
json::json(object_t&& o)
|
||||||
: type_(value_t::object), value_(new object_t(std::move(o)))
|
: final_type_(0), type_(value_t::object), value_(new object_t(std::move(o)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -141,33 +144,90 @@ as is to create an array.
|
||||||
|
|
||||||
@bug With the described approach, we would fail to recognize an array whose
|
@bug With the described approach, we would fail to recognize an array whose
|
||||||
first element is again an arrays as array.
|
first element is again an arrays as array.
|
||||||
|
|
||||||
|
@param a an initializer list to create from
|
||||||
|
@param type_deduction whether the type (array/object) shall eb deducted
|
||||||
|
@param manual_type if type deduction is switched of, pass a manual type
|
||||||
*/
|
*/
|
||||||
json::json(list_init_t a)
|
json::json(list_init_t a, bool type_deduction, value_t manual_type) : final_type_(0)
|
||||||
{
|
{
|
||||||
|
// the initializer list could describe an object
|
||||||
|
bool is_object = true;
|
||||||
|
|
||||||
// check if each element is an array with two elements whose first element
|
// check if each element is an array with two elements whose first element
|
||||||
// is a string
|
// is a string
|
||||||
for (const auto& element : a)
|
for (const auto& element : a)
|
||||||
{
|
{
|
||||||
if (element.type_ != value_t::array or
|
if ((element.final_type_ == 1 and element.type_ == value_t::array)
|
||||||
element.size() != 2 or
|
or (element.type_ != value_t::array or element.size() != 2 or element[0].type_ != value_t::string))
|
||||||
element[0].type_ != value_t::string)
|
|
||||||
{
|
{
|
||||||
|
// we found an element that makes it impossible to use the
|
||||||
// the initializer list describes an array
|
// initializer list as object
|
||||||
type_ = value_t::array;
|
is_object = false;
|
||||||
value_ = new array_t(a);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the initializer list is a list of pairs
|
// adjust type if type deduction is not wanted
|
||||||
type_ = value_t::object;
|
if (not type_deduction)
|
||||||
value_ = new object_t();
|
|
||||||
for (const json& element : a)
|
|
||||||
{
|
{
|
||||||
const std::string k = element[0];
|
// mark this object's type as final
|
||||||
value_.object->emplace(std::make_pair(std::move(k),
|
final_type_ = 1;
|
||||||
std::move(element[1])));
|
|
||||||
|
// if array is wanted, do not create an object though possible
|
||||||
|
if (manual_type == value_t::array)
|
||||||
|
{
|
||||||
|
is_object = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if object is wanted but impossible, throw an exception
|
||||||
|
if (manual_type == value_t::object and not is_object)
|
||||||
|
{
|
||||||
|
throw std::logic_error("cannot create JSON object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_object)
|
||||||
|
{
|
||||||
|
// the initializer list is a list of pairs -> create object
|
||||||
|
type_ = value_t::object;
|
||||||
|
value_ = new object_t();
|
||||||
|
for (auto& element : a)
|
||||||
|
{
|
||||||
|
value_.object->emplace(std::make_pair(std::move(element[0]), std::move(element[1])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the initializer list describes an array -> create array
|
||||||
|
type_ = value_t::array;
|
||||||
|
value_ = new array_t(std::move(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@param a initializer list to create an array from
|
||||||
|
@return array
|
||||||
|
*/
|
||||||
|
json json::array(list_init_t a)
|
||||||
|
{
|
||||||
|
return json(a, false, value_t::array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@param a initializer list to create an object from
|
||||||
|
@return object
|
||||||
|
*/
|
||||||
|
json json::object(list_init_t a)
|
||||||
|
{
|
||||||
|
// if more than one element is in the initializer list, wrap it
|
||||||
|
if (a.size() > 1)
|
||||||
|
{
|
||||||
|
return json({a}, false, value_t::object);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return json(a, false, value_t::object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/json.h
16
src/json.h
|
@ -140,7 +140,7 @@ class json
|
||||||
/// create an object according to given type
|
/// create an object according to given type
|
||||||
json(const value_t);
|
json(const value_t);
|
||||||
/// create a null object
|
/// create a null object
|
||||||
json() = default;
|
json() noexcept;
|
||||||
/// create a null object
|
/// create a null object
|
||||||
json(std::nullptr_t) noexcept;
|
json(std::nullptr_t) noexcept;
|
||||||
/// create a string object from a C++ string
|
/// create a string object from a C++ string
|
||||||
|
@ -160,7 +160,7 @@ class json
|
||||||
/// create an object (move)
|
/// create an object (move)
|
||||||
json(object_t&&);
|
json(object_t&&);
|
||||||
/// create from an initializer list (to an array or object)
|
/// create from an initializer list (to an array or object)
|
||||||
json(list_init_t);
|
json(list_init_t, bool = true, value_t = value_t::array);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a number object (integer)
|
@brief create a number object (integer)
|
||||||
|
@ -171,7 +171,7 @@ class json
|
||||||
std::numeric_limits<T>::is_integer, T>::type
|
std::numeric_limits<T>::is_integer, T>::type
|
||||||
= 0>
|
= 0>
|
||||||
json(const T n) noexcept
|
json(const T n) noexcept
|
||||||
: type_(value_t::number),
|
: final_type_(0), type_(value_t::number),
|
||||||
value_(static_cast<number_t>(n))
|
value_(static_cast<number_t>(n))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ class json
|
||||||
std::is_floating_point<T>::value>::type
|
std::is_floating_point<T>::value>::type
|
||||||
>
|
>
|
||||||
json(const T n) noexcept
|
json(const T n) noexcept
|
||||||
: type_(value_t::number_float),
|
: final_type_(0), type_(value_t::number_float),
|
||||||
value_(static_cast<number_float_t>(n))
|
value_(static_cast<number_float_t>(n))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -229,6 +229,11 @@ class json
|
||||||
/// destructor
|
/// destructor
|
||||||
~json() noexcept;
|
~json() noexcept;
|
||||||
|
|
||||||
|
/// explicit keyword to force array creation
|
||||||
|
static json array(list_init_t = list_init_t());
|
||||||
|
/// explicit keyword to force object creation
|
||||||
|
static json object(list_init_t = list_init_t());
|
||||||
|
|
||||||
/// create from string representation
|
/// create from string representation
|
||||||
static json parse(const std::string&);
|
static json parse(const std::string&);
|
||||||
/// create from string representation
|
/// create from string representation
|
||||||
|
@ -404,9 +409,10 @@ class json
|
||||||
const_reverse_iterator crend() const noexcept;
|
const_reverse_iterator crend() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// whether the type is final
|
||||||
|
unsigned final_type_ : 1;
|
||||||
/// the type of this object
|
/// the type of this object
|
||||||
value_t type_ = value_t::null;
|
value_t type_ = value_t::null;
|
||||||
|
|
||||||
/// the payload
|
/// the payload
|
||||||
value value_ {};
|
value value_ {};
|
||||||
|
|
||||||
|
|
|
@ -304,13 +304,70 @@ TEST_CASE("array")
|
||||||
CHECK(v == vec[static_cast<size_t>(v)]);
|
CHECK(v == vec[static_cast<size_t>(v)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Initializer lists")
|
||||||
|
{
|
||||||
// edge case: This should be an array with two elements which are in
|
// edge case: This should be an array with two elements which are in
|
||||||
// turn arrays with two strings. However, this is treated like the
|
// turn arrays with two strings. However, this is treated like the
|
||||||
// initializer list of an object.
|
// initializer list of an object.
|
||||||
json j_should_be_an_array = { {"foo", "bar"}, {"baz", "bat"} };
|
json j_should_be_an_array = { {"foo", "bar"}, {"baz", "bat"} };
|
||||||
CHECK(j_should_be_an_array.type() == json::value_t::object);
|
CHECK(j_should_be_an_array.type() == json::value_t::object);
|
||||||
|
|
||||||
|
json j_is_an_array = { json::array({"foo", "bar"}), {"baz", "bat"} };
|
||||||
|
CHECK(j_is_an_array.type() == json::value_t::array);
|
||||||
|
|
||||||
|
// array outside initializer list
|
||||||
|
json j_pair_array = json::array({"s1", "s2"});
|
||||||
|
CHECK(j_pair_array.type() == json::value_t::array);
|
||||||
|
|
||||||
|
// array inside initializer list
|
||||||
|
json j_pair_array2 = {json::array({"us1", "us2"})};
|
||||||
|
CHECK(j_pair_array2.type() == json::value_t::array);
|
||||||
|
|
||||||
|
// array() is []
|
||||||
|
json j_empty_array_explicit = json::array();
|
||||||
|
CHECK(j_empty_array_explicit.type() == json::value_t::array);
|
||||||
|
|
||||||
|
// object() is []
|
||||||
|
json j_empty_object_explicit = json::object();
|
||||||
|
CHECK(j_empty_object_explicit.type() == json::value_t::object);
|
||||||
|
|
||||||
|
// {object({"s1", "s2"})} is [{"s1": "s2"}]
|
||||||
|
json j_explicit_object = {json::object({"s1", "s2"})};
|
||||||
|
CHECK(j_explicit_object.type() == json::value_t::array);
|
||||||
|
|
||||||
|
// object({"s1", "s2"}) is [{"s1": "s2"}]
|
||||||
|
json j_explicit_object2 = json::object({"s1", "s2"});
|
||||||
|
CHECK(j_explicit_object2.type() == json::value_t::object);
|
||||||
|
|
||||||
|
// object({{"s1", "s2"}}) is [{"s1": "s2"}]
|
||||||
|
json j_explicit_object3 = json::object({{"s1", "s2"}});
|
||||||
|
CHECK(j_explicit_object3.type() == json::value_t::object);
|
||||||
|
|
||||||
|
// check errors when explicit object creation is demanded
|
||||||
|
CHECK_THROWS_AS(json::object({"s1"}), std::logic_error);
|
||||||
|
CHECK_THROWS_AS(json::object({"s1", 1, 3}), std::logic_error);
|
||||||
|
CHECK_THROWS_AS(json::object({1, "s1"}), std::logic_error);
|
||||||
|
CHECK_THROWS_AS(json::object({{1, "s1"}}), std::logic_error);
|
||||||
|
CHECK_THROWS_AS(json::object({{"foo", "bar"}, {1, "s1"}}), std::logic_error);
|
||||||
|
|
||||||
|
// {} is null
|
||||||
|
json j_null = {};
|
||||||
|
CHECK(j_null.type() == json::value_t::null);
|
||||||
|
|
||||||
|
// {{}} is []
|
||||||
|
json j_empty_array_implicit = {{}};
|
||||||
|
CHECK(j_empty_array_implicit.type() == json::value_t::array);
|
||||||
|
|
||||||
|
// {1} is [1]
|
||||||
|
json j_singleton_array = {1};
|
||||||
|
CHECK(j_singleton_array.type() == json::value_t::array);
|
||||||
|
|
||||||
|
// test case from issue #8
|
||||||
|
json j_issue8 = {json::array({"a", "b"}), json::array({"c", "d"})};
|
||||||
|
CHECK(j_issue8.type() == json::value_t::array);
|
||||||
|
CHECK(j_issue8.dump() == "[[\"a\",\"b\"],[\"c\",\"d\"]]");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Iterators and empty arrays")
|
SECTION("Iterators and empty arrays")
|
||||||
|
|
Loading…
Reference in a new issue