From 19043d2003c77b6a01f335d259b302097619ad85 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 13 Jan 2015 19:07:53 +0100
Subject: [PATCH] this should fix #28

---
 Makefile.am        |   4 +-
 header_only/json.h | 100 ++++++++++++++++++++++++++++++++++++++-------
 src/json.cc        | 100 ++++++++++++++++++++++++++++++++++++++-------
 test/json_unit.cc  |  28 +++++++++++--
 4 files changed, 197 insertions(+), 35 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index ce5efd17..eda21026 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,6 +34,8 @@ parser:
 	make CXXFLAGS="" json_parser
 
 header_only/json.h: $(CORE_SOURCES)
-	cat $(CORE_SOURCES) | $(SED) 's/#include "json.h"//' > header_only/json.h
+	$(AM_V_GEN)
+	$(AM_V_at)mkdir -p header_only
+	$(AM_V_at)cat $(CORE_SOURCES) | $(SED) 's/#include "json.h"//' > header_only/json.h
 
 BUILT_SOURCES = header_only/json.h
diff --git a/header_only/json.h b/header_only/json.h
index dc741f7d..78a36820 100644
--- a/header_only/json.h
+++ b/header_only/json.h
@@ -1898,11 +1898,25 @@ json::iterator::iterator(json* j) : object_(j)
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::iterator(object_->value_.array->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::iterator(object_->value_.object->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -1913,11 +1927,25 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::iterator(*(o.vi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::iterator(*(o.oi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -2091,11 +2119,25 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -2106,11 +2148,25 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::const_iterator(*(o.vi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::const_iterator(*(o.oi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -2121,11 +2177,25 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::const_iterator(*(o.vi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::const_iterator(*(o.oi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            }
         }
     }
 }
diff --git a/src/json.cc b/src/json.cc
index 2d67f81e..8370a735 100644
--- a/src/json.cc
+++ b/src/json.cc
@@ -1446,11 +1446,25 @@ json::iterator::iterator(json* j) : object_(j)
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::iterator(object_->value_.array->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::iterator(object_->value_.object->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -1461,11 +1475,25 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::iterator(*(o.vi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::iterator(*(o.oi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -1639,11 +1667,25 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -1654,11 +1696,25 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::const_iterator(*(o.vi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::const_iterator(*(o.oi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            }
         }
     }
 }
@@ -1669,11 +1725,25 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
     {
         if (object_->type_ == json::value_type::array)
         {
-            vi_ = new array_t::const_iterator(*(o.vi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                vi_ = new array_t::const_iterator(object_->value_.array->begin());
+            }
         }
-        if (object_->type_ == json::value_type::object)
+        else if (object_->type_ == json::value_type::object)
         {
-            oi_ = new object_t::const_iterator(*(o.oi_));
+            if (object_->empty())
+            {
+                object_ = nullptr;
+            }
+            else
+            {
+                oi_ = new object_t::const_iterator(object_->value_.object->begin());
+            }
         }
     }
 }
diff --git a/test/json_unit.cc b/test/json_unit.cc
index 63c955d1..e2f30eec 100644
--- a/test/json_unit.cc
+++ b/test/json_unit.cc
@@ -20,8 +20,8 @@ TEST_CASE("array")
         CHECK(j.dump() == "[]");
 
         // iterators
-        CHECK(j.begin() != j.end());
-        CHECK(j.cbegin() != j.cend());
+        CHECK(j.begin() == j.end());
+        CHECK(j.cbegin() == j.cend());
 
         // container members
         CHECK(j.size() == 0);
@@ -291,6 +291,16 @@ TEST_CASE("array")
         json j_should_be_an_array = { {"foo", "bar"}, {"baz", "bat"} };
         CHECK(j_should_be_an_array.type() == json::value_type::object);
     }
+
+    SECTION("Iterators and empty arrays")
+    {
+        json j(json::value_type::array);
+        for (json::iterator it = j.begin(); it != j.end(); ++it) {}
+        for (json::const_iterator it = j.begin(); it != j.end(); ++it) {}
+        for (json::const_iterator it = j.cbegin(); it != j.cend(); ++it) {}
+        for (auto el : j) {}
+        for (const auto el : j) {}
+    }
 }
 
 TEST_CASE("object")
@@ -308,8 +318,8 @@ TEST_CASE("object")
         CHECK(j.dump() == "{}");
 
         // iterators
-        CHECK(j.begin() != j.end());
-        CHECK(j.cbegin() != j.cend());
+        CHECK(j.begin() == j.end());
+        CHECK(j.cbegin() == j.cend());
 
         // container members
         CHECK(j.size() == 0);
@@ -674,6 +684,16 @@ TEST_CASE("object")
             CHECK(element.get<int>() >= 0);
         }
     }
+
+    SECTION("Iterators and empty objects")
+    {
+        json j(json::value_type::object);
+        for (json::iterator it = j.begin(); it != j.end(); ++it) {}
+        for (json::const_iterator it = j.begin(); it != j.end(); ++it) {}
+        for (json::const_iterator it = j.cbegin(); it != j.cend(); ++it) {}
+        for (auto el : j) {}
+        for (const auto el : j) {}
+    }
 }
 
 TEST_CASE("null")