diff --git a/.gitignore b/.gitignore
index 35dc9b42..086e855c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,4 @@ benchmarks/files/numbers/*.json
 cmake-build-debug
 
 test/test-*
+/.vs
diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp
index d274eadd..ee13eb55 100644
--- a/include/nlohmann/detail/conversions/to_json.hpp
+++ b/include/nlohmann/detail/conversions/to_json.hpp
@@ -290,9 +290,9 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
 template <
     typename BasicJsonType, typename T, std::size_t N,
     enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
-                const T (&)[N]>::value,
+                const T(&)[N]>::value,
                 int> = 0 >
-void to_json(BasicJsonType& j, const T (&arr)[N])
+void to_json(BasicJsonType& j, const T(&arr)[N])
 {
     external_constructor<value_t::array>::construct(j, arr);
 }
@@ -300,21 +300,21 @@ void to_json(BasicJsonType& j, const T (&arr)[N])
 template<typename BasicJsonType, typename... Args>
 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
 {
-    j = {p.first, p.second};
+    j = { p.first, p.second };
 }
 
 // for https://github.com/nlohmann/json/pull/1134
-template<typename BasicJsonType, typename T,
-         enable_if_t<std::is_same<T, typename iteration_proxy<typename BasicJsonType::iterator>::iteration_proxy_internal>::value, int> = 0>
+template < typename BasicJsonType, typename T,
+           enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
 void to_json(BasicJsonType& j, const T& b)
 {
-    j = {{b.key(), b.value()}};
+    j = { {b.key(), b.value()} };
 }
 
 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
 {
-    j = {std::get<Idx>(t)...};
+    j = { std::get<Idx>(t)... };
 }
 
 template<typename BasicJsonType, typename... Args>
diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp
index 6674c064..81a5e0d7 100644
--- a/include/nlohmann/detail/iterators/iter_impl.hpp
+++ b/include/nlohmann/detail/iterators/iter_impl.hpp
@@ -17,24 +17,21 @@ namespace detail
 {
 // forward declare, to be able to friend it later on
 template<typename IteratorType> class iteration_proxy;
+template<typename IteratorType> class iteration_proxy_value;
 
 /*!
 @brief a template for a bidirectional iterator for the @ref basic_json class
-
 This class implements a both iterators (iterator and const_iterator) for the
 @ref basic_json class.
-
 @note An iterator is called *initialized* when a pointer to a JSON value has
       been set (e.g., by a constructor or a copy assignment). If the iterator is
       default-constructed, it is *uninitialized* and most methods are undefined.
       **The library uses assertions to detect calls on uninitialized iterators.**
-
 @requirement The class satisfies the following concept requirements:
 -
 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
   The iterator that can be moved can be moved in both directions (i.e.
   incremented and decremented).
-
 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
 */
@@ -45,6 +42,7 @@ class iter_impl
     friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
     friend BasicJsonType;
     friend iteration_proxy<iter_impl>;
+    friend iteration_proxy_value<iter_impl>;
 
     using object_t = typename BasicJsonType::object_t;
     using array_t = typename BasicJsonType::array_t;
@@ -611,4 +609,4 @@ class iter_impl
     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
 };
 }  // namespace detail
-}  // namespace nlohmann
+} // namespace nlohmann
\ No newline at end of file
diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp
index d4f90502..837ce9c8 100644
--- a/include/nlohmann/detail/iterators/iteration_proxy.hpp
+++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp
@@ -3,104 +3,105 @@
 #include <cstddef> // size_t
 #include <string> // string, to_string
 #include <iterator> // input_iterator_tag
+#include <tuple> // tuple_size, get, tuple_element
 
 #include <nlohmann/detail/value_t.hpp>
