Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
3d67ec40
Unverified
Commit
3d67ec40
authored
Jul 30, 2017
by
Niels Lohmann
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of
https://github.com/nlohmann/json
into develop
parents
85c76808
67fb517c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
361 additions
and
104 deletions
+361
-104
CMakeLists.txt
CMakeLists.txt
+66
-44
config.cmake.in
cmake/config.cmake.in
+2
-6
json.hpp
src/json.hpp
+165
-36
unit-constructor1.cpp
test/src/unit-constructor1.cpp
+128
-18
No files found.
CMakeLists.txt
View file @
3d67ec40
cmake_minimum_required
(
VERSION 3.0
)
cmake_minimum_required
(
VERSION 3.0
.0
)
# define the project
##
project
(
nlohmann_json VERSION 2.1.1 LANGUAGES CXX
)
## PROJECT
## name and version
##
project
(
nlohmann_json VERSION 2.1.1
)
##
## OPTIONS
##
option
(
JSON_BuildTests
"Build the unit tests"
ON
)
option
(
JSON_BuildTests
"Build the unit tests"
ON
)
# define project variables
##
set
(
JSON_TARGET_NAME
${
PROJECT_NAME
}
)
## CONFIGURATION
set
(
JSON_PACKAGE_NAME
${
JSON_TARGET_NAME
}
)
##
set
(
JSON_TARGETS_FILENAME
"
${
JSON_PACKAGE_NAME
}
Targets.cmake"
)
set
(
NLOHMANN_JSON_TARGET_NAME
${
PROJECT_NAME
}
)
set
(
JSON_CONFIG_FILENAME
"
${
JSON_PACKAGE_NAME
}
Config.cmake"
)
set
(
NLOHMANN_JSON_SOURCE_DIR
"src/"
)
set
(
JSON_CONFIGVERSION_FILENAME
"
${
JSON_PACKAGE_NAME
}
ConfigVersion.cmake"
)
set
(
NLOHMANN_JSON_CONFIG_INSTALL_DIR
"lib/cmake/
${
PROJECT_NAME
}
"
)
set
(
JSON_CONFIG_DESTINATION
"cmake"
)
set
(
NLOHMANN_JSON_INCLUDE_INSTALL_DIR
"include"
)
set
(
JSON_INCLUDE_DESTINATION
"include/nlohmann"
)
set
(
NLOHMANN_JSON_HEADER_INSTALL_DIR
"
${
NLOHMANN_JSON_INCLUDE_INSTALL_DIR
}
/nlohmann"
)
set
(
NLOHMANN_JSON_TARGETS_EXPORT_NAME
"
${
PROJECT_NAME
}
Targets"
)
set
(
NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE
"cmake/config.cmake.in"
)
set
(
NLOHMANN_JSON_CMAKE_CONFIG_DIR
"
${
CMAKE_CURRENT_BINARY_DIR
}
/cmake_config"
)
set
(
NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE
"
${
NLOHMANN_JSON_CMAKE_CONFIG_DIR
}
/
${
PROJECT_NAME
}
ConfigVersion.cmake"
)
set
(
NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE
"
${
NLOHMANN_JSON_CMAKE_CONFIG_DIR
}
/
${
PROJECT_NAME
}
Config.cmake"
)
set
(
CMAKE_MODULE_PATH
"
${
CMAKE_SOURCE_DIR
}
/cmake"
)
##
## TARGET
## create target and add include path
##
add_library
(
${
NLOHMANN_JSON_TARGET_NAME
}
INTERFACE
)
# create and configure the library target
target_include_directories
(
add_library
(
${
JSON_TARGET_NAME
}
INTERFACE
)
${
NLOHMANN_JSON_TARGET_NAME
}
target_include_directories
(
${
JSON_TARGET_NAME
}
INTERFACE
INTERFACE $<INSTALL_INTERFACE:include/>
$<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/src>
)
$<INSTALL_INTERFACE:
${
JSON_INCLUDE_DESTINATION
}
>
)
##
# create and configure the unit test target
## TESTS
## create and configure the unit test target
##
if
(
JSON_BuildTests
)
if
(
JSON_BuildTests
)
enable_testing
()
enable_testing
()
include_directories
(
${
NLOHMANN_JSON_SOURCE_DIR
}
)
add_subdirectory
(
test
)
add_subdirectory
(
test
)
endif
()
endif
()
# generate a config and config version file for the package
##
## INSTALL
## install header files, generate and install cmake config files for find_package()
##
include
(
CMakePackageConfigHelpers
)
include
(
CMakePackageConfigHelpers
)
configure_package_config_file
(
"cmake/config.cmake.in"
write_basic_package_version_file
(
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
JSON_CONFIG_FILENAME
}
"
${
NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE
}
COMPATIBILITY SameMajorVersion
INSTALL_DESTINATION
${
JSON_CONFIG_DESTINATION
}
)
PATH_VARS JSON_INCLUDE_DESTINATION
)
configure_package_config_file
(
write_basic_package_version_file
(
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
JSON_CONFIGVERSION_FILENAME
}
"
${
NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE
}
VERSION
${
PROJECT_VERSION
}
${
NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE
}
COMPATIBILITY SameMajorVersion
)
INSTALL_DESTINATION
${
NLOHMANN_JSON_CONFIG_INSTALL_DIR
}
)
# export the library target and store build directory in package registry
install
(
export
(
TARGETS
${
JSON_TARGET_NAME
}
DIRECTORY
${
NLOHMANN_JSON_SOURCE_DIR
}
FILE
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
JSON_TARGETS_FILENAME
}
"
)
DESTINATION
${
NLOHMANN_JSON_HEADER_INSTALL_DIR
}
export
(
PACKAGE
${
JSON_PACKAGE_NAME
}
)
)
install
(
# install library target and config files
FILES
${
NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE
}
${
NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE
}
install
(
TARGETS
${
JSON_TARGET_NAME
}
DESTINATION
${
NLOHMANN_JSON_CONFIG_INSTALL_DIR
}
EXPORT
${
JSON_PACKAGE_NAME
}
)
)
install
(
FILES
"src/json.hpp"
install
(
DESTINATION
${
JSON_INCLUDE_DESTINATION
}
)
TARGETS
${
NLOHMANN_JSON_TARGET_NAME
}
install
(
EXPORT
${
JSON_PACKAGE_NAME
}
EXPORT
${
NLOHMANN_JSON_TARGETS_EXPORT_NAME
}
FILE
${
JSON_TARGETS_FILENAME
}
INCLUDES DESTINATION
${
NLOHMANN_JSON_INCLUDE_INSTALL_DIR
}
DESTINATION
${
JSON_CONFIG_DESTINATION
}
)
)
install
(
FILES
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
JSON_CONFIG_FILENAME
}
"
install
(
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
JSON_CONFIGVERSION_FILENAME
}
"
EXPORT
${
NLOHMANN_JSON_TARGETS_EXPORT_NAME
}
DESTINATION
${
JSON_CONFIG_DESTINATION
}
)
DESTINATION
${
NLOHMANN_JSON_CONFIG_INSTALL_DIR
}
)
cmake/config.cmake.in
View file @
3d67ec40
@PACKAGE_INIT@
@PACKAGE_INIT@
set_and_check(JSON_INCLUDE_DIR "@PACKAGE_JSON_INCLUDE_DESTINATION@")
include("${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")
cmake_policy(PUSH)
cmake_policy(SET CMP0024 OLD)
include(${CMAKE_CURRENT_LIST_DIR}/@JSON_TARGETS_FILENAME@)
cmake_policy(POP)
src/json.hpp
View file @
3d67ec40
...
@@ -575,6 +575,14 @@ struct external_constructor<value_t::string>
...
@@ -575,6 +575,14 @@ struct external_constructor<value_t::string>
j
.
m_value
=
s
;
j
.
m_value
=
s
;
j
.
assert_invariant
();
j
.
assert_invariant
();
}
}
template
<
typename
BasicJsonType
>
static
void
construct
(
BasicJsonType
&
j
,
typename
BasicJsonType
::
string_t
&&
s
)
{
j
.
m_type
=
value_t
::
string
;
j
.
m_value
=
std
::
move
(
s
);
j
.
assert_invariant
();
}
};
};
template
<>
template
<>
...
@@ -624,6 +632,14 @@ struct external_constructor<value_t::array>
...
@@ -624,6 +632,14 @@ struct external_constructor<value_t::array>
j
.
assert_invariant
();
j
.
assert_invariant
();
}
}
template
<
typename
BasicJsonType
>
static
void
construct
(
BasicJsonType
&
j
,
typename
BasicJsonType
::
array_t
&&
arr
)
{
j
.
m_type
=
value_t
::
array
;
j
.
m_value
=
std
::
move
(
arr
);
j
.
assert_invariant
();
}
template
<
typename
BasicJsonType
,
typename
CompatibleArrayType
,
template
<
typename
BasicJsonType
,
typename
CompatibleArrayType
,
enable_if_t
<
not
std
::
is_same
<
CompatibleArrayType
,
enable_if_t
<
not
std
::
is_same
<
CompatibleArrayType
,
typename
BasicJsonType
::
array_t
>::
value
,
typename
BasicJsonType
::
array_t
>::
value
,
...
@@ -662,6 +678,14 @@ struct external_constructor<value_t::object>
...
@@ -662,6 +678,14 @@ struct external_constructor<value_t::object>
j
.
assert_invariant
();
j
.
assert_invariant
();
}
}
template
<
typename
BasicJsonType
>
static
void
construct
(
BasicJsonType
&
j
,
typename
BasicJsonType
::
object_t
&&
obj
)
{
j
.
m_type
=
value_t
::
object
;
j
.
m_value
=
std
::
move
(
obj
);
j
.
assert_invariant
();
}
template
<
typename
BasicJsonType
,
typename
CompatibleObjectType
,
template
<
typename
BasicJsonType
,
typename
CompatibleObjectType
,
enable_if_t
<
not
std
::
is_same
<
CompatibleObjectType
,
enable_if_t
<
not
std
::
is_same
<
CompatibleObjectType
,
typename
BasicJsonType
::
object_t
>::
value
,
int
>
=
0
>
typename
BasicJsonType
::
object_t
>::
value
,
int
>
=
0
>
...
@@ -850,6 +874,12 @@ void to_json(BasicJsonType& j, const CompatibleString& s)
...
@@ -850,6 +874,12 @@ void to_json(BasicJsonType& j, const CompatibleString& s)
external_constructor
<
value_t
::
string
>::
construct
(
j
,
s
);
external_constructor
<
value_t
::
string
>::
construct
(
j
,
s
);
}
}
template
<
typename
BasicJsonType
>
void
to_json
(
BasicJsonType
&
j
,
typename
BasicJsonType
::
string_t
&&
s
)
{
external_constructor
<
value_t
::
string
>::
construct
(
j
,
std
::
move
(
s
));
}
template
<
typename
BasicJsonType
,
typename
FloatType
,
template
<
typename
BasicJsonType
,
typename
FloatType
,
enable_if_t
<
std
::
is_floating_point
<
FloatType
>::
value
,
int
>
=
0
>
enable_if_t
<
std
::
is_floating_point
<
FloatType
>::
value
,
int
>
=
0
>
void
to_json
(
BasicJsonType
&
j
,
FloatType
val
)
noexcept
void
to_json
(
BasicJsonType
&
j
,
FloatType
val
)
noexcept
...
@@ -900,13 +930,25 @@ void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
...
@@ -900,13 +930,25 @@ void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
external_constructor
<
value_t
::
array
>::
construct
(
j
,
arr
);
external_constructor
<
value_t
::
array
>::
construct
(
j
,
arr
);
}
}
template
<
typename
BasicJsonType
>
void
to_json
(
BasicJsonType
&
j
,
typename
BasicJsonType
::
array_t
&&
arr
)
{
external_constructor
<
value_t
::
array
>::
construct
(
j
,
std
::
move
(
arr
));
}
template
<
template
<
typename
BasicJsonType
,
typename
CompatibleObjectType
,
typename
BasicJsonType
,
typename
CompatibleObjectType
,
enable_if_t
<
is_compatible_object_type
<
BasicJsonType
,
CompatibleObjectType
>::
value
,
enable_if_t
<
is_compatible_object_type
<
BasicJsonType
,
CompatibleObjectType
>::
value
,
int
>
=
0
>
int
>
=
0
>
void
to_json
(
BasicJsonType
&
j
,
const
CompatibleObjectType
&
arr
)
void
to_json
(
BasicJsonType
&
j
,
const
CompatibleObjectType
&
obj
)
{
external_constructor
<
value_t
::
object
>::
construct
(
j
,
obj
);
}
template
<
typename
BasicJsonType
>
void
to_json
(
BasicJsonType
&
j
,
typename
BasicJsonType
::
object_t
&&
obj
)
{
{
external_constructor
<
value_t
::
object
>::
construct
(
j
,
arr
);
external_constructor
<
value_t
::
object
>::
construct
(
j
,
std
::
move
(
obj
)
);
}
}
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
,
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
,
...
@@ -6799,6 +6841,67 @@ class serializer
...
@@ -6799,6 +6841,67 @@ class serializer
/// the indentation string
/// the indentation string
string_t
indent_string
;
string_t
indent_string
;
};
};
template
<
typename
BasicJsonType
>
struct
json_ref
{
typedef
BasicJsonType
value_type
;
json_ref
(
value_type
&&
value
)
:
owned_value_
(
std
::
move
(
value
))
,
is_rvalue_
(
true
)
{
value_ref_
=
&
owned_value_
;
}
json_ref
(
const
value_type
&
value
)
:
value_ref_
(
const_cast
<
value_type
*>
(
&
value
))
,
is_rvalue_
(
false
)
{}
json_ref
(
std
::
initializer_list
<
json_ref
>
init
)
:
owned_value_
(
init
)
,
is_rvalue_
(
true
)
{
value_ref_
=
&
owned_value_
;
}
template
<
class
...
Args
>
json_ref
(
Args
...
args
)
:
owned_value_
(
std
::
forward
<
Args
>
(
args
)...)
,
is_rvalue_
(
true
)
{
value_ref_
=
&
owned_value_
;
}
value_type
moved_or_copied
()
const
{
if
(
is_rvalue_
)
{
return
std
::
move
(
*
value_ref_
);
}
else
{
return
*
value_ref_
;
}
}
value_type
const
&
operator
*
()
const
{
return
*
static_cast
<
value_type
const
*>
(
value_ref_
);
}
value_type
const
*
operator
->
()
const
{
return
static_cast
<
value_type
const
*>
(
value_ref_
);
}
private
:
value_type
*
value_ref_
;
mutable
value_type
owned_value_
;
bool
is_rvalue_
;
};
}
// namespace detail
}
// namespace detail
/// namespace to hold default `to_json` / `from_json` functions
/// namespace to hold default `to_json` / `from_json` functions
...
@@ -7297,6 +7400,7 @@ class basic_json
...
@@ -7297,6 +7400,7 @@ class basic_json
template
<
typename
T
,
typename
SFINAE
>
template
<
typename
T
,
typename
SFINAE
>
using
json_serializer
=
JSONSerializer
<
T
,
SFINAE
>
;
using
json_serializer
=
JSONSerializer
<
T
,
SFINAE
>
;
using
initializer_list_t
=
std
::
initializer_list
<
detail
::
json_ref
<
basic_json
>>
;
////////////////
////////////////
// exceptions //
// exceptions //
...
@@ -8025,18 +8129,36 @@ class basic_json
...
@@ -8025,18 +8129,36 @@ class basic_json
string
=
create
<
string_t
>
(
value
);
string
=
create
<
string_t
>
(
value
);
}
}
/// constructor for rvalue strings
json_value
(
string_t
&&
value
)
{
string
=
create
<
string_t
>
(
std
::
move
(
value
));
}
/// constructor for objects
/// constructor for objects
json_value
(
const
object_t
&
value
)
json_value
(
const
object_t
&
value
)
{
{
object
=
create
<
object_t
>
(
value
);
object
=
create
<
object_t
>
(
value
);
}
}
/// constructor for rvalue objects
json_value
(
object_t
&&
value
)
{
object
=
create
<
object_t
>
(
std
::
move
(
value
));
}
/// constructor for arrays
/// constructor for arrays
json_value
(
const
array_t
&
value
)
json_value
(
const
array_t
&
value
)
{
{
array
=
create
<
array_t
>
(
value
);
array
=
create
<
array_t
>
(
value
);
}
}
/// constructor for rvalue arrays
json_value
(
array_t
&&
value
)
{
array
=
create
<
array_t
>
(
std
::
move
(
value
));
}
void
destroy
(
value_t
t
)
void
destroy
(
value_t
t
)
{
{
switch
(
t
)
switch
(
t
)
...
@@ -8310,10 +8432,10 @@ class basic_json
...
@@ -8310,10 +8432,10 @@ class basic_json
With the rules described above, the following JSON values cannot be
With the rules described above, the following JSON values cannot be
expressed by an initializer list:
expressed by an initializer list:
- the empty array (`[]`): use @ref array(
std::initializer_list<basic_json>
)
- the empty array (`[]`): use @ref array(
initializer_list_t
)
with an empty initializer list in this case
with an empty initializer list in this case
- arrays whose elements satisfy rule 2: use @ref
- arrays whose elements satisfy rule 2: use @ref
array(
std::initializer_list<basic_json>
) with the same initializer list
array(
initializer_list_t
) with the same initializer list
in this case
in this case
@note When used without parentheses around an empty initializer list, @ref
@note When used without parentheses around an empty initializer list, @ref
...
@@ -8325,8 +8447,8 @@ class basic_json
...
@@ -8325,8 +8447,8 @@ class basic_json
@param[in] type_deduction internal parameter; when set to `true`, the type
@param[in] type_deduction internal parameter; when set to `true`, the type
of the JSON value is deducted from the initializer list @a init; when set
of the JSON value is deducted from the initializer list @a init; when set
to `false`, the type provided via @a manual_type is forced. This mode is
to `false`, the type provided via @a manual_type is forced. This mode is
used by the functions @ref array(
std::initializer_list<basic_json>
) and
used by the functions @ref array(
initializer_list_t
) and
@ref object(
std::initializer_list<basic_json>
).
@ref object(
initializer_list_t
).
@param[in] manual_type internal parameter; when @a type_deduction is set
@param[in] manual_type internal parameter; when @a type_deduction is set
to `false`, the created JSON value will use the provided type (only @ref
to `false`, the created JSON value will use the provided type (only @ref
...
@@ -8337,7 +8459,7 @@ class basic_json
...
@@ -8337,7 +8459,7 @@ class basic_json
`value_t::object`, but @a init contains an element which is not a pair
`value_t::object`, but @a init contains an element which is not a pair
whose first element is a string. In this case, the constructor could not
whose first element is a string. In this case, the constructor could not
create an object. If @a type_deduction would have be `true`, an array
create an object. If @a type_deduction would have be `true`, an array
would have been created. See @ref object(
std::initializer_list<basic_json>
)
would have been created. See @ref object(
initializer_list_t
)
for an example.
for an example.
@complexity Linear in the size of the initializer list @a init.
@complexity Linear in the size of the initializer list @a init.
...
@@ -8345,23 +8467,23 @@ class basic_json
...
@@ -8345,23 +8467,23 @@ class basic_json
@liveexample{The example below shows how JSON values are created from
@liveexample{The example below shows how JSON values are created from
initializer lists.,basic_json__list_init_t}
initializer lists.,basic_json__list_init_t}
@sa @ref array(
std::initializer_list<basic_json>
) -- create a JSON array
@sa @ref array(
initializer_list_t
) -- create a JSON array
value from an initializer list
value from an initializer list
@sa @ref object(
std::initializer_list<basic_json>
) -- create a JSON object
@sa @ref object(
initializer_list_t
) -- create a JSON object
value from an initializer list
value from an initializer list
@since version 1.0.0
@since version 1.0.0
*/
*/
basic_json
(
std
::
initializer_list
<
basic_json
>
init
,
basic_json
(
initializer_list_t
init
,
bool
type_deduction
=
true
,
bool
type_deduction
=
true
,
value_t
manual_type
=
value_t
::
array
)
value_t
manual_type
=
value_t
::
array
)
{
{
// check if each element is an array with two elements whose first
// check if each element is an array with two elements whose first
// element is a string
// element is a string
bool
is_an_object
=
std
::
all_of
(
init
.
begin
(),
init
.
end
(),
bool
is_an_object
=
std
::
all_of
(
init
.
begin
(),
init
.
end
(),
[](
const
basic_json
&
element
)
[](
const
detail
::
json_ref
<
basic_json
>&
element_ref
)
{
{
return
(
element
.
is_array
()
and
element
.
size
()
==
2
and
element
[
0
].
is_string
());
return
(
element
_ref
->
is_array
()
and
element_ref
->
size
()
==
2
and
(
*
element_ref
)
[
0
].
is_string
());
});
});
// adjust type if type deduction is not wanted
// adjust type if type deduction is not wanted
...
@@ -8386,16 +8508,19 @@ class basic_json
...
@@ -8386,16 +8508,19 @@ class basic_json
m_type
=
value_t
::
object
;
m_type
=
value_t
::
object
;
m_value
=
value_t
::
object
;
m_value
=
value_t
::
object
;
std
::
for_each
(
init
.
begin
(),
init
.
end
(),
[
this
](
const
basic_json
&
element
)
std
::
for_each
(
init
.
begin
(),
init
.
end
(),
[
this
](
const
detail
::
json_ref
<
basic_json
>&
element_ref
)
{
{
m_value
.
object
->
emplace
(
*
(
element
[
0
].
m_value
.
string
),
element
[
1
]);
basic_json
element
=
element_ref
.
moved_or_copied
();
m_value
.
object
->
emplace
(
std
::
move
(
*
((
*
element
.
m_value
.
array
)[
0
].
m_value
.
string
)),
std
::
move
((
*
element
.
m_value
.
array
)[
1
]));
});
});
}
}
else
else
{
{
// 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
;
m_value
.
array
=
create
<
array_t
>
(
init
);
m_value
.
array
=
create
<
array_t
>
(
init
.
begin
(),
init
.
end
()
);
}
}
assert_invariant
();
assert_invariant
();
...
@@ -8410,7 +8535,7 @@ class basic_json
...
@@ -8410,7 +8535,7 @@ class basic_json
@note This function is only needed to express two edge cases that cannot
@note This function is only needed to express two edge cases that cannot
be realized with the initializer list constructor (@ref
be realized with the initializer list constructor (@ref
basic_json(
std::initializer_list<basic_json>
, bool, value_t)). These cases
basic_json(
initializer_list_t
, bool, value_t)). These cases
are:
are:
1. creating an array whose elements are all pairs whose first element is a
1. creating an array whose elements are all pairs whose first element is a
string -- in this case, the initializer list constructor would create an
string -- in this case, the initializer list constructor would create an
...
@@ -8428,15 +8553,14 @@ class basic_json
...
@@ -8428,15 +8553,14 @@ class basic_json
@liveexample{The following code shows an example for the `array`
@liveexample{The following code shows an example for the `array`
function.,array}
function.,array}
@sa @ref basic_json(
std::initializer_list<basic_json>
, bool, value_t) --
@sa @ref basic_json(
initializer_list_t
, bool, value_t) --
create a JSON value from an initializer list
create a JSON value from an initializer list
@sa @ref object(
std::initializer_list<basic_json>
) -- create a JSON object
@sa @ref object(
initializer_list_t
) -- create a JSON object
value from an initializer list
value from an initializer list
@since version 1.0.0
@since version 1.0.0
*/
*/
static
basic_json
array
(
std
::
initializer_list
<
basic_json
>
init
=
static
basic_json
array
(
initializer_list_t
init
=
{})
std
::
initializer_list
<
basic_json
>
())
{
{
return
basic_json
(
init
,
false
,
value_t
::
array
);
return
basic_json
(
init
,
false
,
value_t
::
array
);
}
}
...
@@ -8449,10 +8573,10 @@ class basic_json
...
@@ -8449,10 +8573,10 @@ class basic_json
the initializer list is empty, the empty object `{}` is created.
the initializer list is empty, the empty object `{}` is created.
@note This function is only added for symmetry reasons. In contrast to the
@note This function is only added for symmetry reasons. In contrast to the
related function @ref array(
std::initializer_list<basic_json>
), there are
related function @ref array(
initializer_list_t
), there are
no cases which can only be expressed by this function. That is, any
no cases which can only be expressed by this function. That is, any
initializer list @a init can also be passed to the initializer list
initializer list @a init can also be passed to the initializer list
constructor @ref basic_json(
std::initializer_list<basic_json>
, bool, value_t).
constructor @ref basic_json(
initializer_list_t
, bool, value_t).
@param[in] init initializer list to create an object from (optional)
@param[in] init initializer list to create an object from (optional)
...
@@ -8460,7 +8584,7 @@ class basic_json
...
@@ -8460,7 +8584,7 @@ class basic_json
@throw type_error.301 if @a init is not a list of pairs whose first
@throw type_error.301 if @a init is not a list of pairs whose first
elements are strings. In this case, no object can be created. When such a
elements are strings. In this case, no object can be created. When such a
value is passed to @ref basic_json(
std::initializer_list<basic_json>
, bool, value_t),
value is passed to @ref basic_json(
initializer_list_t
, bool, value_t),
an array would have been created from the passed initializer list @a init.
an array would have been created from the passed initializer list @a init.
See example below.
See example below.
...
@@ -8469,15 +8593,14 @@ class basic_json
...
@@ -8469,15 +8593,14 @@ class basic_json
@liveexample{The following code shows an example for the `object`
@liveexample{The following code shows an example for the `object`
function.,object}
function.,object}
@sa @ref basic_json(
std::initializer_list<basic_json>
, bool, value_t) --
@sa @ref basic_json(
initializer_list_t
, bool, value_t) --
create a JSON value from an initializer list
create a JSON value from an initializer list
@sa @ref array(
std::initializer_list<basic_json>
) -- create a JSON array
@sa @ref array(
initializer_list_t
) -- create a JSON array
value from an initializer list
value from an initializer list
@since version 1.0.0
@since version 1.0.0
*/
*/
static
basic_json
object
(
std
::
initializer_list
<
basic_json
>
init
=
static
basic_json
object
(
initializer_list_t
init
=
{})
std
::
initializer_list
<
basic_json
>
())
{
{
return
basic_json
(
init
,
false
,
value_t
::
object
);
return
basic_json
(
init
,
false
,
value_t
::
object
);
}
}
...
@@ -8650,6 +8773,11 @@ class basic_json
...
@@ -8650,6 +8773,11 @@ class basic_json
// other constructors and destructor //
// other constructors and destructor //
///////////////////////////////////////
///////////////////////////////////////
basic_json
(
const
detail
::
json_ref
<
basic_json
>&
ref
)
:
basic_json
(
ref
.
moved_or_copied
())
{
}
/*!
/*!
@brief copy constructor
@brief copy constructor
...
@@ -11450,7 +11578,7 @@ class basic_json
...
@@ -11450,7 +11578,7 @@ class basic_json
@brief add an object to an array
@brief add an object to an array
@copydoc push_back(basic_json&&)
@copydoc push_back(basic_json&&)
*/
*/
reference
operator
+=
(
basic_json
&&
val
)
reference
operator
+=
(
basic_json
&&
val
)
{
{
push_back
(
std
::
move
(
val
));
push_back
(
std
::
move
(
val
));
return
*
this
;
return
*
this
;
...
@@ -11565,12 +11693,13 @@ class basic_json
...
@@ -11565,12 +11693,13 @@ class basic_json
@liveexample{The example shows how initializer lists are treated as
@liveexample{The example shows how initializer lists are treated as
objects when possible.,push_back__initializer_list}
objects when possible.,push_back__initializer_list}
*/
*/
void
push_back
(
std
::
initializer_list
<
basic_json
>
init
)
void
push_back
(
initializer_list_t
init
)
{
{
if
(
is_object
()
and
init
.
size
()
==
2
and
init
.
begin
(
)
->
is_string
())
if
(
is_object
()
and
init
.
size
()
==
2
and
(
*
init
.
begin
()
)
->
is_string
())
{
{
const
string_t
key
=
*
init
.
begin
();
basic_json
&&
key
=
init
.
begin
()
->
moved_or_copied
();
push_back
(
typename
object_t
::
value_type
(
key
,
*
(
init
.
begin
()
+
1
)));
push_back
(
typename
object_t
::
value_type
(
std
::
move
(
key
.
get_ref
<
string_t
&>
()),
(
init
.
begin
()
+
1
)
->
moved_or_copied
()));
}
}
else
else
{
{
...
@@ -11580,9 +11709,9 @@ class basic_json
...
@@ -11580,9 +11709,9 @@ class basic_json
/*!
/*!
@brief add an object to an object
@brief add an object to an object
@copydoc push_back(
std::initializer_list<basic_json>
)
@copydoc push_back(
initializer_list_t
)
*/
*/
reference
operator
+=
(
std
::
initializer_list
<
basic_json
>
init
)
reference
operator
+=
(
initializer_list_t
init
)
{
{
push_back
(
init
);
push_back
(
init
);
return
*
this
;
return
*
this
;
...
@@ -11867,7 +11996,7 @@ class basic_json
...
@@ -11867,7 +11996,7 @@ class basic_json
@since version 1.0.0
@since version 1.0.0
*/
*/
iterator
insert
(
const_iterator
pos
,
std
::
initializer_list
<
basic_json
>
ilist
)
iterator
insert
(
const_iterator
pos
,
initializer_list_t
ilist
)
{
{
// insert only works for arrays
// insert only works for arrays
if
(
JSON_UNLIKELY
(
not
is_array
()))
if
(
JSON_UNLIKELY
(
not
is_array
()))
...
@@ -11883,7 +12012,7 @@ class basic_json
...
@@ -11883,7 +12012,7 @@ class basic_json
// insert to array and return iterator
// insert to array and return iterator
iterator
result
(
this
);
iterator
result
(
this
);
result
.
m_it
.
array_iterator
=
m_value
.
array
->
insert
(
pos
.
m_it
.
array_iterator
,
ilist
);
result
.
m_it
.
array_iterator
=
m_value
.
array
->
insert
(
pos
.
m_it
.
array_iterator
,
ilist
.
begin
(),
ilist
.
end
()
);
return
result
;
return
result
;
}
}
...
...
test/src/unit-constructor1.cpp
View file @
3d67ec40
...
@@ -842,8 +842,7 @@ TEST_CASE("constructors")
...
@@ -842,8 +842,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
;
json
j
(
json
::
initializer_list_t
{});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
object
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
object
);
}
}
...
@@ -860,8 +859,7 @@ TEST_CASE("constructors")
...
@@ -860,8 +859,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
json
(
json
::
array_t
())};
json
j
(
json
::
initializer_list_t
{
json
(
json
::
array_t
())});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -876,8 +874,7 @@ TEST_CASE("constructors")
...
@@ -876,8 +874,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
json
(
json
::
object_t
())};
json
j
(
json
::
initializer_list_t
{
json
(
json
::
object_t
())});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -892,8 +889,7 @@ TEST_CASE("constructors")
...
@@ -892,8 +889,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
json
(
"Hello world"
)};
json
j
(
json
::
initializer_list_t
{
json
(
"Hello world"
)});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -908,8 +904,7 @@ TEST_CASE("constructors")
...
@@ -908,8 +904,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
json
(
true
)};
json
j
(
json
::
initializer_list_t
{
json
(
true
)});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -924,8 +919,7 @@ TEST_CASE("constructors")
...
@@ -924,8 +919,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
json
(
1
)};
json
j
(
json
::
initializer_list_t
{
json
(
1
)});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -940,8 +934,7 @@ TEST_CASE("constructors")
...
@@ -940,8 +934,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
json
(
1u
)};
json
j
(
json
::
initializer_list_t
{
json
(
1u
)});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -956,8 +949,7 @@ TEST_CASE("constructors")
...
@@ -956,8 +949,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
json
(
42.23
)};
json
j
(
json
::
initializer_list_t
{
json
(
42.23
)});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -973,8 +965,7 @@ TEST_CASE("constructors")
...
@@ -973,8 +965,7 @@ TEST_CASE("constructors")
{
{
SECTION
(
"explicit"
)
SECTION
(
"explicit"
)
{
{
std
::
initializer_list
<
json
>
l
=
{
1
,
1u
,
42.23
,
true
,
nullptr
,
json
::
object_t
(),
json
::
array_t
()};
json
j
(
json
::
initializer_list_t
{
1
,
1u
,
42.23
,
true
,
nullptr
,
json
::
object_t
(),
json
::
array_t
()});
json
j
(
l
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
...
@@ -1034,6 +1025,125 @@ TEST_CASE("constructors")
...
@@ -1034,6 +1025,125 @@ TEST_CASE("constructors")
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
}
}
}
}
SECTION
(
"move from initializer_list"
)
{
SECTION
(
"string"
)
{
// This should break through any short string optimization in std::string
std
::
string
source
(
1024
,
'!'
);
const
char
*
source_addr
=
source
.
data
();
SECTION
(
"constructor with implicit types (array)"
)
{
json
j
=
{
std
::
move
(
source
)};
CHECK
(
j
[
0
].
get_ref
<
std
::
string
const
&>
().
data
()
==
source_addr
);
}
SECTION
(
"constructor with implicit types (object)"
)
{
json
j
=
{{
"key"
,
std
::
move
(
source
)}};
CHECK
(
j
[
"key"
].
get_ref
<
std
::
string
const
&>
().
data
()
==
source_addr
);
}
SECTION
(
"constructor with implicit types (object key)"
)
{
json
j
=
{{
std
::
move
(
source
),
42
}};
CHECK
(
j
.
get_ref
<
json
::
object_t
&>
().
begin
()
->
first
.
data
()
==
source_addr
);
}
}
SECTION
(
"array"
)
{
json
::
array_t
source
=
{
1
,
2
,
3
};
const
json
*
source_addr
=
source
.
data
();
SECTION
(
"constructor with implicit types (array)"
)
{
json
j
{
std
::
move
(
source
)};
CHECK
(
j
[
0
].
get_ref
<
json
::
array_t
const
&>
().
data
()
==
source_addr
);
}
SECTION
(
"constructor with implicit types (object)"
)
{
json
j
{{
"key"
,
std
::
move
(
source
)}};
CHECK
(
j
[
"key"
].
get_ref
<
json
::
array_t
const
&>
().
data
()
==
source_addr
);
}
SECTION
(
"assignment with implicit types (array)"
)
{
json
j
=
{
std
::
move
(
source
)};
CHECK
(
j
[
0
].
get_ref
<
json
::
array_t
const
&>
().
data
()
==
source_addr
);
}
SECTION
(
"assignment with implicit types (object)"
)
{
json
j
=
{{
"key"
,
std
::
move
(
source
)}};
CHECK
(
j
[
"key"
].
get_ref
<
json
::
array_t
const
&>
().
data
()
==
source_addr
);
}
}
SECTION
(
"object"
)
{
json
::
object_t
source
=
{{
"hello"
,
"world"
}};
const
json
*
source_addr
=
&
source
.
at
(
"hello"
);
SECTION
(
"constructor with implicit types (array)"
)
{
json
j
{
std
::
move
(
source
)};
CHECK
(
&
(
j
[
0
].
get_ref
<
json
::
object_t
const
&>
().
at
(
"hello"
))
==
source_addr
);
}
SECTION
(
"constructor with implicit types (object)"
)
{
json
j
{{
"key"
,
std
::
move
(
source
)}};
CHECK
(
&
(
j
[
"key"
].
get_ref
<
json
::
object_t
const
&>
().
at
(
"hello"
))
==
source_addr
);
}
SECTION
(
"assignment with implicit types (array)"
)
{
json
j
=
{
std
::
move
(
source
)};
CHECK
(
&
(
j
[
0
].
get_ref
<
json
::
object_t
const
&>
().
at
(
"hello"
))
==
source_addr
);
}
SECTION
(
"assignment with implicit types (object)"
)
{
json
j
=
{{
"key"
,
std
::
move
(
source
)}};
CHECK
(
&
(
j
[
"key"
].
get_ref
<
json
::
object_t
const
&>
().
at
(
"hello"
))
==
source_addr
);
}
}
SECTION
(
"json"
)
{
json
source
{
1
,
2
,
3
};
const
json
*
source_addr
=
&
source
[
0
];
SECTION
(
"constructor with implicit types (array)"
)
{
json
j
{
std
::
move
(
source
),
{}};
CHECK
(
&
j
[
0
][
0
]
==
source_addr
);
}
SECTION
(
"constructor with implicit types (object)"
)
{
json
j
{{
"key"
,
std
::
move
(
source
)}};
CHECK
(
&
j
[
"key"
][
0
]
==
source_addr
);
}
SECTION
(
"assignment with implicit types (array)"
)
{
json
j
=
{
std
::
move
(
source
),
{}};
CHECK
(
&
j
[
0
][
0
]
==
source_addr
);
}
SECTION
(
"assignment with implicit types (object)"
)
{
json
j
=
{{
"key"
,
std
::
move
(
source
)}};
CHECK
(
&
j
[
"key"
][
0
]
==
source_addr
);
}
}
}
}
}
SECTION
(
"create an array of n copies of a given value"
)
SECTION
(
"create an array of n copies of a given value"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment