diff --git a/src/json.hpp b/src/json.hpp
index d1338969..61b18f10 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -5712,10 +5712,41 @@ class basic_json
             json_iterator anchor;
             /// an index for arrays
             size_t array_index = 0;
-            size_t container_size = 0;
 
-            /// calculate a key for the iterator
-            std::string calculate_key()
+          public:
+            /// construct wrapper given an iterator
+            iterator_wrapper_internal(json_iterator i) : anchor(i)
+            {}
+
+            /// dereference operator (needed for range-based for)
+            iterator_wrapper_internal& operator*()
+            {
+                return *this;
+            }
+
+            /// increment operator (needed for range-based for)
+            iterator_wrapper_internal& operator++()
+            {
+                ++anchor;
+                ++array_index;
+
+                return *this;
+            }
+
+            /// inequality operator (needed for range-based for)
+            bool operator!= (const iterator_wrapper_internal& o)
+            {
+                return anchor != o.anchor;
+            }
+
+            /// stream operator
+            friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
+            {
+                return o << w.value();
+            }
+
+            /// return key of the iterator
+            typename basic_json::string_t key() const
             {
                 switch (anchor.m_object->type())
                 {
@@ -5739,61 +5770,11 @@ class basic_json
                 }
             }
 
-          public:
-            /// construct wrapper given an iterator
-            iterator_wrapper_internal(json_iterator i, size_t s)
-                : anchor(i), container_size(s), first(calculate_key()), second(*i)
-            {}
-
-            /// dereference operator (needed for range-based for)
-            iterator_wrapper_internal operator*()
-            {
-                return *this;
-            }
-
-            /// increment operator (needed for range-based for)
-            iterator_wrapper_internal& operator++()
-            {
-                ++anchor;
-                ++array_index;
-
-                if (array_index < container_size)
-                {
-                    first = calculate_key();
-                    second = *anchor;
-                }
-
-                return *this;
-            }
-
-            /// inequality operator (needed for range-based for)
-            bool operator!= (const iterator_wrapper_internal& o)
-            {
-                return anchor != o.anchor;
-            }
-
-            /// stream operator
-            friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
-            {
-                return o << w.value();
-            }
-
-            /// return key of the iterator
-            typename basic_json::string_t key() const
-            {
-                return first;
-            }
-
             /// return value of the iterator
-            basic_json value() const
+            typename json_iterator::reference value() const
             {
-                return second;
+                return anchor.value();
             }
-
-            /// public member to simulate std::map::iterator access
-            typename basic_json::string_t first;
-            /// public member to simulate std::map::iterator access
-            basic_json& second;
         };
 
       public:
@@ -5805,13 +5786,13 @@ class basic_json
         /// return iterator begin (needed for range-based for)
         iterator_wrapper_internal begin()
         {
-            return iterator_wrapper_internal(container.begin(), container.size());
+            return iterator_wrapper_internal(container.begin());
         }
 
         /// return iterator end (needed for range-based for)
         iterator_wrapper_internal end()
         {
-            return iterator_wrapper_internal(container.end(), container.size());
+            return iterator_wrapper_internal(container.end());
         }
     };
 
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index f8547367..2f01c007 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -5712,10 +5712,41 @@ class basic_json
             json_iterator anchor;
             /// an index for arrays
             size_t array_index = 0;
-            size_t container_size = 0;
 
-            /// calculate a key for the iterator
-            std::string calculate_key()
+          public:
+            /// construct wrapper given an iterator
+            iterator_wrapper_internal(json_iterator i) : anchor(i)
+            {}
+
+            /// dereference operator (needed for range-based for)
+            iterator_wrapper_internal& operator*()
+            {
+                return *this;
+            }
+
+            /// increment operator (needed for range-based for)
+            iterator_wrapper_internal& operator++()
+            {
+                ++anchor;
+                ++array_index;
+
+                return *this;
+            }
+
+            /// inequality operator (needed for range-based for)
+            bool operator!= (const iterator_wrapper_internal& o)
+            {
+                return anchor != o.anchor;
+            }
+
+            /// stream operator
+            friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
+            {
+                return o << w.value();
+            }
+
+            /// return key of the iterator
+            typename basic_json::string_t key() const
             {
                 switch (anchor.m_object->type())
                 {
@@ -5739,61 +5770,11 @@ class basic_json
                 }
             }
 
