From ed62129f8e2d2388e4c05d8de9d34ac197d09a2c Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Sat, 27 May 2017 13:44:14 +1000
Subject: [PATCH 01/11] Override n + iterator operator in the iterator

---
 src/json.hpp                 | 15 +++++++++++++--
 test/src/unit-iterators2.cpp | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 486b9c6c..902d80f6 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8474,18 +8474,29 @@ class basic_json
         @brief  add to iterator
         @pre The iterator is initialized; i.e. `m_object != nullptr`.
         */
-        iter_impl operator+(difference_type i)
+        iter_impl operator+(difference_type i) const
         {
             auto result = *this;
             result += i;
             return result;
         }
 
+        /*!
+        @brief  addition of distance and iterator
+        @pre The iterator is initialized; i.e. `m_object != nullptr`.
+        */
+        friend iter_impl operator+(difference_type i, const iter_impl& it)
+        {
+            auto result = it;
+            result += i;
+            return result;
+        }
+
         /*!
         @brief  subtract from iterator
         @pre The iterator is initialized; i.e. `m_object != nullptr`.
         */
-        iter_impl operator-(difference_type i)
+        iter_impl operator-(difference_type i) const
         {
             auto result = *this;
             result -= i;
diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp
index e20417a1..d9f43e2f 100644
--- a/test/src/unit-iterators2.cpp
+++ b/test/src/unit-iterators2.cpp
@@ -269,6 +269,16 @@ TEST_CASE("iterators 2")
                     CHECK_THROWS_AS(it + 1, json::invalid_iterator);
                     CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
                 }
+                {
+                    auto it = j_object.begin();
+                    CHECK_THROWS_AS(1 + it, json::invalid_iterator);
+                    CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                }
+                {
+                    auto it = j_object.cbegin();
+                    CHECK_THROWS_AS(1 + it, json::invalid_iterator);
+                    CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                }
                 {
                     auto it = j_object.begin();
                     CHECK_THROWS_AS(it -= 1, json::invalid_iterator);
@@ -688,6 +698,16 @@ TEST_CASE("iterators 2")
                     CHECK_THROWS_AS(it + 1, json::invalid_iterator);
                     CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
                 }