+#include <nlohmann/detail/meta/type_traits.hpp>
 
 namespace nlohmann
 {
 namespace detail
 {
+template <typename IteratorType> class iteration_proxy_value
+{
+  public:
+    using difference_type = std::ptrdiff_t;
+    using value_type = iteration_proxy_value;
+    using pointer = value_type * ;
+    using reference = value_type & ;
+    using iterator_category = std::input_iterator_tag;
+
+  private:
+    /// the iterator
+    IteratorType anchor;
+    /// an index for arrays (used to create key names)
+    std::size_t array_index = 0;
+    /// last stringified array index
+    mutable std::size_t array_index_last = 0;
+    /// a string representation of the array index
+    mutable std::string array_index_str = "0";
+    /// an empty string (to return a reference for primitive values)
+    const std::string empty_str = "";
+
+  public:
+    explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
+
+    /// dereference operator (needed for range-based for)
+    iteration_proxy_value& operator*()
+    {
+        return *this;
+    }
+
+    /// increment operator (needed for range-based for)
+    iteration_proxy_value& operator++()
+    {
+        ++anchor;
+        ++array_index;
+
+        return *this;
+    }
+
+    /// equality operator (needed for InputIterator)
+    bool operator==(const iteration_proxy_value& o) const noexcept
+    {
+        return anchor == o.anchor;
+    }
+
+    /// inequality operator (needed for range-based for)
+    bool operator!=(const iteration_proxy_value& o) const noexcept
+    {
+        return anchor != o.anchor;
+    }
+
+    /// return key of the iterator
+    const std::string& key() const
+    {
+        assert(anchor.m_object != nullptr);
+
+        switch (anchor.m_object->type())
+        {
+            // use integer array index as key
+            case value_t::array:
+            {
+                if (array_index != array_index_last)
+                {
+                    array_index_str = std::to_string(array_index);
+                    array_index_last = array_index;
+                }
+                return array_index_str;
+            }
+
+            // use key from the object
+            case value_t::object:
+                return anchor.key();
+
+            // use an empty key for all primitive types
+            default:
+                return empty_str;
+        }
+    }
+
+    /// return value of the iterator
+    typename IteratorType::reference value() const
+    {
+        return anchor.value();
+    }
+};
+
 /// proxy class for the items() function
 template<typename IteratorType> class iteration_proxy
 {
   private:
-    /// helper class for iteration
-    class iteration_proxy_internal
-    {
-      public:
-        using difference_type = std::ptrdiff_t;
-        using value_type = iteration_proxy_internal;
-        using pointer = iteration_proxy_internal*;
-        using reference = iteration_proxy_internal&;
-        using iterator_category = std::input_iterator_tag;
-
-      private:
-        /// the iterator
-        IteratorType anchor;
-        /// an index for arrays (used to create key names)
-        std::size_t array_index = 0;
-        /// last stringified array index
-        mutable std::size_t array_index_last = 0;
-        /// a string representation of the array index
-        mutable std::string array_index_str = "0";
-        /// an empty string (to return a reference for primitive values)
-        const std::string empty_str = "";
-
-      public:
-        explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
-
-        /// dereference operator (needed for range-based for)
-        iteration_proxy_internal& operator*()
-        {
-            return *this;
-        }
-
-        /// increment operator (needed for range-based for)
-        iteration_proxy_internal& operator++()
-        {
-            ++anchor;
-            ++array_index;
-
-            return *this;
-        }
-
-        /// equality operator (needed for InputIterator)
-        bool operator==(const iteration_proxy_internal& o) const noexcept
-        {
-            return anchor == o.anchor;
-        }
-
-        /// inequality operator (needed for range-based for)
-        bool operator!=(const iteration_proxy_internal& o) const noexcept
-        {
-            return anchor != o.anchor;
-        }
-
-        /// return key of the iterator
-        const std::string& key() const
-        {
-            assert(anchor.m_object != nullptr);
-
-            switch (anchor.m_object->type())
-            {
-                // use integer array index as key
-                case value_t::array:
-                {
-                    if (array_index != array_index_last)
-                    {
-                        array_index_str = std::to_string(array_index);
-                        array_index_last = array_index;
-                    }
-                    return array_index_str;
-                }
-
-                // use key from the object
-                case value_t::object:
-                    return anchor.key();
-
-                // use an empty key for all primitive types
-                default:
-                    return empty_str;
-            }
-        }
-
-        /// return value of the iterator
-        typename IteratorType::reference value() const
-        {
-            return anchor.value();
-        }
-    };
-
     /// the container to iterate
     typename IteratorType::reference container;
 
@@ -110,16 +111,52 @@ template<typename IteratorType> class iteration_proxy
         : container(cont) {}
 
     /// return iterator begin (needed for range-based for)
-    iteration_proxy_internal begin() noexcept
+    iteration_proxy_value<IteratorType> begin() noexcept
     {
-        return iteration_proxy_internal(container.begin());
+        return iteration_proxy_value<IteratorType>(container.begin());
     }
 
     /// return iterator end (needed for range-based for)
-    iteration_proxy_internal end() noexcept
+    iteration_proxy_value<IteratorType> end() noexcept
     {
-        return iteration_proxy_internal(container.end());
+        return iteration_proxy_value<IteratorType>(container.end());
     }
 };
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
+{
+    return i.key();
+}
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
+{
+    return i.value();
+}
 }  // namespace detail
 }  // namespace nlohmann
