diff --git a/.gitignore b/.gitignore
index 9aacce92..fead35ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 .deps
 utf8_test
+
+json_unit
diff --git a/src/json.hpp b/src/json.hpp
index 930db7e6..9ac648c0 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -93,7 +93,10 @@ class basic_json
     using iterator = basic_json::iterator;
     /// a const iterator for a basic_json container
     using const_iterator = basic_json::const_iterator;
-
+    /// a reverse iterator for a basic_json container
+    using reverse_iterator = std::reverse_iterator<iterator>;
+    /// a const reverse iterator for a basic_json container
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
     ///////////////////////////
     // JSON value data types //
@@ -264,6 +267,8 @@ class basic_json
               std::enable_if<
                   not std::is_same<V, basic_json::iterator>::value and
                   not std::is_same<V, basic_json::const_iterator>::value and
+                  not std::is_same<V, basic_json::reverse_iterator>::value and
+                  not std::is_same<V, basic_json::const_reverse_iterator>::value and
                   not std::is_same<V, typename array_t::iterator>::value and
                   not std::is_same<V, typename array_t::const_iterator>::value and
                   std::is_constructible<basic_json, typename V::value_type>::value, int>::type
@@ -822,6 +827,30 @@ class basic_json
         return result;
     }
 
+    /// returns a reverse iterator to the beginning
+    inline reverse_iterator rbegin() noexcept
+    {
+        return reverse_iterator(end());
+    }
+
+    /// returns a reverse iterator to the end
+    inline reverse_iterator rend() noexcept
+    {
+        return reverse_iterator(begin());
+    }
+
+    /// returns a reverse iterator to the beginning
+    inline const_reverse_iterator crbegin() const noexcept
+    {
+        return const_reverse_iterator(cend());
+    }
+
+    /// returns a reverse iterator to the end
+    inline const_reverse_iterator crend() const noexcept
+    {
+        return const_reverse_iterator(cbegin());
+    }
+
 
     //////////////
     // capacity //
@@ -2490,359 +2519,715 @@ class basic_json
             // remember the begin of the token
             m_start = m_cursor;
 