+                {
+                    auto it = j_object.rbegin();
+                    CHECK_THROWS_AS(1 + it, json::invalid_iterator);
+                    CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                }
+                {
+                    auto it = j_object.crbegin();
+                    CHECK_THROWS_AS(1 + it, json::invalid_iterator);
+                    CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                }
                 {
                     auto it = j_object.rbegin();
                     CHECK_THROWS_AS(it -= 1, json::invalid_iterator);

From adc73d6d5f3354da5b95283279e06e615e848738 Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 29 May 2017 18:52:53 +1000
Subject: [PATCH 02/11] Fix the arithmetic mistakes in reverse iterator

---
 src/json.hpp                 |  6 +++---
 test/src/unit-iterators2.cpp | 28 ++++++++++++++--------------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 902d80f6..fb2740ab 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8672,7 +8672,7 @@ class basic_json
         json_reverse_iterator operator+(difference_type i) const
         {
             auto result = *this;
-            result += i;
+            result -= i;
             return result;
         }
 
@@ -8680,14 +8680,14 @@ class basic_json
         json_reverse_iterator operator-(difference_type i) const
         {
             auto result = *this;
-            result -= i;
+            result += i;
             return result;
         }
 
         /// return difference
         difference_type operator-(const json_reverse_iterator& other) const
         {
-            return this->base() - other.base();
+            return other.base() - this->base();
         }
 
         /// access to successor
diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp
index d9f43e2f..3b767211 100644
--- a/test/src/unit-iterators2.cpp
+++ b/test/src/unit-iterators2.cpp
@@ -747,7 +747,7 @@ TEST_CASE("iterators 2")
                     it += 3;
                     CHECK((j_array.rbegin() + 3) == it);
                     CHECK((it - 3) == j_array.rbegin());
-                    CHECK((j_array.rbegin() - it) == 3);
+                    CHECK((it - j_array.rbegin()) == 3);
                     CHECK(*it == json(3));
                     it -= 2;
                     CHECK(*it == json(5));
@@ -757,7 +757,7 @@ TEST_CASE("iterators 2")
                     it += 3;
                     CHECK((j_array.crbegin() + 3) == it);
                     CHECK((it - 3) == j_array.crbegin());
-                    CHECK((j_array.crbegin() - it) == 3);
+                    CHECK((it - j_array.crbegin()) == 3);
                     CHECK(*it == json(3));
                     it -= 2;
                     CHECK(*it == json(5));
@@ -769,9 +769,9 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_null.rbegin();
                     it += 3;
-                    CHECK((j_null.rbegin() + 3) == it);
-                    CHECK((it - 3) == j_null.rbegin());
-                    CHECK((j_null.rbegin() - it) == 3);
+                    CHECK((j_null.rbegin() - 3) == it);
+                    CHECK((it + 3) == j_null.rbegin());
+                    CHECK((it - j_null.rbegin()) == 3);
                     CHECK(it != j_null.rend());
                     it -= 3;
                     CHECK(it == j_null.rend());
@@ -779,9 +779,9 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_null.crbegin();
                     it += 3;
-                    CHECK((j_null.crbegin() + 3) == it);
-                    CHECK((it - 3) == j_null.crbegin());
-                    CHECK((j_null.crbegin() - it) == 3);
+                    CHECK((j_null.crbegin() - 3) == it);
+                    CHECK((it + 3) == j_null.crbegin());
+                    CHECK((it - j_null.crbegin()) == 3);
                     CHECK(it != j_null.crend());
                     it -= 3;
                     CHECK(it == j_null.crend());
@@ -793,9 +793,9 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_value.rbegin();
                     it += 3;
-                    CHECK((j_value.rbegin() + 3) == it);
-                    CHECK((it - 3) == j_value.rbegin());
-                    CHECK((j_value.rbegin() - it) == 3);
+                    CHECK((j_value.rbegin() - 3) == it);
+                    CHECK((it + 3) == j_value.rbegin());
+                    CHECK((it - j_value.rbegin()) == 3);
                     CHECK(it != j_value.rend());
                     it -= 3;
                     CHECK(*it == json(42));
@@ -803,9 +803,9 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_value.crbegin();
                     it += 3;
-                    CHECK((j_value.crbegin() + 3) == it);
-                    CHECK((it - 3) == j_value.crbegin());
-                    CHECK((j_value.crbegin() - it) == 3);
+                    CHECK((j_value.crbegin() - 3) == it);
+                    CHECK((it + 3) == j_value.crbegin());
+                    CHECK((it - j_value.crbegin()) == 3);
                     CHECK(it != j_value.crend());
                     it -= 3;
                     CHECK(*it == json(42));

From a3bf0131c412d660ade37c08204909d979ca689e Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 29 May 2017 19:43:45 +1000
Subject: [PATCH 03/11] Fix some more reverse iterator arithmetic test codes

---
 test/src/unit-iterators2.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp
index 3b767211..2fcca263 100644
--- a/test/src/unit-iterators2.cpp
+++ b/test/src/unit-iterators2.cpp
@@ -769,8 +769,8 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_null.rbegin();
                     it += 3;
-                    CHECK((j_null.rbegin() - 3) == it);
-                    CHECK((it + 3) == j_null.rbegin());
+                    CHECK((j_null.rbegin() + 3) == it);
+                    CHECK((it - 3) == j_null.rbegin());
                     CHECK((it - j_null.rbegin()) == 3);
                     CHECK(it != j_null.rend());
                     it -= 3;
@@ -779,8 +779,8 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_null.crbegin();
                     it += 3;
-                    CHECK((j_null.crbegin() - 3) == it);
-                    CHECK((it + 3) == j_null.crbegin());
+                    CHECK((j_null.crbegin() + 3) == it);
+                    CHECK((it - 3) == j_null.crbegin());
                     CHECK((it - j_null.crbegin()) == 3);
                     CHECK(it != j_null.crend());
                     it -= 3;
@@ -793,8 +793,8 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_value.rbegin();
                     it += 3;
-                    CHECK((j_value.rbegin() - 3) == it);
-                    CHECK((it + 3) == j_value.rbegin());
+                    CHECK((j_value.rbegin() + 3) == it);
+                    CHECK((it - 3) == j_value.rbegin());
                     CHECK((it - j_value.rbegin()) == 3);
                     CHECK(it != j_value.rend());
                     it -= 3;
@@ -803,8 +803,8 @@ TEST_CASE("iterators 2")
                 {
                     auto it = j_value.crbegin();
                     it += 3;
-                    CHECK((j_value.crbegin() - 3) == it);
-                    CHECK((it + 3) == j_value.crbegin());
+                    CHECK((j_value.crbegin() + 3) == it);
+                    CHECK((it - 3) == j_value.crbegin());
                     CHECK((it - j_value.crbegin()) == 3);
                     CHECK(it != j_value.crend());
                     it -= 3;

From 3aef1a582e929dfae7c8ca4da2dc03439eb6f26e Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 29 May 2017 19:45:34 +1000
Subject: [PATCH 04/11] Change the definition of the operator override of
 reverse iterator to using the result of the base class directly

---
 src/json.hpp | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index fb2740ab..86fe8f86 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8626,7 +8626,7 @@ class basic_json
         using reference = typename Base::reference;
 
         /// create reverse iterator from iterator
-        json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
+		json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
             : base_iterator(it)
         {}
 
@@ -8671,29 +8671,25 @@ class basic_json
         /// add to iterator
         json_reverse_iterator operator+(difference_type i) const
         {
-            auto result = *this;
-            result -= i;
-            return result;
+            return json_reverse_iterator(base_iterator::operator+(i));
         }
 
         /// subtract from iterator
         json_reverse_iterator operator-(difference_type i) const
         {
-            auto result = *this;
-            result += i;
-            return result;
+            return json_reverse_iterator(base_iterator::operator-(i));
         }
 
         /// return difference
         difference_type operator-(const json_reverse_iterator& other) const
         {
-            return other.base() - this->base();
+            return base_iterator(*this) - base_iterator(other);
         }
 
         /// access to successor
         reference operator[](difference_type n) const
         {
-            return *(this->operator+(n));
+            return base_iterator::operator[](n);
         }
 
         /// return the key of an object iterator

From e42db27d6d90d5ab470ad392befa595277e0dd97 Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 29 May 2017 20:02:58 +1000
Subject: [PATCH 05/11] Fix the indentation from the latest commit

---
 src/json.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/json.hpp b/src/json.hpp
index 86fe8f86..13b62ded 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8626,7 +8626,7 @@ class basic_json
         using reference = typename Base::reference;
 
         /// create reverse iterator from iterator
-		json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
+        json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
             : base_iterator(it)
         {}
 

From 5b245dae06f0c61418a11d596ed28916c9647eca Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 29 May 2017 22:19:10 +1000
Subject: [PATCH 06/11] Comment out the exception message check in operator[]
 of reverse iterator

---
 test/src/unit-iterators2.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp
index 2fcca263..a27a924b 100644
--- a/test/src/unit-iterators2.cpp
+++ b/test/src/unit-iterators2.cpp
@@ -821,15 +821,15 @@ TEST_CASE("iterators 2")
                     auto it = j_object.rbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
-                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
                 }
                 {
                     auto it = j_object.crbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
-                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
                 }
             }
 
