diff --git a/doc/examples/contains.cpp b/doc/examples/contains.cpp
new file mode 100644
index 00000000..df8201c3
--- /dev/null
+++ b/doc/examples/contains.cpp
@@ -0,0 +1,17 @@
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create some JSON values
+    json j_object = R"( {"key": "value"} )"_json;
+    json j_array = R"( [1, 2, 3] )"_json;
+
+    // call contains
+    std::cout << std::boolalpha <<
+              "j_object contains 'key': " << j_object.contains("key") << '\n' <<
+              "j_object contains 'another': " << j_object.contains("another") << '\n' <<
+              "j_array contains 'key': " << j_array.contains("key") << std::endl;
+}
diff --git a/doc/examples/contains.link b/doc/examples/contains.link
new file mode 100644
index 00000000..c66676a6
--- /dev/null
+++ b/doc/examples/contains.link
@@ -0,0 +1 @@
+<a target="_blank" href="https://wandbox.org/permlink/iHSlXjtjhgO9Q1Tw"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/contains.output b/doc/examples/contains.output
new file mode 100644
index 00000000..14ad177b
--- /dev/null
+++ b/doc/examples/contains.output
@@ -0,0 +1,3 @@
+j_object contains 'key': true
+j_object contains 'another': false
+j_array contains 'key': false
diff --git a/doc/examples/json_pointer__empty.cpp b/doc/examples/json_pointer__empty.cpp
new file mode 100644
index 00000000..5daaadc6
--- /dev/null
+++ b/doc/examples/json_pointer__empty.cpp
@@ -0,0 +1,20 @@
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // different JSON Pointers
+    json::json_pointer ptr0;
+    json::json_pointer ptr1("");
+    json::json_pointer ptr2("/foo");
+    json::json_pointer ptr3("/foo/0");
+
+    // call empty()
+    std::cout << std::boolalpha
+              << ptr0 << ": " << ptr0.empty() << '\n'
+              << ptr1 << ": " << ptr1.empty() << '\n'
+              << ptr2 << ": " << ptr2.empty() << '\n'
+              << ptr3 << ": " << ptr3.empty() << std::endl;
+}
diff --git a/doc/examples/json_pointer__empty.link b/doc/examples/json_pointer__empty.link
new file mode 100644
index 00000000..e3759120
--- /dev/null
+++ b/doc/examples/json_pointer__empty.link
@@ -0,0 +1 @@
+<a target="_blank" href="https://wandbox.org/permlink/pqG2Q8bmj9SvSX0i"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/json_pointer__empty.output b/doc/examples/json_pointer__empty.output
new file mode 100644
index 00000000..a7ee49c1
--- /dev/null
+++ b/doc/examples/json_pointer__empty.output
@@ -0,0 +1,4 @@
+"": true
+"": true
+"/foo": false
+"/foo/0": false
diff --git a/doc/examples/json_pointer__parent_pointer.cpp b/doc/examples/json_pointer__parent_pointer.cpp
new file mode 100644
index 00000000..6021463a
--- /dev/null
+++ b/doc/examples/json_pointer__parent_pointer.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // different JSON Pointers
+    json::json_pointer ptr1("");
+    json::json_pointer ptr2("/foo");
+    json::json_pointer ptr3("/foo/0");
+
+    // call parent_pointer()
+    std::cout << std::boolalpha
+              << "parent of " << ptr1 << " is " << ptr1.parent_pointer() << '\n'
+              << "parent of " << ptr2 << " is " << ptr2.parent_pointer() << '\n'
+              << "parent of " << ptr3 << " is " << ptr3.parent_pointer() << std::endl;
+}
diff --git a/doc/examples/json_pointer__parent_pointer.link b/doc/examples/json_pointer__parent_pointer.link
new file mode 100644
index 00000000..4aa6327e
--- /dev/null
+++ b/doc/examples/json_pointer__parent_pointer.link
@@ -0,0 +1 @@
+<a target="_blank" href="https://wandbox.org/permlink/yweqBQ8bAC6pcn68"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/json_pointer__parent_pointer.output b/doc/examples/json_pointer__parent_pointer.output
new file mode 100644
index 00000000..4cc6f3f1
--- /dev/null
+++ b/doc/examples/json_pointer__parent_pointer.output
@@ -0,0 +1,3 @@
+parent of "" is ""
+parent of "/foo" is ""
+parent of "/foo/0" is "/foo"
diff --git a/doc/examples/json_pointer__push_back.cpp b/doc/examples/json_pointer__push_back.cpp
new file mode 100644
index 00000000..d6536b3f
--- /dev/null
+++ b/doc/examples/json_pointer__push_back.cpp
@@ -0,0 +1,21 @@
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create empty JSON Pointer
+    json::json_pointer ptr;
+    std::cout << ptr << '\n';
+
+    // call push_back()
+    ptr.push_back("foo");
+    std::cout << ptr << '\n';
+
+    ptr.push_back("0");
+    std::cout << ptr << '\n';
+
+    ptr.push_back("bar");
+    std::cout << ptr << '\n';
+}
diff --git a/doc/examples/json_pointer__push_back.link b/doc/examples/json_pointer__push_back.link
new file mode 100644
index 00000000..d0cadd7c
--- /dev/null
+++ b/doc/examples/json_pointer__push_back.link
@@ -0,0 +1 @@
+<a target="_blank" href="https://wandbox.org/permlink/kLC7IUvqQ6XJCeG9"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/json_pointer__push_back.output b/doc/examples/json_pointer__push_back.output
new file mode 100644
index 00000000..92c019cd
--- /dev/null
+++ b/doc/examples/json_pointer__push_back.output
@@ -0,0 +1,4 @@
+""
+"/foo"
+"/foo/0"
+"/foo/0/bar"
diff --git a/doc/index.md b/doc/index.md
index 1266a273..ea6dc6ae 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -57,6 +57,7 @@ These pages contain the API documentation of JSON for Modern C++, a C++11 header
     - @link nlohmann::basic_json::number_integer_t signed integers @endlink
     - @link nlohmann::basic_json::number_unsigned_t unsigned integers @endlink
     - @link nlohmann::basic_json::number_float_t floating-point @endlink