-            
-    {
-        char yych;
-        unsigned int yyaccept = 0;
-        static const unsigned char yybm[] = {
-              0,  64,  64,  64,  64,  64,  64,  64, 
-             64,  96,  96,  64,  64,  96,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             96,  64,   0,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-            192, 192, 192, 192, 192, 192, 192, 192, 
-            192, 192,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,   0,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-             64,  64,  64,  64,  64,  64,  64,  64, 
-        };
 
-        yych = *m_cursor;
-        if (yych <= '9') {
-            if (yych <= ' ') {
-                if (yych <= '\n') {
-                    if (yych <= 0x00) goto json_parser_27;
-                    if (yych <= 0x08) goto json_parser_29;
-                    if (yych <= '\t') goto json_parser_3;
-                    goto json_parser_4;
-                } else {
-                    if (yych == '\r') goto json_parser_3;
-                    if (yych <= 0x1F) goto json_parser_29;
-                    goto json_parser_3;
+            {
+                char yych;
+                unsigned int yyaccept = 0;
+                static const unsigned char yybm[] =
+                {
+                    0,  64,  64,  64,  64,  64,  64,  64,
+                    64,  96,  96,  64,  64,  96,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    96,  64,   0,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    192, 192, 192, 192, 192, 192, 192, 192,
+                    192, 192,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,   0,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                    64,  64,  64,  64,  64,  64,  64,  64,
+                };
+
+                yych = *m_cursor;
+                if (yych <= '9')
+                {
+                    if (yych <= ' ')
+                    {
+                        if (yych <= '\n')
+                        {
+                            if (yych <= 0x00)
+                            {
+                                goto json_parser_27;
+                            }
+                            if (yych <= 0x08)
+                            {
+                                goto json_parser_29;
+                            }
+                            if (yych <= '\t')
+                            {
+                                goto json_parser_3;
+                            }
+                            goto json_parser_4;
+                        }
+                        else
+                        {
+                            if (yych == '\r')
+                            {
+                                goto json_parser_3;
+                            }
+                            if (yych <= 0x1F)
+                            {
+                                goto json_parser_29;
+                            }
+                            goto json_parser_3;
+                        }
+                    }
+                    else
+                    {
+                        if (yych <= ',')
+                        {
+                            if (yych == '"')
+                            {
+                                goto json_parser_26;
+                            }
+                            if (yych <= '+')
+                            {
+                                goto json_parser_29;
+                            }
+                            goto json_parser_14;
+                        }
+                        else
+                        {
+                            if (yych <= '-')
+                            {
+                                goto json_parser_22;
+                            }
+                            if (yych <= '/')
+                            {
+                                goto json_parser_29;
+                            }
+                            if (yych <= '0')
+                            {
+                                goto json_parser_23;
+                            }
+                            goto json_parser_25;
+                        }
+                    }
                 }
-            } else {
-                if (yych <= ',') {
-                    if (yych == '"') goto json_parser_26;
-                    if (yych <= '+') goto json_parser_29;
-                    goto json_parser_14;
-                } else {
-                    if (yych <= '-') goto json_parser_22;
-                    if (yych <= '/') goto json_parser_29;
-                    if (yych <= '0') goto json_parser_23;
-                    goto json_parser_25;
+                else
+                {
+                    if (yych <= 'm')
+                    {
+                        if (yych <= '\\')
+                        {
+                            if (yych <= ':')
+                            {
+                                goto json_parser_16;
+                            }
+                            if (yych == '[')
+                            {
+                                goto json_parser_6;
+                            }
+                            goto json_parser_29;
+                        }
+                        else
+                        {
+                            if (yych <= ']')
+                            {
+                                goto json_parser_8;
+                            }
+                            if (yych == 'f')
+                            {
+                                goto json_parser_21;
+                            }
+                            goto json_parser_29;
+                        }
+                    }
+                    else
+                    {
+                        if (yych <= 'z')
+                        {
+                            if (yych <= 'n')
+                            {
+                                goto json_parser_18;
+                            }
+                            if (yych == 't')
+                            {
+                                goto json_parser_20;
+                            }
+                            goto json_parser_29;
+                        }
+                        else
+                        {
+                            if (yych <= '{')
+                            {
+                                goto json_parser_10;
+                            }
+                            if (yych == '}')
+                            {
+                                goto json_parser_12;
+                            }
+                            goto json_parser_29;
+                        }
+                    }
                 }
-            }
-        } else {
-            if (yych <= 'm') {
-                if (yych <= '\\') {
-                    if (yych <= ':') goto json_parser_16;
-                    if (yych == '[') goto json_parser_6;
-                    goto json_parser_29;
-                } else {
-                    if (yych <= ']') goto json_parser_8;
-                    if (yych == 'f') goto json_parser_21;
-                    goto json_parser_29;
-                }
-            } else {
-                if (yych <= 'z') {
-                    if (yych <= 'n') goto json_parser_18;
-                    if (yych == 't') goto json_parser_20;
-                    goto json_parser_29;
-                } else {
-                    if (yych <= '{') goto json_parser_10;
-                    if (yych == '}') goto json_parser_12;
-                    goto json_parser_29;
-                }
-            }
-        }
 json_parser_2:
-        { return scan(); }
+                {
+                    return scan();
+                }
 json_parser_3:
-        yych = *++m_cursor;
-        goto json_parser_5;
+                yych = *++m_cursor;
+                goto json_parser_5;
 json_parser_4:
-        ++m_cursor;
-        yych = *m_cursor;
+                ++m_cursor;
+                yych = *m_cursor;
 json_parser_5:
-        if (yybm[0+yych] & 32) {
-            goto json_parser_4;
-        }
-        goto json_parser_2;
+                if (yybm[0 + yych] & 32)
+                {
+                    goto json_parser_4;
+                }
+                goto json_parser_2;
 json_parser_6:
-        ++m_cursor;
-        { return token_type::begin_array; }
+                ++m_cursor;
+                {
+                    return token_type::begin_array;
+                }
 json_parser_8:
-        ++m_cursor;
-        { return token_type::end_array; }
+                ++m_cursor;
+                {
+                    return token_type::end_array;
+                }
 json_parser_10:
-        ++m_cursor;
-        { return token_type::begin_object; }
+                ++m_cursor;
+                {
+                    return token_type::begin_object;
+                }
 json_parser_12:
-        ++m_cursor;
-        { return token_type::end_object; }
+                ++m_cursor;
+                {
+                    return token_type::end_object;
+                }
 json_parser_14:
-        ++m_cursor;
-        { return token_type::value_separator; }
+                ++m_cursor;
+                {
+                    return token_type::value_separator;
+                }
 json_parser_16:
-        ++m_cursor;
-        { return token_type::name_separator; }
+                ++m_cursor;
+                {
+                    return token_type::name_separator;
+                }
 json_parser_18:
-        yyaccept = 0;
-        yych = *(m_marker = ++m_cursor);
-        if (yych == 'u') goto json_parser_59;
+                yyaccept = 0;
+                yych = *(m_marker = ++m_cursor);
+                if (yych == 'u')
+                {
+                    goto json_parser_59;
+                }
 json_parser_19:
-        { return token_type::parse_error; }
+                {
+                    return token_type::parse_error;
+                }
 json_parser_20:
-        yyaccept = 0;
-        yych = *(m_marker = ++m_cursor);
-        if (yych == 'r') goto json_parser_55;
-        goto json_parser_19;
+                yyaccept = 0;
+                yych = *(m_marker = ++m_cursor);
+                if (yych == 'r')
+                {
+                    goto json_parser_55;
+                }
+                goto json_parser_19;
 json_parser_21:
-        yyaccept = 0;
-        yych = *(m_marker = ++m_cursor);
-        if (yych == 'a') goto json_parser_50;
-        goto json_parser_19;
+                yyaccept = 0;
+                yych = *(m_marker = ++m_cursor);
+                if (yych == 'a')
+                {
+                    goto json_parser_50;
+                }
+                goto json_parser_19;
 json_parser_22:
-        yych = *++m_cursor;
-        if (yych <= '/') goto json_parser_19;
-        if (yych <= '0') goto json_parser_49;
-        if (yych <= '9') goto json_parser_40;
-        goto json_parser_19;
+                yych = *++m_cursor;
+                if (yych <= '/')
+                {
+                    goto json_parser_19;
+                }
+                if (yych <= '0')
+                {
+                    goto json_parser_49;
+                }
+                if (yych <= '9')
+                {
+                    goto json_parser_40;
+                }
+                goto json_parser_19;
 json_parser_23:
-        yyaccept = 1;
-        yych = *(m_marker = ++m_cursor);
-        if (yych <= 'D') {
-            if (yych == '.') goto json_parser_42;
-        } else {
-            if (yych <= 'E') goto json_parser_43;
-            if (yych == 'e') goto json_parser_43;
-        }
+                yyaccept = 1;
+                yych = *(m_marker = ++m_cursor);
+                if (yych <= 'D')
+                {
+                    if (yych == '.')
+                    {
+                        goto json_parser_42;
+                    }
+                }
+                else
+                {
+                    if (yych <= 'E')
+                    {
+                        goto json_parser_43;
+                    }
+                    if (yych == 'e')
+                    {
+                        goto json_parser_43;
+                    }
+                }
 json_parser_24:
-        { return token_type::value_number; }
+                {
+                    return token_type::value_number;
+                }
 json_parser_25:
-        yyaccept = 1;
-        yych = *(m_marker = ++m_cursor);
-        goto json_parser_41;
+                yyaccept = 1;
+                yych = *(m_marker = ++m_cursor);
+                goto json_parser_41;
 json_parser_26:
-        yyaccept = 0;
-        yych = *(m_marker = ++m_cursor);
-        if (yych <= 0x00) goto json_parser_19;
-        goto json_parser_31;
+                yyaccept = 0;
+                yych = *(m_marker = ++m_cursor);
+                if (yych <= 0x00)
+                {
+                    goto json_parser_19;
+                }
+                goto json_parser_31;
 json_parser_27:
-        ++m_cursor;
-        { return token_type::end_of_input; }
+                ++m_cursor;
+                {
+                    return token_type::end_of_input;
+                }
 json_parser_29:
-        yych = *++m_cursor;
-        goto json_parser_19;
+                yych = *++m_cursor;
+                goto json_parser_19;
 json_parser_30:
-        ++m_cursor;
-        yych = *m_cursor;
+                ++m_cursor;
+                yych = *m_cursor;
 json_parser_31:
-        if (yybm[0+yych] & 64) {
-            goto json_parser_30;
-        }
-        if (yych <= 0x00) goto json_parser_32;
-        if (yych <= '"') goto json_parser_34;
-        goto json_parser_33;
-json_parser_32:
-        m_cursor = m_marker;
-        if (yyaccept == 0) {
-            goto json_parser_19;
-        } else {
-            goto json_parser_24;
-        }
-json_parser_33:
-        ++m_cursor;
-        yych = *m_cursor;
-        if (yych <= 'e') {
-            if (yych <= '/') {
-                if (yych == '"') goto json_parser_30;
-                if (yych <= '.') goto json_parser_32;
-                goto json_parser_30;
-            } else {
-                if (yych <= '\\') {
-                    if (yych <= '[') goto json_parser_32;
+                if (yybm[0 + yych] & 64)
+                {
                     goto json_parser_30;
-                } else {
-                    if (yych == 'b') goto json_parser_30;
+                }
+                if (yych <= 0x00)
+                {
                     goto json_parser_32;
                 }
-            }
-        } else {
-            if (yych <= 'q') {
-                if (yych <= 'f') goto json_parser_30;
-                if (yych == 'n') goto json_parser_30;
-                goto json_parser_32;
-            } else {
-                if (yych <= 's') {
-                    if (yych <= 'r') goto json_parser_30;
-                    goto json_parser_32;
-                } else {
-                    if (yych <= 't') goto json_parser_30;
-                    if (yych <= 'u') goto json_parser_36;
-                    goto json_parser_32;
+                if (yych <= '"')
+                {
+                    goto json_parser_34;
+                }
+                goto json_parser_33;
+json_parser_32:
+                m_cursor = m_marker;
+                if (yyaccept == 0)
+                {
+                    goto json_parser_19;
+                }
+                else
+                {
+                    goto json_parser_24;
+                }
+json_parser_33:
+                ++m_cursor;
+                yych = *m_cursor;
+                if (yych <= 'e')
+                {
+                    if (yych <= '/')
+                    {
+                        if (yych == '"')
+                        {
+                            goto json_parser_30;
+                        }
+                        if (yych <= '.')
+                        {
+                            goto json_parser_32;
+                        }
+                        goto json_parser_30;
+                    }
+                    else
+                    {
+                        if (yych <= '\\')
+                        {
+                            if (yych <= '[')
+                            {
+                                goto json_parser_32;
+                            }
+                            goto json_parser_30;
+                        }
+                        else
+                        {
+                            if (yych == 'b')
+                            {
+                                goto json_parser_30;
+                            }
+                            goto json_parser_32;
+                        }
+                    }
+                }
+                else
+                {
+                    if (yych <= 'q')
+                    {
+                        if (yych <= 'f')
+                        {
+                            goto json_parser_30;
+                        }
+                        if (yych == 'n')
+                        {
+                            goto json_parser_30;
+                        }
+                        goto json_parser_32;
+                    }
+                    else
+                    {
+                        if (yych <= 's')
+                        {
+                            if (yych <= 'r')
+                            {
+                                goto json_parser_30;
+                            }
+                            goto json_parser_32;
+                        }
+                        else
+                        {
+                            if (yych <= 't')
+                            {
+                                goto json_parser_30;
+                            }
+                            if (yych <= 'u')
+                            {
+                                goto json_parser_36;
+                            }
+                            goto json_parser_32;
+                        }
+                    }
                 }
-            }
-        }
 json_parser_34:
-        ++m_cursor;
-        { return token_type::value_string; }
+                ++m_cursor;
+                {
+                    return token_type::value_string;
+                }
 json_parser_36:
-        ++m_cursor;
-        yych = *m_cursor;
-        if (yych <= '@') {
-            if (yych <= '/') goto json_parser_32;
-            if (yych >= ':') goto json_parser_32;
-        } else {
-            if (yych <= 'F') goto json_parser_37;
-            if (yych <= '`') goto json_parser_32;
-            if (yych >= 'g') goto json_parser_32;
-        }
+                ++m_cursor;
+                yych = *m_cursor;
+                if (yych <= '@')
+                {
+                    if (yych <= '/')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych >= ':')
+                    {
+                        goto json_parser_32;
+                    }
+                }
+                else
+                {
+                    if (yych <= 'F')
+                    {
+                        goto json_parser_37;
+                    }
+                    if (yych <= '`')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych >= 'g')
+                    {
+                        goto json_parser_32;
+                    }
+                }
 json_parser_37:
-        ++m_cursor;
-        yych = *m_cursor;
-        if (yych <= '@') {
-            if (yych <= '/') goto json_parser_32;
-            if (yych >= ':') goto json_parser_32;
-        } else {
-            if (yych <= 'F') goto json_parser_38;
-            if (yych <= '`') goto json_parser_32;
-            if (yych >= 'g') goto json_parser_32;
-        }
+                ++m_cursor;
+                yych = *m_cursor;
+                if (yych <= '@')
+                {
+                    if (yych <= '/')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych >= ':')
+                    {
+                        goto json_parser_32;
+                    }
+                }
+                else
+                {
+                    if (yych <= 'F')
+                    {
+                        goto json_parser_38;
+                    }
+                    if (yych <= '`')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych >= 'g')
+                    {
+                        goto json_parser_32;
+                    }
+                }
 json_parser_38:
-        ++m_cursor;
-        yych = *m_cursor;
-        if (yych <= '@') {
-            if (yych <= '/') goto json_parser_32;
-            if (yych >= ':') goto json_parser_32;
-        } else {
-            if (yych <= 'F') goto json_parser_39;
-            if (yych <= '`') goto json_parser_32;
-            if (yych >= 'g') goto json_parser_32;
-        }
+                ++m_cursor;
+                yych = *m_cursor;
+                if (yych <= '@')
+                {
+                    if (yych <= '/')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych >= ':')
+                    {
+                        goto json_parser_32;
+                    }
+                }
+                else
+                {
+                    if (yych <= 'F')
+                    {
+                        goto json_parser_39;
+                    }
+                    if (yych <= '`')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych >= 'g')
+                    {
+                        goto json_parser_32;
+                    }
+                }
 json_parser_39:
-        ++m_cursor;
-        yych = *m_cursor;
-        if (yych <= '@') {
-            if (yych <= '/') goto json_parser_32;
-            if (yych <= '9') goto json_parser_30;
-            goto json_parser_32;
-        } else {
-            if (yych <= 'F') goto json_parser_30;
-            if (yych <= '`') goto json_parser_32;
-            if (yych <= 'f') goto json_parser_30;
-            goto json_parser_32;
-        }
+                ++m_cursor;
+                yych = *m_cursor;
+                if (yych <= '@')
+                {
+                    if (yych <= '/')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto json_parser_30;
+                    }
+                    goto json_parser_32;
+                }
+                else
+                {
+                    if (yych <= 'F')
+                    {
+                        goto json_parser_30;
+                    }
+                    if (yych <= '`')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych <= 'f')
+                    {
+                        goto json_parser_30;
+                    }
+                    goto json_parser_32;
+                }
 json_parser_40:
-        yyaccept = 1;
-        m_marker = ++m_cursor;
-        yych = *m_cursor;
+                yyaccept = 1;
+                m_marker = ++m_cursor;
+                yych = *m_cursor;
 json_parser_41:
-        if (yybm[0+yych] & 128) {
-            goto json_parser_40;
-        }
-        if (yych <= 'D') {
-            if (yych != '.') goto json_parser_24;
-        } else {
-            if (yych <= 'E') goto json_parser_43;
-            if (yych == 'e') goto json_parser_43;
-            goto json_parser_24;
-        }
+                if (yybm[0 + yych] & 128)
+                {
+                    goto json_parser_40;
+                }
+                if (yych <= 'D')
+                {
+                    if (yych != '.')
+                    {
+                        goto json_parser_24;
+                    }
+                }
+                else
+                {
+                    if (yych <= 'E')
+                    {
+                        goto json_parser_43;
+                    }
+                    if (yych == 'e')
+                    {
+                        goto json_parser_43;
+                    }
+                    goto json_parser_24;
+                }
 json_parser_42:
-        yych = *++m_cursor;
-        if (yych <= '/') goto json_parser_32;
-        if (yych <= '9') goto json_parser_47;
-        goto json_parser_32;
+                yych = *++m_cursor;
+                if (yych <= '/')
+                {
+                    goto json_parser_32;
+                }
+                if (yych <= '9')
+                {
+                    goto json_parser_47;
+                }
+                goto json_parser_32;
 json_parser_43:
-        yych = *++m_cursor;
-        if (yych <= ',') {
-            if (yych != '+') goto json_parser_32;
-        } else {
-            if (yych <= '-') goto json_parser_44;
-            if (yych <= '/') goto json_parser_32;
-            if (yych <= '9') goto json_parser_45;
-            goto json_parser_32;
-        }
+                yych = *++m_cursor;
+                if (yych <= ',')
+                {
+                    if (yych != '+')
+                    {
+                        goto json_parser_32;
+                    }
+                }
+                else
+                {
+                    if (yych <= '-')
+                    {
+                        goto json_parser_44;
+                    }
+                    if (yych <= '/')
+                    {
+                        goto json_parser_32;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto json_parser_45;
+                    }
+                    goto json_parser_32;
+                }
 json_parser_44:
-        yych = *++m_cursor;
-        if (yych <= '/') goto json_parser_32;
-        if (yych >= ':') goto json_parser_32;
+                yych = *++m_cursor;
+                if (yych <= '/')
+                {
+                    goto json_parser_32;
+                }
+                if (yych >= ':')
+                {
+                    goto json_parser_32;
+                }
 json_parser_45:
-        ++m_cursor;
-        yych = *m_cursor;
-        if (yych <= '/') goto json_parser_24;
-        if (yych <= '9') goto json_parser_45;
-        goto json_parser_24;
+                ++m_cursor;
+                yych = *m_cursor;
+                if (yych <= '/')
+                {
+                    goto json_parser_24;
+                }
+                if (yych <= '9')
+                {
+                    goto json_parser_45;
+                }
+                goto json_parser_24;
 json_parser_47:
-        yyaccept = 1;
-        m_marker = ++m_cursor;
-        yych = *m_cursor;
-        if (yych <= 'D') {
-            if (yych <= '/') goto json_parser_24;
-            if (yych <= '9') goto json_parser_47;
-            goto json_parser_24;
-        } else {
-            if (yych <= 'E') goto json_parser_43;
-            if (yych == 'e') goto json_parser_43;
-            goto json_parser_24;
-        }
+                yyaccept = 1;
+                m_marker = ++m_cursor;
+                yych = *m_cursor;
+                if (yych <= 'D')
+                {
+                    if (yych <= '/')
+                    {
+                        goto json_parser_24;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto json_parser_47;
+                    }
+                    goto json_parser_24;
+                }
+                else
+                {
+                    if (yych <= 'E')
+                    {
+                        goto json_parser_43;
+                    }
+                    if (yych == 'e')
+                    {
+                        goto json_parser_43;
+                    }
+                    goto json_parser_24;
+                }
 json_parser_49:
-        yyaccept = 1;
-        yych = *(m_marker = ++m_cursor);
-        if (yych <= 'D') {
-            if (yych == '.') goto json_parser_42;
-            goto json_parser_24;
-        } else {
-            if (yych <= 'E') goto json_parser_43;
-            if (yych == 'e') goto json_parser_43;
-            goto json_parser_24;
-        }
+                yyaccept = 1;
+                yych = *(m_marker = ++m_cursor);
+                if (yych <= 'D')
+                {
+                    if (yych == '.')
+                    {
+                        goto json_parser_42;
+                    }
+                    goto json_parser_24;
+                }
+                else
+                {
+                    if (yych <= 'E')
+                    {
+                        goto json_parser_43;
+                    }
+                    if (yych == 'e')
+                    {
+                        goto json_parser_43;
+                    }
+                    goto json_parser_24;
+                }
 json_parser_50:
-        yych = *++m_cursor;
-        if (yych != 'l') goto json_parser_32;
-        yych = *++m_cursor;
-        if (yych != 's') goto json_parser_32;
-        yych = *++m_cursor;
-        if (yych != 'e') goto json_parser_32;
-        ++m_cursor;
-        { return token_type::literal_false; }
+                yych = *++m_cursor;
+                if (yych != 'l')
+                {
+                    goto json_parser_32;
+                }
+                yych = *++m_cursor;
+                if (yych != 's')
+                {
+                    goto json_parser_32;
+                }
+                yych = *++m_cursor;
+                if (yych != 'e')
+                {
+                    goto json_parser_32;
+                }
+                ++m_cursor;
+                {
+                    return token_type::literal_false;
+                }
 json_parser_55:
-        yych = *++m_cursor;
-        if (yych != 'u') goto json_parser_32;
-        yych = *++m_cursor;
-        if (yych != 'e') goto json_parser_32;
-        ++m_cursor;
-        { return token_type::literal_true; }
+                yych = *++m_cursor;
+                if (yych != 'u')
+                {
+                    goto json_parser_32;
+                }
+                yych = *++m_cursor;
+                if (yych != 'e')
+                {
+                    goto json_parser_32;
+                }
+                ++m_cursor;
+                {
+                    return token_type::literal_true;
+                }
 json_parser_59:
-        yych = *++m_cursor;
-        if (yych != 'l') goto json_parser_32;
-        yych = *++m_cursor;
-        if (yych != 'l') goto json_parser_32;
-        ++m_cursor;
-        { return token_type::literal_null; }
-    }
+                yych = *++m_cursor;
+                if (yych != 'l')
+                {
+                    goto json_parser_32;
+                }
+                yych = *++m_cursor;
+                if (yych != 'l')
+                {
+                    goto json_parser_32;
+                }
+                ++m_cursor;
+                {
+                    return token_type::literal_null;
+                }
+            }
 
         }
 
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 9c1cf1b3..f59985eb 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -93,7 +93,10 @@ class basic_json
     using iterator = basic_json::iterator;
     /// a const iterator for a basic_json container
     using const_iterator = basic_json::const_iterator;
-
+    /// a reverse iterator for a basic_json container
+    using reverse_iterator = std::reverse_iterator<iterator>;
+    /// a const reverse iterator for a basic_json container
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
     ///////////////////////////
     // JSON value data types //
@@ -264,6 +267,8 @@ class basic_json
               std::enable_if<
                   not std::is_same<V, basic_json::iterator>::value and
                   not std::is_same<V, basic_json::const_iterator>::value and