+
+// The Addition to the STD Namespace is required to add
+// Structured Bindings Support to the iteration_proxy_value class
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+namespace std
+{
+template <typename IteratorType>
+struct tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
+            : std::integral_constant<std::size_t, 2> {};
+
+template <std::size_t N, typename IteratorType>
+struct tuple_element <
+    N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
+{
+    using type = decltype(
+                     get<N>(std::declval <
+                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
+};
+}
\ No newline at end of file
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index 081d897a..dbcec732 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -1649,105 +1649,107 @@ constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::va
 #include <cstddef> // size_t
 #include <string> // string, to_string
 #include <iterator> // input_iterator_tag
+#include <tuple> // tuple_size, get, tuple_element
 
 // #include <nlohmann/detail/value_t.hpp>
 
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
 
 namespace nlohmann
 {
 namespace detail
 {
+template <typename IteratorType> class iteration_proxy_value
+{
+  public:
+    using difference_type = std::ptrdiff_t;
+    using value_type = iteration_proxy_value;
+    using pointer = value_type * ;
+    using reference = value_type & ;
+    using iterator_category = std::input_iterator_tag;
+
+  private:
+    /// the iterator
+    IteratorType anchor;
+    /// an index for arrays (used to create key names)
+    std::size_t array_index = 0;
+    /// last stringified array index
+    mutable std::size_t array_index_last = 0;
+    /// a string representation of the array index
+    mutable std::string array_index_str = "0";
+    /// an empty string (to return a reference for primitive values)
+    const std::string empty_str = "";
+
+  public:
+    explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
+
+    /// dereference operator (needed for range-based for)
+    iteration_proxy_value& operator*()
+    {
+        return *this;
+    }
+
+    /// increment operator (needed for range-based for)
+    iteration_proxy_value& operator++()
+    {
+        ++anchor;
+        ++array_index;
+
+        return *this;
+    }
+
+    /// equality operator (needed for InputIterator)
+    bool operator==(const iteration_proxy_value& o) const noexcept
+    {
+        return anchor == o.anchor;
+    }
+
+    /// inequality operator (needed for range-based for)
+    bool operator!=(const iteration_proxy_value& o) const noexcept
+    {
+        return anchor != o.anchor;
+    }
+
+    /// return key of the iterator
+    const std::string& key() const
+    {
+        assert(anchor.m_object != nullptr);
+
+        switch (anchor.m_object->type())
+        {
+            // use integer array index as key
+            case value_t::array:
+            {
+                if (array_index != array_index_last)
+                {
+                    array_index_str = std::to_string(array_index);
+                    array_index_last = array_index;
+                }
+                return array_index_str;
+            }
+
+            // use key from the object
+            case value_t::object:
+                return anchor.key();
+
+            // use an empty key for all primitive types
+            default:
+                return empty_str;
+        }
+    }
+
+    /// return value of the iterator
+    typename IteratorType::reference value() const
+    {
+        return anchor.value();
+    }
+};
+
 /// proxy class for the items() function
 template<typename IteratorType> class iteration_proxy
 {
   private:
-    /// helper class for iteration
-    class iteration_proxy_internal
-    {
-      public:
-        using difference_type = std::ptrdiff_t;
-        using value_type = iteration_proxy_internal;
-        using pointer = iteration_proxy_internal*;
-        using reference = iteration_proxy_internal&;
-        using iterator_category = std::input_iterator_tag;
-
-      private:
-        /// the iterator
-        IteratorType anchor;
-        /// an index for arrays (used to create key names)
-        std::size_t array_index = 0;
-        /// last stringified array index
-        mutable std::size_t array_index_last = 0;
-        /// a string representation of the array index
-        mutable std::string array_index_str = "0";
-        /// an empty string (to return a reference for primitive values)
-        const std::string empty_str = "";
-
-      public:
-        explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
-
-        /// dereference operator (needed for range-based for)
-        iteration_proxy_internal& operator*()
-        {
-            return *this;
-        }
-
-        /// increment operator (needed for range-based for)
-        iteration_proxy_internal& operator++()
-        {
-            ++anchor;
-            ++array_index;
-
-            return *this;
-        }
-
-        /// equality operator (needed for InputIterator)
-        bool operator==(const iteration_proxy_internal& o) const noexcept
-        {
-            return anchor == o.anchor;
-        }
-
-        /// inequality operator (needed for range-based for)
-        bool operator!=(const iteration_proxy_internal& o) const noexcept
-        {
-            return anchor != o.anchor;
-        }
-
-        /// return key of the iterator
-        const std::string& key() const
-        {
-            assert(anchor.m_object != nullptr);
-
-            switch (anchor.m_object->type())
-            {
-                // use integer array index as key
-                case value_t::array:
-                {
-                    if (array_index != array_index_last)
-                    {
-                        array_index_str = std::to_string(array_index);
-                        array_index_last = array_index;
-                    }
-                    return array_index_str;
-                }
-
-                // use key from the object
-                case value_t::object:
-                    return anchor.key();
-
-                // use an empty key for all primitive types
-                default:
-                    return empty_str;
-            }
-        }
-
-        /// return value of the iterator
-        typename IteratorType::reference value() const
-        {
-            return anchor.value();
-        }
-    };
-
     /// the container to iterate
     typename IteratorType::reference container;
 
@@ -1757,20 +1759,55 @@ template<typename IteratorType> class iteration_proxy
         : container(cont) {}
 
     /// return iterator begin (needed for range-based for)
-    iteration_proxy_internal begin() noexcept
+    iteration_proxy_value<IteratorType> begin() noexcept
     {
-        return iteration_proxy_internal(container.begin());
+        return iteration_proxy_value<IteratorType>(container.begin());
     }
 
     /// return iterator end (needed for range-based for)
-    iteration_proxy_internal end() noexcept
+    iteration_proxy_value<IteratorType> end() noexcept
     {
-        return iteration_proxy_internal(container.end());
+        return iteration_proxy_value<IteratorType>(container.end());
     }
 };
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
+{
+    return i.key();
+}
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
+{
+    return i.value();
+}
 }  // namespace detail
 }  // namespace nlohmann
 
+// The Addition to the STD Namespace is required to add
+// Structured Bindings Support to the iteration_proxy_value class
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+namespace std
+{
+template <typename IteratorType>
+struct tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
+            : std::integral_constant<std::size_t, 2> {};
+
+template <std::size_t N, typename IteratorType>
+struct tuple_element <
+    N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
+{
+    using type = decltype(
+                     get<N>(std::declval <
+                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
+};
+}
 
 namespace nlohmann
 {
@@ -2049,9 +2086,9 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
 template <
     typename BasicJsonType, typename T, std::size_t N,
     enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
-                const T (&)[N]>::value,
+                const T(&)[N]>::value,
                 int> = 0 >
-void to_json(BasicJsonType& j, const T (&arr)[N])
+void to_json(BasicJsonType& j, const T(&arr)[N])
 {
     external_constructor<value_t::array>::construct(j, arr);
 }
@@ -2059,21 +2096,21 @@ void to_json(BasicJsonType& j, const T (&arr)[N])
 template<typename BasicJsonType, typename... Args>
 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
 {
-    j = {p.first, p.second};
+    j = { p.first, p.second };
 }
 
 // for https://github.com/nlohmann/json/pull/1134
-template<typename BasicJsonType, typename T,
-         enable_if_t<std::is_same<T, typename iteration_proxy<typename BasicJsonType::iterator>::iteration_proxy_internal>::value, int> = 0>
+template < typename BasicJsonType, typename T,
+           enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
 void to_json(BasicJsonType& j, const T& b)
 {
-    j = {{b.key(), b.value()}};
+    j = { {b.key(), b.value()} };
 }
 
 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
 {
-    j = {std::get<Idx>(t)...};
+    j = { std::get<Idx>(t)... };
 }
 
 template<typename BasicJsonType, typename... Args>
@@ -5570,24 +5607,21 @@ namespace detail
 {
 // forward declare, to be able to friend it later on
 template<typename IteratorType> class iteration_proxy;
+template<typename IteratorType> class iteration_proxy_value;
 
 /*!
 @brief a template for a bidirectional iterator for the @ref basic_json class
-
 This class implements a both iterators (iterator and const_iterator) for the
 @ref basic_json class.
-
 @note An iterator is called *initialized* when a pointer to a JSON value has
       been set (e.g., by a constructor or a copy assignment). If the iterator is
       default-constructed, it is *uninitialized* and most methods are undefined.
       **The library uses assertions to detect calls on uninitialized iterators.**
-
 @requirement The class satisfies the following concept requirements:
 -
 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
   The iterator that can be moved can be moved in both directions (i.e.
   incremented and decremented).
-
 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
 */
@@ -5598,6 +5632,7 @@ class iter_impl
     friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
     friend BasicJsonType;
     friend iteration_proxy<iter_impl>;
+    friend iteration_proxy_value<iter_impl>;
 
     using object_t = typename BasicJsonType::object_t;
     using array_t = typename BasicJsonType::array_t;
@@ -6164,8 +6199,7 @@ class iter_impl
     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
 };
 }  // namespace detail
-}  // namespace nlohmann
-
+} // namespace nlohmann
 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
 
 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
diff --git a/test/src/unit-items.cpp b/test/src/unit-items.cpp
index bfa3f9e4..2afcde44 100644
--- a/test/src/unit-items.cpp
+++ b/test/src/unit-items.cpp
@@ -3,21 +3,17 @@
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
 |  |  |__   |  |  | | | |  version 3.4.0
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
-
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
 SPDX-License-Identifier: MIT
 Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
-
 Permission is hereby  granted, free of charge, to any  person obtaining a copy
 of this software and associated  documentation files (the "Software"), to deal
 in the Software  without restriction, including without  limitation the rights
 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
 furnished to do so, subject to the following conditions:
-
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
-
 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
@@ -32,13 +28,20 @@ SOFTWARE.
 #include <nlohmann/json.hpp>
 using nlohmann::json;
 
+#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
+    #define JSON_HAS_CPP_17
+    #define JSON_HAS_CPP_14
+#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
+    #define JSON_HAS_CPP_14
+#endif
+
 TEST_CASE("iterator_wrapper")
 {
     SECTION("object")
     {
         SECTION("value")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto i : json::iterator_wrapper(j))
@@ -71,7 +74,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("reference")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto& i : json::iterator_wrapper(j))
@@ -110,12 +113,12 @@ TEST_CASE("iterator_wrapper")
             CHECK(counter == 3);
 
             // check if values where changed
-            CHECK(j == json({{"A", 11}, {"B", 22}}));
+            CHECK(j == json({ {"A", 11}, {"B", 22} }));
         }
 
         SECTION("const value")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto i : json::iterator_wrapper(j))