+- @link nlohmann::json_pointer JSON Pointer @endlink
 
 # Container function overview
 
diff --git a/include/nlohmann/detail/exceptions.hpp b/include/nlohmann/detail/exceptions.hpp
index 5a73dedb..519a5975 100644
--- a/include/nlohmann/detail/exceptions.hpp
+++ b/include/nlohmann/detail/exceptions.hpp
@@ -223,7 +223,7 @@ name / id                     | example message | description
 ----------------------------- | --------------- | -------------------------
 json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
 json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
-json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&.
+json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp
index 0374731f..8730748c 100644
--- a/include/nlohmann/detail/input/input_adapters.hpp
+++ b/include/nlohmann/detail/input/input_adapters.hpp
@@ -61,9 +61,9 @@ class file_input_adapter : public input_adapter_protocol
 
     // make class move-only
     file_input_adapter(const file_input_adapter&) = delete;
-    file_input_adapter(file_input_adapter&&) noexcept = default;
+    file_input_adapter(file_input_adapter&&) = default;
     file_input_adapter& operator=(const file_input_adapter&) = delete;
-    file_input_adapter& operator=(file_input_adapter&&) noexcept = default;
+    file_input_adapter& operator=(file_input_adapter&&) = default;
     ~file_input_adapter() override = default;
 
     std::char_traits<char>::int_type get_character() noexcept override
diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp
index a2db2357..3d44e267 100644
--- a/include/nlohmann/detail/json_pointer.hpp
+++ b/include/nlohmann/detail/json_pointer.hpp
@@ -82,7 +82,9 @@ class json_pointer
     */
     json_pointer& operator/=(const json_pointer& ptr)
     {
-        reference_tokens.insert(reference_tokens.end(), ptr.reference_tokens.begin(), ptr.reference_tokens.end());
+        reference_tokens.insert(reference_tokens.end(),
+                                ptr.reference_tokens.begin(),
+                                ptr.reference_tokens.end());
         return *this;
     }
 
