diff --git a/src/json.hpp b/src/json.hpp
index 361e0a32..ed3f1fb7 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -971,6 +971,13 @@ class basic_json
         value.m_type = value_t::null;
     }
 
+    /// add an object to an array
+    inline reference operator+=(basic_json&& value)
+    {
+        push_back(std::move(value));
+        return *this;
+    }
+
     /// add an object to an array
     inline void push_back(const basic_json& value)
     {
@@ -991,32 +998,12 @@ class basic_json
         m_value.array->push_back(value);
     }
 
-    /*
     /// add an object to an array
     inline reference operator+=(const basic_json& value)
     {
         push_back(value);
         return *this;
     }
-    */
-
-    /// add constructible objects to an array
-    template<class T, typename std::enable_if<std::is_constructible<basic_json, T>::value>::type = 0>
-    inline void push_back(const T& value)
-    {
-        assert(false); // not sure if function will ever be called
-        push_back(basic_json(value));
-    }
-
-    /*
-    /// add constructible objects to an array
-    template<class T, typename std::enable_if<std::is_constructible<basic_json, T>::value>::type = 0>
-    inline reference operator+=(const T& value)
-    {
-        push_back(basic_json(value));
-        return *this;
-    }
-    */
 
     /// add an object to an object
     inline void push_back(const typename object_t::value_type& value)
@@ -1047,30 +1034,6 @@ class basic_json
     }
     */
 
-    /// constructs element in-place at the end of an array
-    template <typename T, typename
-              std::enable_if<
-                  std::is_constructible<basic_json, T>::value, int>::type
-              = 0>
-    inline void emplace_back(T && arg)
-    {
-        // push_back only works for null objects or arrays
-        if (not(m_type == value_t::null or m_type == value_t::array))
-        {
-            throw std::runtime_error("cannot add element to " + type_name());
-        }
-
-        // transform null object into an array
-        if (m_type == value_t::null)
-        {
-            m_type = value_t::array;
-            m_value.array = new array_t;
-        }
-
-        // add element to array
-        m_value.array->emplace_back(std::forward<T>(arg));
-    }
-
     /// swaps the contents
     inline void swap(reference other) noexcept
     {
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 47882f39..0a91b3db 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -971,6 +971,13 @@ class basic_json
         value.m_type = value_t::null;
     }
 
+    /// add an object to an array
+    inline reference operator+=(basic_json&& value)
+    {
+        push_back(std::move(value));
+        return *this;
+    }
+
     /// add an object to an array
     inline void push_back(const basic_json& value)
     {
@@ -991,32 +998,12 @@ class basic_json
         m_value.array->push_back(value);
     }
 
-    /*
     /// add an object to an array
     inline reference operator+=(const basic_json& value)
     {
         push_back(value);
         return *this;
     }
-    */
-
-    /// add constructible objects to an array
-    template<class T, typename std::enable_if<std::is_constructible<basic_json, T>::value>::type = 0>
-    inline void push_back(const T& value)
-    {
-        assert(false); // not sure if function will ever be called
-        push_back(basic_json(value));
-    }
-
-    /*
-    /// add constructible objects to an array
-    template<class T, typename std::enable_if<std::is_constructible<basic_json, T>::value>::type = 0>
-    inline reference operator+=(const T& value)
-    {
-        push_back(basic_json(value));
-        return *this;
-    }
-    */
 
     /// add an object to an object
     inline void push_back(const typename object_t::value_type& value)
@@ -1047,30 +1034,6 @@ class basic_json
     }
     */
 
-    /// constructs element in-place at the end of an array
-    template <typename T, typename
-              std::enable_if<
-                  std::is_constructible<basic_json, T>::value, int>::type
-              = 0>
-    inline void emplace_back(T && arg)
-    {
-        // push_back only works for null objects or arrays
-        if (not(m_type == value_t::null or m_type == value_t::array))
-        {
-            throw std::runtime_error("cannot add element to " + type_name());
-        }
-
-        // transform null object into an array
-        if (m_type == value_t::null)
-        {
-            m_type = value_t::array;
-            m_value.array = new array_t;
-        }
-
-        // add element to array
-        m_value.array->emplace_back(std::forward<T>(arg));
-    }
-
     /// swaps the contents
     inline void swap(reference other) noexcept
     {
diff --git a/test/unit.cpp b/test/unit.cpp
index e6307619..79f8bb41 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -3465,6 +3465,128 @@ TEST_CASE("modifiers")
         }
     }
 
+    SECTION("push_back()")
+    {
+        SECTION("to array")
+        {
+            SECTION("json&&")
+            {
+                SECTION("null")
+                {
+                    json j;
+                    j.push_back(1);
+                    j.push_back(2);
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 2}));
+                }
+
+                SECTION("array")
+                {
+                    json j = {1, 2, 3};
+                    j.push_back("Hello");
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 2, 3, "Hello"}));
+                }
+
+                SECTION("other type")
+                {
+                    json j = 1;
+                    CHECK_THROWS_AS(j.push_back("Hello"), std::runtime_error);
+                }
+            }
+
+            SECTION("const json&")
+            {
+                SECTION("null")
+                {
+                    json j;
+                    json k(1);
+                    j.push_back(k);
+                    j.push_back(k);
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 1}));
+                }
+
+                SECTION("array")
+                {
+                    json j = {1, 2, 3};
+                    json k("Hello");
+                    j.push_back(k);
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 2, 3, "Hello"}));
+                }
+
+                SECTION("other type")
+                {
+                    json j = 1;
+                    json k("Hello");
+                    CHECK_THROWS_AS(j.push_back(k), std::runtime_error);
+                }
+            }
+        }
+    }
+
+    SECTION("operator+=")
+    {
+        SECTION("to array")
+        {
+            SECTION("json&&")
+            {
+                SECTION("null")
+                {
+                    json j;
+                    j += 1;
+                    j += 2;
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 2}));
+                }
+
+                SECTION("array")
+                {
+                    json j = {1, 2, 3};
+                    j += "Hello";
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 2, 3, "Hello"}));
+                }
+
+                SECTION("other type")
+                {
+                    json j = 1;
+                    CHECK_THROWS_AS(j += "Hello", std::runtime_error);
+                }
+            }
+
+            SECTION("const json&")
+            {
+                SECTION("null")
+                {
+                    json j;
+                    json k(1);
+                    j += k;
+                    j += k;
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 1}));
+                }
+
+                SECTION("array")
+                {
+                    json j = {1, 2, 3};
+                    json k("Hello");
+                    j += k;
+                    CHECK(j.type() == json::value_t::array);
+                    CHECK(j == json({1, 2, 3, "Hello"}));
+                }
+
+                SECTION("other type")
+                {
+                    json j = 1;
+                    json k("Hello");
+                    CHECK_THROWS_AS(j += k, std::runtime_error);
+                }
+            }
+        }
+    }
+
     SECTION("swap()")
     {
         SECTION("json")