@@ -148,7 +151,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("const reference")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto& i : json::iterator_wrapper(j))
@@ -184,7 +187,7 @@ TEST_CASE("iterator_wrapper")
     {
         SECTION("value")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto i : json::iterator_wrapper(j))
@@ -217,7 +220,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("reference")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto& i : json::iterator_wrapper(j))
@@ -250,7 +253,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("const value")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto i : json::iterator_wrapper(j))
@@ -283,7 +286,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("const reference")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto& i : json::iterator_wrapper(j))
@@ -319,7 +322,7 @@ TEST_CASE("iterator_wrapper")
     {
         SECTION("value")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (auto i : json::iterator_wrapper(j))
@@ -352,7 +355,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("reference")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (auto& i : json::iterator_wrapper(j))
@@ -391,12 +394,12 @@ TEST_CASE("iterator_wrapper")
             CHECK(counter == 3);
 
             // check if values where changed
-            CHECK(j == json({"AA", "BB"}));
+            CHECK(j == json({ "AA", "BB" }));
         }
 
         SECTION("const value")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (const auto i : json::iterator_wrapper(j))
@@ -429,7 +432,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("const reference")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (const auto& i : json::iterator_wrapper(j))
@@ -465,7 +468,7 @@ TEST_CASE("iterator_wrapper")
     {
         SECTION("value")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (auto i : json::iterator_wrapper(j))
@@ -498,7 +501,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("reference")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (auto& i : json::iterator_wrapper(j))
@@ -531,7 +534,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("const value")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (const auto i : json::iterator_wrapper(j))
@@ -564,7 +567,7 @@ TEST_CASE("iterator_wrapper")
 
         SECTION("const reference")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (const auto& i : json::iterator_wrapper(j))
@@ -735,7 +738,7 @@ TEST_CASE("items()")
     {
         SECTION("value")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto i : j.items())
@@ -768,7 +771,7 @@ TEST_CASE("items()")
 
         SECTION("reference")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto& i : j.items())