-          public:
-            /// construct wrapper given an iterator
-            iterator_wrapper_internal(json_iterator i, size_t s)
-                : anchor(i), container_size(s), first(calculate_key()), second(*i)
-            {}
-
-            /// dereference operator (needed for range-based for)
-            iterator_wrapper_internal operator*()
-            {
-                return *this;
-            }
-
-            /// increment operator (needed for range-based for)
-            iterator_wrapper_internal& operator++()
-            {
-                ++anchor;
-                ++array_index;
-
-                if (array_index < container_size)
-                {
-                    first = calculate_key();
-                    second = *anchor;
-                }
-
-                return *this;
-            }
-
-            /// inequality operator (needed for range-based for)
-            bool operator!= (const iterator_wrapper_internal& o)
-            {
-                return anchor != o.anchor;
-            }
-
-            /// stream operator
-            friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
-            {
-                return o << w.value();
-            }
-
-            /// return key of the iterator
-            typename basic_json::string_t key() const
-            {
-                return first;
-            }
-
             /// return value of the iterator
-            basic_json value() const
+            typename json_iterator::reference value() const
             {
-                return second;
+                return anchor.value();
             }
-
-            /// public member to simulate std::map::iterator access
-            typename basic_json::string_t first;
-            /// public member to simulate std::map::iterator access
-            basic_json& second;
         };
 
       public:
@@ -5805,13 +5786,13 @@ class basic_json
         /// return iterator begin (needed for range-based for)
         iterator_wrapper_internal begin()
         {
-            return iterator_wrapper_internal(container.begin(), container.size());
+            return iterator_wrapper_internal(container.begin());
         }
 
         /// return iterator end (needed for range-based for)
         iterator_wrapper_internal end()
         {
-            return iterator_wrapper_internal(container.end(), container.size());
+            return iterator_wrapper_internal(container.end());
         }
     };
 
diff --git a/test/unit.cpp b/test/unit.cpp
index 81602161..d866b96d 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -9260,70 +9260,301 @@ TEST_CASE("concepts")
     }
 }
 
