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
c983b671
Unverified
Commit
c983b671
authored
Mar 11, 2019
by
Niels Lohmann
Committed by
GitHub
Mar 11, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1469 from garethsb-sony/json_pointer-append
Add operator/= and operator/ to construct a JSON pointer by appending two JSON pointers
parents
c11bead2
d183bd04
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
234 additions
and
22 deletions
+234
-22
json_pointer.hpp
include/nlohmann/detail/json_pointer.hpp
+75
-9
json.hpp
include/nlohmann/json.hpp
+1
-1
json.hpp
single_include/nlohmann/json.hpp
+76
-10
unit-json_pointer.cpp
test/src/unit-json_pointer.cpp
+82
-2
No files found.
include/nlohmann/detail/json_pointer.hpp
View file @
c983b671
...
@@ -77,6 +77,67 @@ class json_pointer
...
@@ -77,6 +77,67 @@ class json_pointer
}
}
/*!
/*!
@brief append another JSON pointer at the end of this JSON pointer
*/
json_pointer
&
operator
/=
(
const
json_pointer
&
ptr
)
{
reference_tokens
.
insert
(
reference_tokens
.
end
(),
ptr
.
reference_tokens
.
begin
(),
ptr
.
reference_tokens
.
end
());
return
*
this
;
}
/// @copydoc push_back(std::string&&)
json_pointer
&
operator
/=
(
std
::
string
token
)
{
push_back
(
std
::
move
(
token
));
return
*
this
;
}
/// @copydoc operator/=(std::string)
json_pointer
&
operator
/=
(
std
::
size_t
array_index
)
{
return
*
this
/=
std
::
to_string
(
array_index
);
}
/*!
@brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
*/
friend
json_pointer
operator
/
(
const
json_pointer
&
left_ptr
,
const
json_pointer
&
right_ptr
)
{
return
json_pointer
(
left_ptr
)
/=
right_ptr
;
}
/*!
@brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
*/
friend
json_pointer
operator
/
(
const
json_pointer
&
ptr
,
std
::
string
token
)
{
return
json_pointer
(
ptr
)
/=
std
::
move
(
token
);
}
/*!
@brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
*/
friend
json_pointer
operator
/
(
const
json_pointer
&
lhs
,
std
::
size_t
array_index
)
{
return
json_pointer
(
lhs
)
/=
array_index
;
}
/*!
@brief create a new JSON pointer that is the parent of this JSON pointer
*/
json_pointer
parent_pointer
()
const
{
if
(
empty
())
{
return
*
this
;
}
json_pointer
res
=
*
this
;
res
.
pop_back
();
return
res
;
}
/*!
@param[in] s reference token to be converted into an array index
@param[in] s reference token to be converted into an array index
@return integer representation of @a s
@return integer representation of @a s
...
@@ -98,12 +159,12 @@ class json_pointer
...
@@ -98,12 +159,12 @@ class json_pointer
}
}
/*!
/*!
@brief remove and return last reference
pointer
@brief remove and return last reference
token
@throw out_of_range.405 if JSON pointer has no parent
@throw out_of_range.405 if JSON pointer has no parent
*/
*/
std
::
string
pop_back
()
std
::
string
pop_back
()
{
{
if
(
JSON_UNLIKELY
(
is_root
()))
if
(
JSON_UNLIKELY
(
empty
()))
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
}
}
...
@@ -114,24 +175,29 @@ class json_pointer
...
@@ -114,24 +175,29 @@ class json_pointer
}
}
/*!
/*!
@brief remove and return last reference pointer
@brief append an unescaped token at the end of the reference pointer
@throw out_of_range.405 if JSON pointer has no parent
*/
*/
void
push_back
(
const
std
::
string
&
tok
)
void
push_back
(
const
std
::
string
&
tok
en
)
{
{
reference_tokens
.
push_back
(
tok
);
reference_tokens
.
push_back
(
token
);
}
/// @copydoc push_back(const std::string&)
void
push_back
(
std
::
string
&&
token
)
{
reference_tokens
.
push_back
(
std
::
move
(
token
));
}
}
private
:
/// return whether pointer points to the root document
/// return whether pointer points to the root document
bool
is_root
()
const
noexcept
bool
empty
()
const
noexcept
{
{
return
reference_tokens
.
empty
();
return
reference_tokens
.
empty
();
}
}
private
:
json_pointer
top
()
const
json_pointer
top
()
const
{
{
if
(
JSON_UNLIKELY
(
is_root
()))
if
(
JSON_UNLIKELY
(
empty
()))
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
}
}
...
...
include/nlohmann/json.hpp
View file @
c983b671
...
@@ -7493,7 +7493,7 @@ class basic_json
...
@@ -7493,7 +7493,7 @@ class basic_json
const
auto
operation_add
=
[
&
result
](
json_pointer
&
ptr
,
basic_json
val
)
const
auto
operation_add
=
[
&
result
](
json_pointer
&
ptr
,
basic_json
val
)
{
{
// adding to the root of the target document means replacing it
// adding to the root of the target document means replacing it
if
(
ptr
.
is_root
())
if
(
ptr
.
empty
())
{
{
result
=
val
;
result
=
val
;
}
}
...
...
single_include/nlohmann/json.hpp
View file @
c983b671
...
@@ -11897,6 +11897,67 @@ class json_pointer
...
@@ -11897,6 +11897,67 @@ class json_pointer
}
}
/*!
/*!
@brief append another JSON pointer at the end of this JSON pointer
*/
json_pointer
&
operator
/=
(
const
json_pointer
&
ptr
)
{
reference_tokens
.
insert
(
reference_tokens
.
end
(),
ptr
.
reference_tokens
.
begin
(),
ptr
.
reference_tokens
.
end
());
return
*
this
;
}
/// @copydoc push_back(std::string&&)
json_pointer
&
operator
/=
(
std
::
string
token
)
{
push_back
(
std
::
move
(
token
));
return
*
this
;
}
/// @copydoc operator/=(std::string)
json_pointer
&
operator
/=
(
std
::
size_t
array_index
)
{
return
*
this
/=
std
::
to_string
(
array_index
);
}
/*!
@brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
*/
friend
json_pointer
operator
/
(
const
json_pointer
&
left_ptr
,
const
json_pointer
&
right_ptr
)
{
return
json_pointer
(
left_ptr
)
/=
right_ptr
;
}
/*!
@brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
*/
friend
json_pointer
operator
/
(
const
json_pointer
&
ptr
,
std
::
string
token
)
{
return
json_pointer
(
ptr
)
/=
std
::
move
(
token
);
}
/*!
@brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
*/
friend
json_pointer
operator
/
(
const
json_pointer
&
lhs
,
std
::
size_t
array_index
)
{
return
json_pointer
(
lhs
)
/=
array_index
;
}
/*!
@brief create a new JSON pointer that is the parent of this JSON pointer
*/
json_pointer
parent_pointer
()
const
{
if
(
empty
())
{
return
*
this
;
}
json_pointer
res
=
*
this
;
res
.
pop_back
();
return
res
;
}
/*!
@param[in] s reference token to be converted into an array index
@param[in] s reference token to be converted into an array index
@return integer representation of @a s
@return integer representation of @a s
...
@@ -11918,12 +11979,12 @@ class json_pointer
...
@@ -11918,12 +11979,12 @@ class json_pointer
}
}
/*!
/*!
@brief remove and return last reference
pointer
@brief remove and return last reference
token
@throw out_of_range.405 if JSON pointer has no parent
@throw out_of_range.405 if JSON pointer has no parent
*/
*/
std
::
string
pop_back
()
std
::
string
pop_back
()
{
{
if
(
JSON_UNLIKELY
(
is_root
()))
if
(
JSON_UNLIKELY
(
empty
()))
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
}
}
...
@@ -11934,24 +11995,29 @@ class json_pointer
...
@@ -11934,24 +11995,29 @@ class json_pointer
}
}
/*!
/*!
@brief remove and return last reference pointer
@brief append an unescaped token at the end of the reference pointer
@throw out_of_range.405 if JSON pointer has no parent
*/
*/
void
push_back
(
const
std
::
string
&
tok
)
void
push_back
(
const
std
::
string
&
tok
en
)
{
{
reference_tokens
.
push_back
(
tok
);
reference_tokens
.
push_back
(
token
);
}
/// @copydoc push_back(const std::string&)
void
push_back
(
std
::
string
&&
token
)
{
reference_tokens
.
push_back
(
std
::
move
(
token
));
}
}
private
:
/// return whether pointer points to the root document
/// return whether pointer points to the root document
bool
is_root
()
const
noexcept
bool
empty
()
const
noexcept
{
{
return
reference_tokens
.
empty
();
return
reference_tokens
.
empty
();
}
}
private
:
json_pointer
top
()
const
json_pointer
top
()
const
{
{
if
(
JSON_UNLIKELY
(
is_root
()))
if
(
JSON_UNLIKELY
(
empty
()))
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
}
}
...
@@ -20002,7 +20068,7 @@ class basic_json
...
@@ -20002,7 +20068,7 @@ class basic_json
const
auto
operation_add
=
[
&
result
](
json_pointer
&
ptr
,
basic_json
val
)
const
auto
operation_add
=
[
&
result
](
json_pointer
&
ptr
,
basic_json
val
)
{
{
// adding to the root of the target document means replacing it
// adding to the root of the target document means replacing it
if
(
ptr
.
is_root
())
if
(
ptr
.
empty
())
{
{
result
=
val
;
result
=
val
;
}
}
...
...
test/src/unit-json_pointer.cpp
View file @
c983b671
...
@@ -438,6 +438,7 @@ TEST_CASE("JSON pointers")
...
@@ -438,6 +438,7 @@ TEST_CASE("JSON pointers")
})
})
{
{
CHECK
(
json
::
json_pointer
(
ptr
).
to_string
()
==
ptr
);
CHECK
(
json
::
json_pointer
(
ptr
).
to_string
()
==
ptr
);
CHECK
(
std
::
string
(
json
::
json_pointer
(
ptr
))
==
ptr
);
}
}
}
}
...
@@ -460,7 +461,7 @@ TEST_CASE("JSON pointers")
...
@@ -460,7 +461,7 @@ TEST_CASE("JSON pointers")
}
}
}
}
SECTION
(
"
push and pop
"
)
SECTION
(
"
empty, push, pop and parent
"
)
{
{
const
json
j
=
const
json
j
=
{
{
...
@@ -489,22 +490,28 @@ TEST_CASE("JSON pointers")
...
@@ -489,22 +490,28 @@ TEST_CASE("JSON pointers")
// empty json_pointer returns the root JSON-object
// empty json_pointer returns the root JSON-object
auto
ptr
=
""
_json_pointer
;
auto
ptr
=
""
_json_pointer
;
CHECK
(
ptr
.
empty
());
CHECK
(
j
[
ptr
]
==
j
);
CHECK
(
j
[
ptr
]
==
j
);
// simple field access
// simple field access
ptr
.
push_back
(
"pi"
);
ptr
.
push_back
(
"pi"
);
CHECK
(
!
ptr
.
empty
());
CHECK
(
j
[
ptr
]
==
j
[
"pi"
]);
CHECK
(
j
[
ptr
]
==
j
[
"pi"
]);
ptr
.
pop_back
();
ptr
.
pop_back
();
CHECK
(
ptr
.
empty
());
CHECK
(
j
[
ptr
]
==
j
);
CHECK
(
j
[
ptr
]
==
j
);
// object and children access
// object and children access
ptr
.
push_back
(
"answer"
);
const
std
::
string
answer
(
"answer"
);
ptr
.
push_back
(
answer
);
ptr
.
push_back
(
"everything"
);
ptr
.
push_back
(
"everything"
);
CHECK
(
!
ptr
.
empty
());
CHECK
(
j
[
ptr
]
==
j
[
"answer"
][
"everything"
]);
CHECK
(
j
[
ptr
]
==
j
[
"answer"
][
"everything"
]);
ptr
.
pop_back
();
ptr
.
pop_back
();
ptr
.
pop_back
();
ptr
.
pop_back
();
CHECK
(
ptr
.
empty
());
CHECK
(
j
[
ptr
]
==
j
);
CHECK
(
j
[
ptr
]
==
j
);
// push key which has to be encoded
// push key which has to be encoded
...
@@ -512,5 +519,78 @@ TEST_CASE("JSON pointers")
...
@@ -512,5 +519,78 @@ TEST_CASE("JSON pointers")
ptr
.
push_back
(
"/"
);
ptr
.
push_back
(
"/"
);
CHECK
(
j
[
ptr
]
==
j
[
"object"
][
"/"
]);
CHECK
(
j
[
ptr
]
==
j
[
"object"
][
"/"
]);
CHECK
(
ptr
.
to_string
()
==
"/object/~1"
);
CHECK
(
ptr
.
to_string
()
==
"/object/~1"
);
CHECK
(
j
[
ptr
.
parent_pointer
()]
==
j
[
"object"
]);
ptr
=
ptr
.
parent_pointer
().
parent_pointer
();
CHECK
(
ptr
.
empty
());
CHECK
(
j
[
ptr
]
==
j
);
// parent-pointer of the empty json_pointer is empty
ptr
=
ptr
.
parent_pointer
();
CHECK
(
ptr
.
empty
());
CHECK
(
j
[
ptr
]
==
j
);
CHECK_THROWS_WITH
(
ptr
.
pop_back
(),
"[json.exception.out_of_range.405] JSON pointer has no parent"
);
}
SECTION
(
"operators"
)
{
const
json
j
=
{
{
""
,
"Hello"
},
{
"pi"
,
3.141
},
{
"happy"
,
true
},
{
"name"
,
"Niels"
},
{
"nothing"
,
nullptr
},
{
"answer"
,
{
{
"everything"
,
42
}
}
},
{
"list"
,
{
1
,
0
,
2
}},
{
"object"
,
{
{
"currency"
,
"USD"
},
{
"value"
,
42.99
},
{
""
,
"empty string"
},
{
"/"
,
"slash"
},
{
"~"
,
"tilde"
},
{
"~1"
,
"tilde1"
}
}
}
};
// empty json_pointer returns the root JSON-object
auto
ptr
=
""
_json_pointer
;
CHECK
(
j
[
ptr
]
==
j
);
// simple field access
ptr
=
ptr
/
"pi"
;
CHECK
(
j
[
ptr
]
==
j
[
"pi"
]);
ptr
.
pop_back
();
CHECK
(
j
[
ptr
]
==
j
);
// object and children access
const
std
::
string
answer
(
"answer"
);
ptr
/=
answer
;
ptr
=
ptr
/
"everything"
;
CHECK
(
j
[
ptr
]
==
j
[
"answer"
][
"everything"
]);
ptr
.
pop_back
();
ptr
.
pop_back
();
CHECK
(
j
[
ptr
]
==
j
);
CHECK
(
ptr
/
""
_json_pointer
==
ptr
);
CHECK
(
j
[
"/answer"
_json_pointer
/
"/everything"
_json_pointer
]
==
j
[
"answer"
][
"everything"
]);
// list children access
CHECK
(
j
[
"/list"
_json_pointer
/
1
]
==
j
[
"list"
][
1
]);
// push key which has to be encoded
ptr
/=
"object"
;
ptr
=
ptr
/
"/"
;
CHECK
(
j
[
ptr
]
==
j
[
"object"
][
"/"
]);
CHECK
(
ptr
.
to_string
()
==
"/object/~1"
);
}
}
}
}
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