@@ -807,12 +810,12 @@ TEST_CASE("items()")
             CHECK(counter == 3);
 
             // check if values where changed
-            CHECK(j == json({{"A", 11}, {"B", 22}}));
+            CHECK(j == json({ {"A", 11}, {"B", 22} }));
         }
 
         SECTION("const value")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto i : j.items())
@@ -845,7 +848,7 @@ TEST_CASE("items()")
 
         SECTION("const reference")
         {
-            json j = {{"A", 1}, {"B", 2}};
+            json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto& i : j.items())
@@ -875,13 +878,29 @@ TEST_CASE("items()")
 
             CHECK(counter == 3);
         }
+
+#ifdef JSON_HAS_CPP_17
+        SECTION("structured bindings")
+        {
+            json j = { {"A", 1}, {"B", 2} };
+
+            std::map<std::string, int> m;
+
+            for (auto const&[key, value] : j.items())
+            {
+                m.emplace(key, value);
+            }
+
+            CHECK(j.get<decltype(m)>() == m);
+        }
+#endif
     }
 
     SECTION("const object")
     {
         SECTION("value")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto i : j.items())
@@ -914,7 +933,7 @@ TEST_CASE("items()")
 
         SECTION("reference")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (auto& i : j.items())
@@ -947,7 +966,7 @@ TEST_CASE("items()")
 
         SECTION("const value")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto i : j.items())