+                  not std::is_same<V, basic_json::reverse_iterator>::value and
+                  not std::is_same<V, basic_json::const_reverse_iterator>::value and
                   not std::is_same<V, typename array_t::iterator>::value and
                   not std::is_same<V, typename array_t::const_iterator>::value and
                   std::is_constructible<basic_json, typename V::value_type>::value, int>::type
@@ -822,6 +827,30 @@ class basic_json
         return result;
     }
 
+    /// returns a reverse iterator to the beginning
+    inline reverse_iterator rbegin() noexcept
+    {
+        return reverse_iterator(end());
+    }
+
+    /// returns a reverse iterator to the end
+    inline reverse_iterator rend() noexcept
+    {
+        return reverse_iterator(begin());
+    }
+
+    /// returns a reverse iterator to the beginning
+    inline const_reverse_iterator crbegin() const noexcept
+    {
+        return const_reverse_iterator(cend());
+    }
+
+    /// returns a reverse iterator to the end
+    inline const_reverse_iterator crend() const noexcept
+    {
+        return const_reverse_iterator(cbegin());
+    }
+
 
     //////////////
     // capacity //
diff --git a/test/unit.cpp b/test/unit.cpp
index f1824544..57501554 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -2420,6 +2420,81 @@ TEST_CASE("iterators")
             CHECK(it != j_const.cend());
             CHECK(*it == j_const);
         }
+
+        SECTION("json + rbegin/rend")
+        {
+            json::reverse_iterator it = j.rbegin();
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            it--;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            --it;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+        }
+
+        SECTION("json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j.crbegin();
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            it--;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            --it;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+        }
+
+        SECTION("const json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j_const.crbegin();
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            it++;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            it--;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            ++it;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            --it;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+        }
     }
 
     SECTION("string")
@@ -2526,6 +2601,81 @@ TEST_CASE("iterators")
             CHECK(it != j_const.cend());
             CHECK(*it == j_const);
         }
+
+        SECTION("json + rbegin/rend")
+        {
+            json::reverse_iterator it = j.rbegin();
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            it--;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            --it;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+        }
+
+        SECTION("json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j.crbegin();
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            it--;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            --it;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+        }
+
+        SECTION("const json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j_const.crbegin();
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            it++;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            it--;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            ++it;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            --it;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+        }
     }
 
     SECTION("array")
@@ -2540,14 +2690,17 @@ TEST_CASE("iterators")
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j[0]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j[1]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j[2]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2561,14 +2714,17 @@ TEST_CASE("iterators")
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j_const[0]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j_const[1]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j_const[2]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2582,14 +2738,17 @@ TEST_CASE("iterators")
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j[0]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j[1]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j[2]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2598,19 +2757,94 @@ TEST_CASE("iterators")
 
         SECTION("const json + cbegin/cend")
         {
-            json::const_iterator it_begin = j.cbegin();
-            json::const_iterator it_end = j.cend();
+            json::const_iterator it_begin = j_const.cbegin();
+            json::const_iterator it_end = j_const.cend();
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j[0]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j[1]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j[2]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it == it_end);
+        }
+
+        SECTION("json + rbegin/rend")
+        {
+            json::reverse_iterator it_begin = j.rbegin();
+            json::reverse_iterator it_end = j.rend();
+
+            auto it = it_begin;
+            CHECK(it != it_end);
+            CHECK(*it == j[2]);
+
+            it++;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j[1]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j[0]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it == it_end);
+        }
+
+        SECTION("json + crbegin/crend")
+        {
+            json::const_reverse_iterator it_begin = j.crbegin();
+            json::const_reverse_iterator it_end = j.crend();
+
+            auto it = it_begin;
+            CHECK(it != it_end);
+            CHECK(*it == j[2]);
+
+            it++;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j[1]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j[0]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it == it_end);
+        }
+
+        SECTION("const json + crbegin/crend")
+        {
+            json::const_reverse_iterator it_begin = j_const.crbegin();
+            json::const_reverse_iterator it_end = j_const.crend();
+
+            auto it = it_begin;
+            CHECK(it != it_end);
+            CHECK(*it == j[2]);
+
+            it++;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j[1]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j[0]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2620,7 +2854,7 @@ TEST_CASE("iterators")
 
     SECTION("object")
     {
-        json j = {{"one", 1}, {"two", 2}, {"three", 3}};
+        json j = {{"A", 1}, {"B", 2}, {"C", 3}};
         json j_const(j);
 
         SECTION("json + begin/end")
@@ -2630,14 +2864,17 @@ TEST_CASE("iterators")
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j["A"]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j["B"]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j["C"]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2651,14 +2888,17 @@ TEST_CASE("iterators")
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j_const["A"]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j_const["B"]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j_const["C"]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2672,14 +2912,17 @@ TEST_CASE("iterators")
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j["A"]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j["B"]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j["C"]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2688,19 +2931,94 @@ TEST_CASE("iterators")
 
         SECTION("const json + cbegin/cend")
         {
-            json::const_iterator it_begin = j.cbegin();
-            json::const_iterator it_end = j.cend();
+            json::const_iterator it_begin = j_const.cbegin();
+            json::const_iterator it_end = j_const.cend();
 
             auto it = it_begin;
             CHECK(it != it_end);
+            CHECK(*it == j_const["A"]);
 
             it++;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j_const["B"]);
 
             ++it;
             CHECK(it != it_begin);
             CHECK(it != it_end);
+            CHECK(*it == j_const["C"]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it == it_end);
+        }
+
+        SECTION("json + rbegin/rend")
+        {
+            json::reverse_iterator it_begin = j.rbegin();
+            json::reverse_iterator it_end = j.rend();
+
+            auto it = it_begin;
+            CHECK(it != it_end);
+            CHECK(*it == j["C"]);
+
+            it++;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j["B"]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j["A"]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it == it_end);
+        }
+
+        SECTION("json + crbegin/crend")
+        {
+            json::const_reverse_iterator it_begin = j.crbegin();
+            json::const_reverse_iterator it_end = j.crend();
+
+            auto it = it_begin;
+            CHECK(it != it_end);
+            CHECK(*it == j["C"]);
+
+            it++;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j["B"]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j["A"]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it == it_end);
+        }
+
+        SECTION("const json + crbegin/crend")
+        {
+            json::const_reverse_iterator it_begin = j_const.crbegin();
+            json::const_reverse_iterator it_end = j_const.crend();
+
+            auto it = it_begin;
+            CHECK(it != it_end);
+            CHECK(*it == j["C"]);
+
+            it++;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j["B"]);
+
+            ++it;
+            CHECK(it != it_begin);
+            CHECK(it != it_end);
+            CHECK(*it == j["A"]);
 
             ++it;
             CHECK(it != it_begin);