@@ -861,15 +861,15 @@ TEST_CASE("iterators 2")
                     auto it = j_null.rbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
-                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
+                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
+                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
                 }
                 {
                     auto it = j_null.crbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
-                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
+                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
+                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
                 }
             }
 

From 0c2ed00ebe1b1c8f289c4131cdc915979e8c5095 Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 29 May 2017 22:39:27 +1000
Subject: [PATCH 07/11] Add missing test cases for n + it arithmetic in
 iterators

---
 test/src/unit-iterators2.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp
index a27a924b..2be349b3 100644
--- a/test/src/unit-iterators2.cpp
+++ b/test/src/unit-iterators2.cpp
@@ -317,6 +317,7 @@ TEST_CASE("iterators 2")
                     auto it = j_array.begin();
                     it += 3;
                     CHECK((j_array.begin() + 3) == it);
+                    CHECK(json::iterator(3 + j_array.begin()) == it);
                     CHECK((it - 3) == j_array.begin());
                     CHECK((it - j_array.begin()) == 3);
                     CHECK(*it == json(4));
@@ -327,6 +328,7 @@ TEST_CASE("iterators 2")
                     auto it = j_array.cbegin();
                     it += 3;
                     CHECK((j_array.cbegin() + 3) == it);
+                    CHECK(json::const_iterator(3 + j_array.cbegin()) == it);
                     CHECK((it - 3) == j_array.cbegin());
                     CHECK((it - j_array.cbegin()) == 3);
                     CHECK(*it == json(4));
@@ -341,6 +343,7 @@ TEST_CASE("iterators 2")
                     auto it = j_null.begin();
                     it += 3;
                     CHECK((j_null.begin() + 3) == it);
