diff --git a/docs/mkdocs/docs/api/json_pointer/front.md b/docs/mkdocs/docs/api/json_pointer/front.md
new file mode 100644
index 000000000..126f5ed90
--- /dev/null
+++ b/docs/mkdocs/docs/api/json_pointer/front.md
@@ -0,0 +1,37 @@
+# nlohmann::json_pointer::front
+
+```cpp
+const string_t& front() const;
+```
+
+Return the first reference token.
+
+## Return value
+
+First reference token.
+
+## Exceptions
+
+Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if the JSON pointer has no parent.
+
+## Complexity
+
+Constant.
+
+## Examples
+
+??? example
+
+ The example shows the usage of `front`.
+
+ ```cpp
+ --8<-- "examples/json_pointer__front.cpp"
+ ```
+
+ Output:
+
+ ```json
+ --8<-- "examples/json_pointer__front.output"
+ ```
+
+## Version history
diff --git a/docs/mkdocs/docs/api/json_pointer/index.md b/docs/mkdocs/docs/api/json_pointer/index.md
index 8b70e2de7..b1f895375 100644
--- a/docs/mkdocs/docs/api/json_pointer/index.md
+++ b/docs/mkdocs/docs/api/json_pointer/index.md
@@ -37,6 +37,9 @@ are the base for JSON patches.
- [**pop_back**](pop_back.md) - remove the last reference token
- [**back**](back.md) - return last reference token
- [**push_back**](push_back.md) - append an unescaped token at the end of the pointer
+- [**pop_front**](pop_front.md) - remove the first reference token
+- [**front**](front.md) - return first reference token
+- [**push_front**](push_front.md) - append an unescaped token at the start of the pointer
- [**empty**](empty.md) - return whether the pointer points to the root document
## Literals
diff --git a/docs/mkdocs/docs/api/json_pointer/pop_front.md b/docs/mkdocs/docs/api/json_pointer/pop_front.md
new file mode 100644
index 000000000..a0bfc546a
--- /dev/null
+++ b/docs/mkdocs/docs/api/json_pointer/pop_front.md
@@ -0,0 +1,33 @@
+# nlohmann::json_pointer::pop_front
+
+```cpp
+void pop_front();
+```
+
+Remove the first reference token.
+
+## Exceptions
+
+Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if the JSON pointer has no parent.
+
+## Complexity
+
+Linear in the number of reference tokens in the `json_pointer`.
+
+## Examples
+
+??? example
+
+ The example shows the usage of `pop_front`.
+
+ ```cpp
+ --8<-- "examples/json_pointer__pop_front.cpp"
+ ```
+
+ Output:
+
+ ```json
+ --8<-- "examples/json_pointer__pop_front.output"
+ ```
+
+## Version history
diff --git a/docs/mkdocs/docs/api/json_pointer/push_front.md b/docs/mkdocs/docs/api/json_pointer/push_front.md
new file mode 100644
index 000000000..8d72f2363
--- /dev/null
+++ b/docs/mkdocs/docs/api/json_pointer/push_front.md
@@ -0,0 +1,36 @@
+# nlohmann::json_pointer::push_front
+
+```cpp
+void push_front(const string_t& token);
+
+void push_front(string_t&& token);
+```
+
+Append an unescaped token at the start of the reference pointer.
+
+## Parameters
+
+`token` (in)
+: token to add
+
+## Complexity
+
+Linear in the number of reference tokens in the `json_pointer`.
+
+## Examples
+
+??? example
+
+ The example shows the result of `push_front` for different JSON Pointers.
+
+ ```cpp
+ --8<-- "examples/json_pointer__push_front.cpp"
+ ```
+
+ Output:
+
+ ```json
+ --8<-- "examples/json_pointer__push_front.output"
+ ```
+
+## Version history
diff --git a/docs/mkdocs/docs/examples/json_pointer__front.cpp b/docs/mkdocs/docs/examples/json_pointer__front.cpp
new file mode 100644
index 000000000..42c76ffec
--- /dev/null
+++ b/docs/mkdocs/docs/examples/json_pointer__front.cpp
@@ -0,0 +1,15 @@
+#include
+#include
+
+using json = nlohmann::json;
+
+int main()
+{
+ // different JSON Pointers
+ json::json_pointer ptr1("/foo");
+ json::json_pointer ptr2("/foo/0");
+
+ // call empty()
+ std::cout << "first reference token of \"" << ptr1 << "\" is \"" << ptr1.front() << "\"\n"
+ << "first reference token of \"" << ptr2 << "\" is \"" << ptr2.front() << "\"" << std::endl;
+}
diff --git a/docs/mkdocs/docs/examples/json_pointer__front.output b/docs/mkdocs/docs/examples/json_pointer__front.output
new file mode 100644
index 000000000..f7a5adc80
--- /dev/null
+++ b/docs/mkdocs/docs/examples/json_pointer__front.output
@@ -0,0 +1,2 @@
+first reference token of "/foo" is "foo"
+first reference token of "/foo/0" is "foo"
diff --git a/docs/mkdocs/docs/examples/json_pointer__pop_front.cpp b/docs/mkdocs/docs/examples/json_pointer__pop_front.cpp
new file mode 100644
index 000000000..59403668c
--- /dev/null
+++ b/docs/mkdocs/docs/examples/json_pointer__pop_front.cpp
@@ -0,0 +1,21 @@
+#include
+#include
+
+using json = nlohmann::json;
+
+int main()
+{
+ // create empty JSON Pointer
+ json::json_pointer ptr("/foo/bar/baz");
+ std::cout << "\"" << ptr << "\"\n";
+
+ // call pop_front()
+ ptr.pop_front();
+ std::cout << "\"" << ptr << "\"\n";
+
+ ptr.pop_front();
+ std::cout << "\"" << ptr << "\"\n";
+
+ ptr.pop_front();
+ std::cout << "\"" << ptr << "\"\n";
+}
diff --git a/docs/mkdocs/docs/examples/json_pointer__pop_front.output b/docs/mkdocs/docs/examples/json_pointer__pop_front.output
new file mode 100644
index 000000000..73d81b953
--- /dev/null
+++ b/docs/mkdocs/docs/examples/json_pointer__pop_front.output
@@ -0,0 +1,4 @@
+"/foo/bar/baz"
+"/bar/baz"
+"/baz"
+""
diff --git a/docs/mkdocs/docs/examples/json_pointer__push_front.cpp b/docs/mkdocs/docs/examples/json_pointer__push_front.cpp
new file mode 100644
index 000000000..7bcdccb45
--- /dev/null
+++ b/docs/mkdocs/docs/examples/json_pointer__push_front.cpp
@@ -0,0 +1,21 @@
+#include
+#include
+
+using json = nlohmann::json;
+
+int main()
+{
+ // create empty JSON Pointer
+ json::json_pointer ptr;
+ std::cout << "\"" << ptr << "\"\n";
+
+ // call push_front()
+ ptr.push_front("foo");
+ std::cout << "\"" << ptr << "\"\n";
+
+ ptr.push_front("0");
+ std::cout << "\"" << ptr << "\"\n";
+
+ ptr.push_front("bar");
+ std::cout << "\"" << ptr << "\"\n";
+}
diff --git a/docs/mkdocs/docs/examples/json_pointer__push_front.output b/docs/mkdocs/docs/examples/json_pointer__push_front.output
new file mode 100644
index 000000000..79bf84946
--- /dev/null
+++ b/docs/mkdocs/docs/examples/json_pointer__push_front.output
@@ -0,0 +1,4 @@
+""
+"/foo"
+"/0/foo"
+"/bar/0/foo"
diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml
index ea089c7ea..ef6e8b505 100644
--- a/docs/mkdocs/mkdocs.yml
+++ b/docs/mkdocs/mkdocs.yml
@@ -233,6 +233,7 @@ nav:
- '(Constructor)': api/json_pointer/json_pointer.md
- 'back': api/json_pointer/back.md
- 'empty': api/json_pointer/empty.md
+ - 'front': api/json_pointer/front.md
- 'operator string_t': api/json_pointer/operator_string_t.md
- 'operator==': api/json_pointer/operator_eq.md
- 'operator!=': api/json_pointer/operator_ne.md
@@ -240,7 +241,9 @@ nav:
- 'operator/=': api/json_pointer/operator_slasheq.md
- 'parent_pointer': api/json_pointer/parent_pointer.md
- 'pop_back': api/json_pointer/pop_back.md
+ - 'pop_front': api/json_pointer/pop_front.md
- 'push_back': api/json_pointer/push_back.md
+ - 'push_front': api/json_pointer/push_front.md
- 'string_t': api/json_pointer/string_t.md
- 'to_string': api/json_pointer/to_string.md
- json_sax:
diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp
index ac50a8703..0767484f8 100644
--- a/include/nlohmann/detail/json_pointer.hpp
+++ b/include/nlohmann/detail/json_pointer.hpp
@@ -154,6 +154,44 @@ class json_pointer
return res;
}
+ /// @brief remove first reference token
+ /// @sa https://json.nlohmann.me/api/json_pointer/pop_front/
+ void pop_front()
+ {
+ if (JSON_HEDLEY_UNLIKELY(empty()))
+ {
+ JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
+ }
+
+ reference_tokens.erase(reference_tokens.begin());
+ }
+
+ /// @brief return first reference token
+ /// @sa https://json.nlohmann.me/api/json_pointer/front/
+ const string_t& front() const
+ {
+ if (JSON_HEDLEY_UNLIKELY(empty()))
+ {
+ JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
+ }
+
+ return reference_tokens.front();
+ }
+
+ /// @brief append an unescaped token at the start of the reference pointer
+ /// @sa https://json.nlohmann.me/api/json_pointer/push_front/
+ void push_front(const string_t& token)
+ {
+ reference_tokens.insert(reference_tokens.begin(), token);
+ }
+
+ /// @brief append an unescaped token at the start of the reference pointer
+ /// @sa https://json.nlohmann.me/api/json_pointer/push_front/
+ void push_front(string_t&& token)
+ {
+ reference_tokens.insert(reference_tokens.begin(), std::move(token));
+ }
+
/// @brief remove last reference token
/// @sa https://json.nlohmann.me/api/json_pointer/pop_back/
void pop_back()
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index c1363f90f..a8da603c7 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -14872,6 +14872,44 @@ class json_pointer
return res;
}
+ /// @brief remove first reference token
+ /// @sa https://json.nlohmann.me/api/json_pointer/pop_front/
+ void pop_front()
+ {
+ if (JSON_HEDLEY_UNLIKELY(empty()))
+ {
+ JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
+ }
+
+ reference_tokens.erase(reference_tokens.begin());
+ }
+
+ /// @brief return first reference token
+ /// @sa https://json.nlohmann.me/api/json_pointer/front/
+ const string_t& front() const
+ {
+ if (JSON_HEDLEY_UNLIKELY(empty()))
+ {
+ JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
+ }
+
+ return reference_tokens.front();
+ }
+
+ /// @brief append an unescaped token at the start of the reference pointer
+ /// @sa https://json.nlohmann.me/api/json_pointer/push_front/
+ void push_front(const string_t& token)
+ {
+ reference_tokens.insert(reference_tokens.begin(), token);
+ }
+
+ /// @brief append an unescaped token at the start of the reference pointer
+ /// @sa https://json.nlohmann.me/api/json_pointer/push_front/
+ void push_front(string_t&& token)
+ {
+ reference_tokens.insert(reference_tokens.begin(), std::move(token));
+ }
+
/// @brief remove last reference token
/// @sa https://json.nlohmann.me/api/json_pointer/pop_back/
void pop_back()
diff --git a/tests/src/unit-json_pointer.cpp b/tests/src/unit-json_pointer.cpp
index e1522c9f7..a8ed4a89e 100644
--- a/tests/src/unit-json_pointer.cpp
+++ b/tests/src/unit-json_pointer.cpp
@@ -564,6 +564,14 @@ TEST_CASE("JSON pointers")
CHECK(!ptr.empty());
CHECK(j[ptr] == j["answer"]["everything"]);
+ ptr.pop_front();
+ CHECK(ptr.front() == "everything");
+ ptr.pop_front();
+ CHECK(ptr.empty());
+ ptr.push_front("everything");
+ ptr.push_front(answer);
+ CHECK(j[ptr] == j["answer"]["everything"]);
+
// check access via const pointer
const auto cptr = ptr;
CHECK(cptr.back() == "everything");
@@ -588,8 +596,17 @@ TEST_CASE("JSON pointers")
CHECK(ptr.empty());
CHECK(j[ptr] == j);
- CHECK_THROWS_WITH(ptr.pop_back(),
- "[json.exception.out_of_range.405] JSON pointer has no parent");
+ CHECK_THROWS_WITH_AS(ptr.pop_back(),
+ "[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
+
+ CHECK_THROWS_WITH_AS(ptr.back(),
+ "[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
+
+ CHECK_THROWS_WITH_AS(ptr.pop_front(),
+ "[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
+
+ CHECK_THROWS_WITH_AS(ptr.front(),
+ "[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
}
SECTION("operators")