-/*
 TEST_CASE("iterator_wrapper")
 {
     SECTION("object")
     {
-        json j = {{"A", 1}, {"B", 2}};
-        int counter = 1;
-
-        for (auto i : json::iterator_wrapper(j))
+        SECTION("value")
         {
-            switch (counter++)
-            {
-                case 1:
-                {
-                    CHECK(i.key() == "A");
-                    CHECK(i.value() == json(1));
-                    CHECK(i.first == "A");
-                    CHECK(i.second == json(1));
-                    break;
-                }
+            json j = {{"A", 1}, {"B", 2}};
+            int counter = 1;
 
-                case 2:
+            for (auto i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
                 {
-                    CHECK(i.key() == "B");
-                    CHECK(i.value() == json(2));
-                    CHECK(i.first == "B");
-                    CHECK(i.second == json(2));
-                    break;
+                    case 1:
+                    {
+                        CHECK(i.key() == "A");
+                        CHECK(i.value() == json(1));
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "B");
+                        CHECK(i.value() == json(2));
+                        break;
+                    }
                 }
             }
+
+            CHECK(counter == 3);
+        }
+
+        SECTION("reference")
+        {
+            json j = {{"A", 1}, {"B", 2}};
+            int counter = 1;
+
+            for (auto& i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
+                {
+                    case 1:
+                    {
+                        CHECK(i.key() == "A");
+                        CHECK(i.value() == json(1));
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "B");
+                        CHECK(i.value() == json(2));
+                        break;
+                    }
+                }
+            }
+
+            CHECK(counter == 3);
+        }
+
+        SECTION("const value")
+        {
+            json j = {{"A", 1}, {"B", 2}};
+            int counter = 1;
+
+            for (const auto i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
+                {
+                    case 1:
+                    {
+                        CHECK(i.key() == "A");
+                        CHECK(i.value() == json(1));
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "B");
+                        CHECK(i.value() == json(2));
+                        break;
+                    }
+                }
+            }
+
+            CHECK(counter == 3);
+        }
+
+        SECTION("const reference")
+        {
+            json j = {{"A", 1}, {"B", 2}};
+            int counter = 1;
+
+            for (const auto& i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
+                {
+                    case 1:
+                    {
+                        CHECK(i.key() == "A");
+                        CHECK(i.value() == json(1));
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "B");
+                        CHECK(i.value() == json(2));
+                        break;
+                    }
+                }
+            }
+
+            CHECK(counter == 3);
         }
     }
 
     SECTION("array")
     {
-        json j = {"A", "B"};
-        int counter = 1;
-
-        for (auto i : json::iterator_wrapper(j))
+        SECTION("value")
         {
-            switch (counter++)
-            {
-                case 1:
-                {
-                    CHECK(i.key() == "0");
-                    CHECK(i.value() == "A");
-                    CHECK(i.first == "0");
-                    CHECK(i.second == "A");
-                    break;
-                }
+            json j = {"A", "B"};
+            int counter = 1;
 
-                case 2:
+            for (auto i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
                 {
-                    CHECK(i.key() == "1");
-                    CHECK(i.value() == "B");
-                    CHECK(i.first == "1");
-                    CHECK(i.second == "B");
-                    break;
+                    case 1:
+                    {
+                        CHECK(i.key() == "0");
+                        CHECK(i.value() == "A");
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "1");
+                        CHECK(i.value() == "B");
+                        break;
+                    }
                 }
             }
+
+            CHECK(counter == 3);
+        }
+
+        SECTION("reference")
+        {
+            json j = {"A", "B"};
+            int counter = 1;
+
+            for (auto& i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
+                {
+                    case 1:
+                    {
+                        CHECK(i.key() == "0");
+                        CHECK(i.value() == "A");
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "1");
+                        CHECK(i.value() == "B");
+                        break;
+                    }
+                }
+            }
+
+            CHECK(counter == 3);
+        }
+
+        SECTION("const value")
+        {
+            json j = {"A", "B"};
+            int counter = 1;
+
+            for (const auto i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
+                {
+                    case 1:
+                    {
+                        CHECK(i.key() == "0");
+                        CHECK(i.value() == "A");
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "1");
+                        CHECK(i.value() == "B");
+                        break;
+                    }
+                }
+            }
+
+            CHECK(counter == 3);
+        }
+
+        SECTION("const reference")
+        {
+            json j = {"A", "B"};
+            int counter = 1;
+
+            for (const auto& i : json::iterator_wrapper(j))
+            {
+                switch (counter++)
+                {
+                    case 1:
+                    {
+                        CHECK(i.key() == "0");
+                        CHECK(i.value() == "A");
+                        break;
+                    }
+
+                    case 2:
+                    {
+                        CHECK(i.key() == "1");
+                        CHECK(i.value() == "B");
+                        break;
+                    }
+                }
+            }
+
+            CHECK(counter == 3);
+        }
+    }
+
+    SECTION("primitive")
+    {
+        SECTION("value")
+        {
+            json j = 1;
+            int counter = 1;
+
+            for (auto i : json::iterator_wrapper(j))
+            {
+                ++counter;
+                CHECK(i.key() == "");
+                CHECK(i.value() == json(1));
+            }
+
+            CHECK(counter == 2);
+        }
+
+        SECTION("reference")
+        {
+            json j = 1;
+            int counter = 1;
+
+            for (auto& i : json::iterator_wrapper(j))
+            {
+                ++counter;
+                CHECK(i.key() == "");
+                CHECK(i.value() == json(1));
+            }
+
+            CHECK(counter == 2);
+        }
+
+        SECTION("const value")
+        {
+            json j = 1;
+            int counter = 1;
+
+            for (const auto i : json::iterator_wrapper(j))
+            {
+                ++counter;
+                CHECK(i.key() == "");
+                CHECK(i.value() == json(1));
+            }
+
+            CHECK(counter == 2);
+        }
+
+        SECTION("reference")
+        {
+            json j = 1;
+            int counter = 1;
+
+            for (const auto& i : json::iterator_wrapper(j))
+            {
+                ++counter;
+                CHECK(i.key() == "");
+                CHECK(i.value() == json(1));
+            }
+
+            CHECK(counter == 2);
         }
     }
 }
-*/
 
 TEST_CASE("compliance tests from json.org")
 {