+                    CHECK(json::iterator(3 + j_null.begin()) == it);
                     CHECK((it - 3) == j_null.begin());
                     CHECK((it - j_null.begin()) == 3);
                     CHECK(it != j_null.end());
@@ -351,6 +354,7 @@ TEST_CASE("iterators 2")
                     auto it = j_null.cbegin();
                     it += 3;
                     CHECK((j_null.cbegin() + 3) == it);
+                    CHECK(json::const_iterator(3 + j_null.cbegin()) == it);
                     CHECK((it - 3) == j_null.cbegin());
                     CHECK((it - j_null.cbegin()) == 3);
                     CHECK(it != j_null.cend());
@@ -365,6 +369,7 @@ TEST_CASE("iterators 2")
                     auto it = j_value.begin();
                     it += 3;
                     CHECK((j_value.begin() + 3) == it);
+                    CHECK(json::iterator(3 + j_value.begin()) == it);
                     CHECK((it - 3) == j_value.begin());
                     CHECK((it - j_value.begin()) == 3);
                     CHECK(it != j_value.end());
@@ -375,6 +380,7 @@ TEST_CASE("iterators 2")
                     auto it = j_value.cbegin();
                     it += 3;
                     CHECK((j_value.cbegin() + 3) == it);
+                    CHECK(json::const_iterator(3 + j_value.cbegin()) == it);
                     CHECK((it - 3) == j_value.cbegin());
                     CHECK((it - j_value.cbegin()) == 3);
                     CHECK(it != j_value.cend());
@@ -746,6 +752,7 @@ TEST_CASE("iterators 2")
                     auto it = j_array.rbegin();
                     it += 3;
                     CHECK((j_array.rbegin() + 3) == it);
+                    CHECK(json::reverse_iterator(3 + j_array.rbegin()) == it);
                     CHECK((it - 3) == j_array.rbegin());
                     CHECK((it - j_array.rbegin()) == 3);
                     CHECK(*it == json(3));
@@ -756,6 +763,7 @@ TEST_CASE("iterators 2")
                     auto it = j_array.crbegin();
                     it += 3;
                     CHECK((j_array.crbegin() + 3) == it);
+                    CHECK(json::const_reverse_iterator(3 + j_array.crbegin()) == it);
                     CHECK((it - 3) == j_array.crbegin());
                     CHECK((it - j_array.crbegin()) == 3);
                     CHECK(*it == json(3));
@@ -770,6 +778,7 @@ TEST_CASE("iterators 2")
                     auto it = j_null.rbegin();
                     it += 3;
                     CHECK((j_null.rbegin() + 3) == it);
+                    CHECK(json::reverse_iterator(3 + j_null.rbegin()) == it);
                     CHECK((it - 3) == j_null.rbegin());
                     CHECK((it - j_null.rbegin()) == 3);
                     CHECK(it != j_null.rend());
@@ -780,6 +789,7 @@ TEST_CASE("iterators 2")
                     auto it = j_null.crbegin();
                     it += 3;
                     CHECK((j_null.crbegin() + 3) == it);
+                    CHECK(json::const_reverse_iterator(3 + j_null.crbegin()) == it);
                     CHECK((it - 3) == j_null.crbegin());
                     CHECK((it - j_null.crbegin()) == 3);
                     CHECK(it != j_null.crend());
@@ -794,6 +804,7 @@ TEST_CASE("iterators 2")
                     auto it = j_value.rbegin();
                     it += 3;
                     CHECK((j_value.rbegin() + 3) == it);
+                    CHECK(json::reverse_iterator(3 + j_value.rbegin()) == it);
                     CHECK((it - 3) == j_value.rbegin());
                     CHECK((it - j_value.rbegin()) == 3);
                     CHECK(it != j_value.rend());
@@ -804,6 +815,7 @@ TEST_CASE("iterators 2")
                     auto it = j_value.crbegin();
                     it += 3;
                     CHECK((j_value.crbegin() + 3) == it);
+                    CHECK(json::const_reverse_iterator(3 + j_value.crbegin()) == it);
                     CHECK((it - 3) == j_value.crbegin());
                     CHECK((it - j_value.crbegin()) == 3);
                     CHECK(it != j_value.crend());