@@ -2812,6 +3130,81 @@ TEST_CASE("iterators")
             CHECK(it != j_const.cend());
             CHECK(*it == j_const);
         }
+
+        SECTION("json + rbegin/rend")
+        {
+            json::reverse_iterator it = j.rbegin();
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            it--;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            --it;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+        }
+
+        SECTION("json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j.crbegin();
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            it--;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            --it;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+        }
+
+        SECTION("const json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j_const.crbegin();
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            it++;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            it--;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            ++it;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            --it;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+        }
     }
 
     SECTION("number (float)")
@@ -2918,6 +3311,81 @@ TEST_CASE("iterators")
             CHECK(it != j_const.cend());
             CHECK(*it == j_const);
         }
+
+        SECTION("json + rbegin/rend")
+        {
+            json::reverse_iterator it = j.rbegin();
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            it--;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.rbegin());
+            CHECK(it == j.rend());
+
+            --it;
+            CHECK(it == j.rbegin());
+            CHECK(it != j.rend());
+            CHECK(*it == j);
+        }
+
+        SECTION("json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j.crbegin();
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            it++;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            it--;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+
+            ++it;
+            CHECK(it != j.crbegin());
+            CHECK(it == j.crend());
+
+            --it;
+            CHECK(it == j.crbegin());
+            CHECK(it != j.crend());
+            CHECK(*it == j);
+        }
+
+        SECTION("const json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j_const.crbegin();
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            it++;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            it--;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+
+            ++it;
+            CHECK(it != j_const.crbegin());
+            CHECK(it == j_const.crend());
+
+            --it;
+            CHECK(it == j_const.crbegin());
+            CHECK(it != j_const.crend());
+            CHECK(*it == j_const);
+        }
     }
 
     SECTION("null")
@@ -2951,6 +3419,24 @@ TEST_CASE("iterators")
             json::const_iterator it_end = j_const.cend();
             CHECK(it_begin == it_end);
         }
+
+        SECTION("json + rbegin/rend")
+        {
+            json::reverse_iterator it = j.rbegin();
+            CHECK(it == j.rend());
+        }
+
+        SECTION("json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j.crbegin();
+            CHECK(it == j.crend());
+        }
+
+        SECTION("const json + crbegin/crend")
+        {
+            json::const_reverse_iterator it = j_const.crbegin();
+            CHECK(it == j_const.crend());
+        }
     }
 }