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
9ecf83f6
Commit
9ecf83f6
authored
May 08, 2016
by
Niels
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
working on #235
parent
fadf2866
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
211 additions
and
2 deletions
+211
-2
push_back__initializer_list.cpp
doc/examples/push_back__initializer_list.cpp
+26
-0
push_back__initializer_list.link
doc/examples/push_back__initializer_list.link
+2
-0
push_back__initializer_list.output
doc/examples/push_back__initializer_list.output
+4
-0
json.hpp
src/json.hpp
+49
-1
json.hpp.re2c
src/json.hpp.re2c
+49
-1
unit.cpp
test/unit.cpp
+81
-0
No files found.
doc/examples/push_back__initializer_list.cpp
0 → 100644
View file @
9ecf83f6
#include <json.hpp>
using
json
=
nlohmann
::
json
;
int
main
()
{
// create JSON values
json
object
=
{{
"one"
,
1
},
{
"two"
,
2
}};
json
null
;
// print values
std
::
cout
<<
object
<<
'\n'
;
std
::
cout
<<
null
<<
'\n'
;
// add values:
object
.
push_back
({
"three"
,
3
});
// object is extended
object
+=
{
"four"
,
4
};
// object is extended
null
.
push_back
({
"five"
,
5
});
// null is converted to array
// print values
std
::
cout
<<
object
<<
'\n'
;
std
::
cout
<<
null
<<
'\n'
;
// would throw:
//object.push_back({1, 2, 3});
}
doc/examples/push_back__initializer_list.link
0 → 100644
View file @
9ecf83f6
<a target="_blank" href="http://melpon.org/wandbox/permlink/wZF4dRHjfCyjb3rx"><b>online</b></a>
\ No newline at end of file
doc/examples/push_back__initializer_list.output
0 → 100644
View file @
9ecf83f6
{"one":1,"two":2}
null
{"four":4,"one":1,"three":3,"two":2}
[["five",5]]
src/json.hpp
View file @
9ecf83f6
...
...
@@ -4878,7 +4878,55 @@ class basic_json
reference
operator
+=
(
const
typename
object_t
::
value_type
&
val
)
{
push_back
(
val
);
return
operator
[](
val
.
first
);
return
*
this
;
}
/*!
@brief add an object to an object
This function allows to use `push_back` with an initializer list. In case
1. the current value is an object,
2. the initializer list @a init contains only two elements, and
3. the first element of @a init is a string,
@a init is converted into an object element and added using
@ref push_back(const typename object_t::value_type&). Otherwise, @a init
is converted to a JSON value and added using @ref push_back(basic_json&&).
@param init an initializer list
@complexity Linear in the size of the initializer list @a init.
@note This function is required to resolve an ambiguous overload error,
because pairs like `{"key", "value"}` can be both interpreted as
`object_t::value_type` or `std::initializer_list<basic_json>`, see
https://github.com/nlohmann/json/issues/235 for more information.
@liveexample{The example shows how initializer lists are treated as
objects when possible.,push_back__initializer_list}
*/
void
push_back
(
std
::
initializer_list
<
basic_json
>
init
)
{
if
(
is_object
()
and
init
.
size
()
==
2
and
init
.
begin
()
->
is_string
())
{
const
string_t
key
=
*
init
.
begin
();
push_back
(
typename
object_t
::
value_type
(
key
,
*
(
init
.
begin
()
+
1
)));
}
else
{
push_back
(
basic_json
(
init
));
}
}
/*!
@brief add an object to an object
@copydoc push_back(std::initializer_list<basic_json>)
*/
reference
operator
+=
(
std
::
initializer_list
<
basic_json
>
init
)
{
push_back
(
init
);
return
*
this
;
}
/*!
...
...
src/json.hpp.re2c
View file @
9ecf83f6
...
...
@@ -4878,7 +4878,55 @@ class basic_json
reference operator+=(const typename object_t::value_type& val)
{
push_back(val);
return operator[](val.first);
return *this;
}
/*!
@brief add an object to an object
This function allows to use `push_back` with an initializer list. In case
1. the current value is an object,
2. the initializer list @a init contains only two elements, and
3. the first element of @a init is a string,
@a init is converted into an object element and added using
@ref push_back(const typename object_t::value_type&). Otherwise, @a init
is converted to a JSON value and added using @ref push_back(basic_json&&).
@param init an initializer list
@complexity Linear in the size of the initializer list @a init.
@note This function is required to resolve an ambiguous overload error,
because pairs like `{"key", "value"}` can be both interpreted as
`object_t::value_type` or `std::initializer_list<basic_json>`, see
https://github.com/nlohmann/json/issues/235 for more information.
@liveexample{The example shows how initializer lists are treated as
objects when possible.,push_back__initializer_list}
*/
void push_back(std::initializer_list<basic_json> init)
{
if (is_object() and init.size() == 2 and init.begin()->is_string())
{
const string_t key = *init.begin();
push_back(typename object_t::value_type(key, *(init.begin() + 1)));
}
else
{
push_back(basic_json(init));
}
}
/*!
@brief add an object to an object
@copydoc push_back(std::initializer_list<basic_json>)
*/
reference operator+=(std::initializer_list<basic_json> init)
{
push_back(init);
return *this;
}
/*!
...
...
test/unit.cpp
View file @
9ecf83f6
...
...
@@ -7920,6 +7920,42 @@ TEST_CASE("modifiers")
"cannot use push_back() with number"
);
}
}
SECTION
(
"with initializer_list"
)
{
SECTION
(
"null"
)
{
json
j
;
j
.
push_back
({
"foo"
,
"bar"
});
CHECK
(
j
==
json
::
array
({{
"foo"
,
"bar"
}}));
json
k
;
k
.
push_back
({
1
,
2
,
3
});
CHECK
(
k
==
json
::
array
({{
1
,
2
,
3
}}));
}
SECTION
(
"array"
)
{
json
j
=
{
1
,
2
,
3
};
j
.
push_back
({
"foo"
,
"bar"
});
CHECK
(
j
==
json
({
1
,
2
,
3
,
{
"foo"
,
"bar"
}}));
json
k
=
{
1
,
2
,
3
};
k
.
push_back
({
1
,
2
,
3
});
CHECK
(
k
==
json
({
1
,
2
,
3
,
{
1
,
2
,
3
}}));
}
SECTION
(
"object"
)
{
json
j
=
{{
"key1"
,
1
}};
j
.
push_back
({
"key2"
,
"bar"
});
CHECK
(
j
==
json
({{
"key1"
,
1
},
{
"key2"
,
"bar"
}}));
json
k
=
{{
"key1"
,
1
}};
CHECK_THROWS_AS
(
k
.
push_back
({
1
,
2
,
3
,
4
}),
std
::
domain_error
);
CHECK_THROWS_WITH
(
k
.
push_back
({
1
,
2
,
3
,
4
}),
"cannot use push_back() with object"
);
}
}
}
SECTION
(
"operator+="
)
...
...
@@ -8016,6 +8052,42 @@ TEST_CASE("modifiers")
"cannot use push_back() with number"
);
}
}
SECTION
(
"with initializer_list"
)
{
SECTION
(
"null"
)
{
json
j
;
j
+=
{
"foo"
,
"bar"
};
CHECK
(
j
==
json
::
array
({{
"foo"
,
"bar"
}}));
json
k
;
k
+=
{
1
,
2
,
3
};
CHECK
(
k
==
json
::
array
({{
1
,
2
,
3
}}));
}
SECTION
(
"array"
)
{
json
j
=
{
1
,
2
,
3
};
j
+=
{
"foo"
,
"bar"
};
CHECK
(
j
==
json
({
1
,
2
,
3
,
{
"foo"
,
"bar"
}}));
json
k
=
{
1
,
2
,
3
};
k
+=
{
1
,
2
,
3
};
CHECK
(
k
==
json
({
1
,
2
,
3
,
{
1
,
2
,
3
}}));
}
SECTION
(
"object"
)
{
json
j
=
{{
"key1"
,
1
}};
j
+=
{
"key2"
,
"bar"
};
CHECK
(
j
==
json
({{
"key1"
,
1
},
{
"key2"
,
"bar"
}}));
json
k
=
{{
"key1"
,
1
}};
CHECK_THROWS_AS
((
k
+=
{
1
,
2
,
3
,
4
}),
std
::
domain_error
);
CHECK_THROWS_WITH
((
k
+=
{
1
,
2
,
3
,
4
}),
"cannot use push_back() with object"
);
}
}
}
SECTION
(
"insert"
)
...
...
@@ -13992,6 +14064,15 @@ TEST_CASE("regression tests")
CHECK
(
dest
==
expected
);
}
SECTION
(
"issue ##235 - ambiguous overload for 'push_back' and 'operator+='"
)
{
json
data
=
{{
"key"
,
"value"
}};
data
.
push_back
({
"key2"
,
"value2"
});
data
+=
{
"key3"
,
"value3"
};
CHECK
(
data
==
json
({{
"key"
,
"value"
},
{
"key2"
,
"value2"
},
{
"key3"
,
"value3"
}}));
}
}
// special test case to check if memory is leaked if constructor throws
...
...
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