@@ -980,7 +999,7 @@ TEST_CASE("items()")
 
         SECTION("const reference")
         {
-            const json j = {{"A", 1}, {"B", 2}};
+            const json j = { {"A", 1}, {"B", 2} };
             int counter = 1;
 
             for (const auto& i : j.items())
@@ -1016,7 +1035,7 @@ TEST_CASE("items()")
     {
         SECTION("value")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (auto i : j.items())
@@ -1049,7 +1068,7 @@ TEST_CASE("items()")
 
         SECTION("reference")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (auto& i : j.items())
@@ -1088,12 +1107,12 @@ TEST_CASE("items()")
             CHECK(counter == 3);
 
             // check if values where changed
-            CHECK(j == json({"AA", "BB"}));
+            CHECK(j == json({ "AA", "BB" }));
         }
 
         SECTION("const value")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (const auto i : j.items())
@@ -1126,7 +1145,7 @@ TEST_CASE("items()")
 
         SECTION("const reference")
         {
-            json j = {"A", "B"};
+            json j = { "A", "B" };
             int counter = 1;
 
             for (const auto& i : j.items())
@@ -1162,7 +1181,7 @@ TEST_CASE("items()")
     {
         SECTION("value")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (auto i : j.items())
@@ -1195,7 +1214,7 @@ TEST_CASE("items()")
 
         SECTION("reference")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (auto& i : j.items())
@@ -1228,7 +1247,7 @@ TEST_CASE("items()")
 
         SECTION("const value")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (const auto i : j.items())
@@ -1261,7 +1280,7 @@ TEST_CASE("items()")
 
         SECTION("const reference")
         {
-            const json j = {"A", "B"};
+            const json j = { "A", "B" };
             int counter = 1;
 
             for (const auto& i : j.items())
@@ -1424,4 +1443,4 @@ TEST_CASE("items()")
             CHECK(counter == 2);
         }
     }
-}
+}
\ No newline at end of file