@@ -102,7 +104,8 @@ class json_pointer
     /*!
     @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)
+    friend json_pointer operator/(const json_pointer& left_ptr,
+                                  const json_pointer& right_ptr)
     {
         return json_pointer(left_ptr) /= right_ptr;
     }
@@ -124,7 +127,17 @@ class json_pointer
     }
 
     /*!
-    @brief create a new JSON pointer that is the parent of this JSON pointer
+    @brief returns the parent of this JSON pointer
+
+    @return parent of this JSON pointer; in case this JSON pointer is the root,
+            the root itself is returned
+
+    @complexity Constant.
+
+    @liveexample{The example shows the result of `parent_pointer` for different
+    JSON Pointers.,json_pointer__parent_pointer}
+
+    @since version 3.6.0
     */
     json_pointer parent_pointer() const
     {
@@ -138,27 +151,6 @@ class json_pointer
         return res;
     }
 
-    /*!
-    @param[in] s  reference token to be converted into an array index
-
-    @return integer representation of @a s
-
-    @throw out_of_range.404 if string @a s could not be converted to an integer
-    */
-    static int array_index(const std::string& s)
-    {
-        std::size_t processed_chars = 0;
-        const int res = std::stoi(s, &processed_chars);
-
-        // check if the string was completely read
-        if (JSON_UNLIKELY(processed_chars != s.size()))
-        {
-            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
-        }
-
-        return res;
-    }
-
     /*!
     @brief remove and return last reference token
     @throw out_of_range.405 if JSON pointer has no parent
@@ -177,6 +169,15 @@ class json_pointer
 
     /*!
     @brief append an unescaped token at the end of the reference pointer
+
+    @param[in] token  token to add
+
+    @complexity Amortized constant.
+
+    @liveexample{The example shows the result of `push_back` for different
+    JSON Pointers.,json_pointer__push_back}
+
+    @since version 0.6.0
     */
     void push_back(const std::string& token)
     {
@@ -189,13 +190,47 @@ class json_pointer
         reference_tokens.push_back(std::move(token));
     }
 
-    /// return whether pointer points to the root document
+    /*!
+    @brief return whether pointer points to the root document
+
+    @return true iff the JSON pointer points to the root document
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example shows the result of `empty` for different JSON
+    Pointers.,json_pointer__empty}
+
+    @since version 3.6.0
+    */
     bool empty() const noexcept
     {
         return reference_tokens.empty();
     }
 
   private:
+    /*!
+    @param[in] s  reference token to be converted into an array index
+
+    @return integer representation of @a s
+
+    @throw out_of_range.404 if string @a s could not be converted to an integer
+    */
+    static int array_index(const std::string& s)
+    {
+        std::size_t processed_chars = 0;
+        const int res = std::stoi(s, &processed_chars);
+
+        // check if the string was completely read
+        if (JSON_UNLIKELY(processed_chars != s.size()))
+        {
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
+        }
+
+        return res;
+    }
+
     json_pointer top() const
     {
         if (JSON_UNLIKELY(empty()))
diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp
index 769126e5..6bc13727 100644
--- a/include/nlohmann/json.hpp
+++ b/include/nlohmann/json.hpp
@@ -3901,6 +3901,8 @@ class basic_json
 
     @liveexample{The example shows how `find()` is used.,find__key_type}
 
+    @sa @ref contains(KeyT&&) const -- checks whether a key exists
+
     @since version 1.0.0
     */
     template<typename KeyT>
@@ -3979,6 +3981,10 @@ class basic_json
 
     @complexity Logarithmic in the size of the JSON object.
 
+    @liveexample{The following code shows an example for `contains()`.,contains}
+
+    @sa @ref find(KeyT&&) -- returns an iterator to an object element
+
     @since version 3.6.0
     */
     template<typename KeyT>
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index 338d2b0d..f5b3aa7c 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -323,7 +323,7 @@ name / id                     | example message | description
 ----------------------------- | --------------- | -------------------------
 json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
 json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
-json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&.
+json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
@@ -2296,9 +2296,9 @@ class file_input_adapter : public input_adapter_protocol
 
     // make class move-only
     file_input_adapter(const file_input_adapter&) = delete;
-    file_input_adapter(file_input_adapter&&) noexcept = default;
+    file_input_adapter(file_input_adapter&&) = default;
     file_input_adapter& operator=(const file_input_adapter&) = delete;
-    file_input_adapter& operator=(file_input_adapter&&) noexcept = default;
+    file_input_adapter& operator=(file_input_adapter&&) = default;
     ~file_input_adapter() override = default;
 
     std::char_traits<char>::int_type get_character() noexcept override
@@ -8529,7 +8529,9 @@ class json_pointer
     */
     json_pointer& operator/=(const json_pointer& ptr)
     {
-        reference_tokens.insert(reference_tokens.end(), ptr.reference_tokens.begin(), ptr.reference_tokens.end());
+        reference_tokens.insert(reference_tokens.end(),
+                                ptr.reference_tokens.begin(),
+                                ptr.reference_tokens.end());
         return *this;
     }
 
@@ -8549,7 +8551,8 @@ class json_pointer
     /*!
     @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)
+    friend json_pointer operator/(const json_pointer& left_ptr,
+                                  const json_pointer& right_ptr)
     {
         return json_pointer(left_ptr) /= right_ptr;
     }
@@ -8571,7 +8574,17 @@ class json_pointer
     }
 
     /*!
-    @brief create a new JSON pointer that is the parent of this JSON pointer
+    @brief returns the parent of this JSON pointer
+
+    @return parent of this JSON pointer; in case this JSON pointer is the root,
+            the root itself is returned
+
+    @complexity Constant.
+
+    @liveexample{The example shows the result of `parent_pointer` for different
+    JSON Pointers.,json_pointer__parent_pointer}
+
+    @since version 3.6.0
     */
     json_pointer parent_pointer() const
     {
@@ -8585,27 +8598,6 @@ class json_pointer
         return res;
     }
 
-    /*!
-    @param[in] s  reference token to be converted into an array index
-
-    @return integer representation of @a s
-
-    @throw out_of_range.404 if string @a s could not be converted to an integer
-    */
-    static int array_index(const std::string& s)
-    {
-        std::size_t processed_chars = 0;
-        const int res = std::stoi(s, &processed_chars);
-
-        // check if the string was completely read
-        if (JSON_UNLIKELY(processed_chars != s.size()))
-        {
-            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
-        }
-
-        return res;
-    }
-
     /*!
     @brief remove and return last reference token
     @throw out_of_range.405 if JSON pointer has no parent
@@ -8624,6 +8616,15 @@ class json_pointer
 
     /*!
     @brief append an unescaped token at the end of the reference pointer
+
+    @param[in] token  token to add
+
+    @complexity Amortized constant.
+
+    @liveexample{The example shows the result of `push_back` for different
+    JSON Pointers.,json_pointer__push_back}
+
+    @since version 0.6.0
     */
     void push_back(const std::string& token)
     {
@@ -8636,13 +8637,47 @@ class json_pointer
         reference_tokens.push_back(std::move(token));
     }
 
-    /// return whether pointer points to the root document
+    /*!
+    @brief return whether pointer points to the root document
+
+    @return true iff the JSON pointer points to the root document
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example shows the result of `empty` for different JSON
+    Pointers.,json_pointer__empty}
+
+    @since version 3.6.0
+    */
     bool empty() const noexcept
     {
         return reference_tokens.empty();
     }
 
   private:
+    /*!
+    @param[in] s  reference token to be converted into an array index
+
+    @return integer representation of @a s
+
+    @throw out_of_range.404 if string @a s could not be converted to an integer
+    */
+    static int array_index(const std::string& s)
+    {
+        std::size_t processed_chars = 0;
+        const int res = std::stoi(s, &processed_chars);
+
+        // check if the string was completely read
+        if (JSON_UNLIKELY(processed_chars != s.size()))
+        {
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
+        }
+
+        return res;
+    }
+
     json_pointer top() const
     {
         if (JSON_UNLIKELY(empty()))
@@ -16543,6 +16578,8 @@ class basic_json
 
     @liveexample{The example shows how `find()` is used.,find__key_type}
 
+    @sa @ref contains(KeyT&&) const -- checks whether a key exists
+
     @since version 1.0.0
     */
     template<typename KeyT>
@@ -16621,6 +16658,10 @@ class basic_json
 
     @complexity Logarithmic in the size of the JSON object.
 
+    @liveexample{The following code shows an example for `contains()`.,contains}
+
+    @sa @ref find(KeyT&&) -- returns an iterator to an object element
+
     @since version 3.6.0
     */
     template<typename KeyT>