From daea213b44135f63409136bbd20cfae2f63b1aa6 Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 29 May 2017 23:56:21 +1000
Subject: [PATCH 08/11] Use static cast in the implementation of the operators
 of reverse iterator

---
 src/json.hpp | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 13b62ded..5c7074f4 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8638,46 +8638,43 @@ class basic_json
         /// post-increment (it++)
         json_reverse_iterator operator++(int)
         {
-            return base_iterator::operator++(1);
+            return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
         }
 
         /// pre-increment (++it)
         json_reverse_iterator& operator++()
         {
-            base_iterator::operator++();
-            return *this;
+            return static_cast<json_reverse_iterator&>(base_iterator::operator++());
         }
 
         /// post-decrement (it--)
         json_reverse_iterator operator--(int)
         {
-            return base_iterator::operator--(1);
+            return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
         }
 
         /// pre-decrement (--it)
         json_reverse_iterator& operator--()
         {
-            base_iterator::operator--();
-            return *this;
+            return static_cast<json_reverse_iterator&>(base_iterator::operator--());
         }
 
         /// add to iterator
         json_reverse_iterator& operator+=(difference_type i)
         {
-            base_iterator::operator+=(i);
-            return *this;
+            return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
         }
 
         /// add to iterator
         json_reverse_iterator operator+(difference_type i) const
         {
-            return json_reverse_iterator(base_iterator::operator+(i));
+            return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
         }
 
         /// subtract from iterator
         json_reverse_iterator operator-(difference_type i) const
         {
-            return json_reverse_iterator(base_iterator::operator-(i));
+            return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
         }
 
         /// return difference

From c4ab8f827e45cd6e6f1e80eb77ab850fa228e433 Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Tue, 30 May 2017 19:44:55 +1000
Subject: [PATCH 09/11] Change iterator category to random access

---
 src/json.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/json.hpp b/src/json.hpp
index 5c7074f4..51221207 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8015,7 +8015,7 @@ class basic_json
               typename basic_json::const_reference,
               typename basic_json::reference>::type;
         /// the category of the iterator
-        using iterator_category = std::bidirectional_iterator_tag;
+        using iterator_category = std::random_access_iterator_tag;
 
         /// default constructor
         iter_impl() = default;

From c98169d0d500e2a5f209c58b9e26f6d53787b782 Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Mon, 5 Jun 2017 21:59:17 +1000
Subject: [PATCH 10/11] Revert "Change iterator category to random access"

This reverts commit c4ab8f827e45cd6e6f1e80eb77ab850fa228e433.
---
 src/json.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/json.hpp b/src/json.hpp
index 35b57a78..3fb89ea2 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8015,7 +8015,7 @@ class basic_json
               typename basic_json::const_reference,
               typename basic_json::reference>::type;
         /// the category of the iterator
-        using iterator_category = std::random_access_iterator_tag;
+        using iterator_category = std::bidirectional_iterator_tag;
 
         /// default constructor
         iter_impl() = default;

From 0f065edff6d741383ea1639fb6bbb8605e4e88d8 Mon Sep 17 00:00:00 2001
From: HenryLee <lee0906@hotmail.com>
Date: Wed, 7 Jun 2017 18:01:01 +1000
Subject: [PATCH 11/11] Revert a change in reverse iterator to pass the test
 cases

---
 src/json.hpp                 |  2 +-
 test/src/unit-iterators2.cpp | 16 ++++++++--------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 3fb89ea2..ee525c91 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8686,7 +8686,7 @@ class basic_json
         /// access to successor
         reference operator[](difference_type n) const
         {
-            return base_iterator::operator[](n);
+            return *(this->operator+(n));
         }
 
         /// return the key of an object iterator
diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp
index 2be349b3..ae8ce687 100644
--- a/test/src/unit-iterators2.cpp
+++ b/test/src/unit-iterators2.cpp
@@ -833,15 +833,15 @@ TEST_CASE("iterators 2")
                     auto it = j_object.rbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
-                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
                 }
                 {
                     auto it = j_object.crbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
-                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
                 }
             }
 
@@ -873,15 +873,15 @@ TEST_CASE("iterators 2")
                     auto it = j_null.rbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
-                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
+                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
+                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
                 }
                 {
                     auto it = j_null.crbegin();
                     CHECK_THROWS_AS(it[0], json::invalid_iterator);
                     CHECK_THROWS_AS(it[1], json::invalid_iterator);
-                    //CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
-                    //CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
+                    CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
+                    CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
                 }
             }