From 9e7941b6ba32e39a5b6100be09abd7a091ff6ebf Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 17 Feb 2015 00:22:12 +0100
Subject: [PATCH] more type adjustments

---
 src/json.hpp      | 25 ++++++++++++++-----------
 src/json.hpp.re2c | 25 ++++++++++++++-----------
 test/unit.cpp     |  1 +
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 186632f5..32b633fa 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -2529,11 +2529,11 @@ class basic_json
         };
 
         /// the char type to use in the lexer
-        using lexer_char_t = typename string_t::value_type;
+        using lexer_char_t = unsigned char;
 
         /// constructor with a given buffer
         inline lexer(const string_t& s) noexcept
-            : m_content(s.c_str())
+            : m_content(reinterpret_cast<const lexer_char_t*>(s.c_str()))
         {
             m_start = m_cursor = m_content;
             m_limit = m_content + s.size();
@@ -2552,7 +2552,7 @@ class basic_json
 
         @see <http://en.wikipedia.org/wiki/UTF-8#Sample_code>
         */
-        inline static string_t to_unicode(const size_t codepoint1, size_t codepoint2 = 0)
+        inline static string_t to_unicode(const size_t codepoint1, const size_t codepoint2 = 0)
         {
             string_t result;
 
@@ -3380,7 +3380,8 @@ basic_json_parser_59:
         /// return string representation of last read token
         inline string_t get_token() const noexcept
         {
-            return string_t(m_start, static_cast<size_t>(m_cursor - m_start));
+            return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
+                            static_cast<size_t>(m_cursor - m_start));
         }
 
         /*!
@@ -3410,7 +3411,7 @@ basic_json_parser_59:
             result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
 
             // iterate the result between the quotes
-            for (const typename string_t::value_type* i = m_start + 1; i < m_cursor - 1; ++i)
+            for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
             {
                 // process escaped characters
                 if (*i == '\\')
@@ -3468,7 +3469,8 @@ basic_json_parser_59:
                         case 'u':
                         {
                             // get code xxxx from uxxxx
-                            auto codepoint = std::strtoul(std::string(i + 1, 4).c_str(), nullptr, 16);
+                            auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
+                                                          4).c_str(), nullptr, 16);
 
                             if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
                             {
@@ -3479,7 +3481,8 @@ basic_json_parser_59:
                                 }
 
                                 // get code yyyy from uxxxx\uyyyy
-                                auto codepoint2 = std::strtoul(std::string(i + 7, 4).c_str(), nullptr, 16);
+                                auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
+                                                               (i + 7), 4).c_str(), nullptr, 16);
                                 result += to_unicode(codepoint, codepoint2);
                                 // skip the next 11 characters (xxxx\uyyyy)
                                 i += 11;
@@ -3499,7 +3502,7 @@ basic_json_parser_59:
                 {
                     // all other characters are just copied to the end of the
                     // string
-                    result.append(1, *i);
+                    result.append(1, static_cast<typename string_t::value_type>(*i));
                 }
             }
 
@@ -3526,13 +3529,13 @@ basic_json_parser_59:
         inline number_float_t get_number() const
         {
             // conversion
-            lexer_char_t* endptr;
-            const auto float_val = std::strtod(reinterpret_cast<const lexer_char_t*>(m_start),
+            typename string_t::value_type* endptr;
+            const auto float_val = std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start),
                                                &endptr);
 
             // return float_val if the whole number was translated and NAN
             // otherwise
-            return (endptr == m_cursor) ? float_val : NAN;
+            return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
         }
 
       private:
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 31d77c6b..4d1c88f2 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -2529,11 +2529,11 @@ class basic_json
         };
 
         /// the char type to use in the lexer
-        using lexer_char_t = typename string_t::value_type;
+        using lexer_char_t = unsigned char;
 
         /// constructor with a given buffer
         inline lexer(const string_t& s) noexcept
-            : m_content(s.c_str())
+            : m_content(reinterpret_cast<const lexer_char_t*>(s.c_str()))
         {
             m_start = m_cursor = m_content;
             m_limit = m_content + s.size();
@@ -2552,7 +2552,7 @@ class basic_json
 
         @see <http://en.wikipedia.org/wiki/UTF-8#Sample_code>
         */
-        inline static string_t to_unicode(const size_t codepoint1, size_t codepoint2 = 0)
+        inline static string_t to_unicode(const size_t codepoint1, const size_t codepoint2 = 0)
         {
             string_t result;
 
@@ -2729,7 +2729,8 @@ class basic_json
         /// return string representation of last read token
         inline string_t get_token() const noexcept
         {
-            return string_t(m_start, static_cast<size_t>(m_cursor - m_start));
+            return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
+                            static_cast<size_t>(m_cursor - m_start));
         }
 
         /*!
@@ -2759,7 +2760,7 @@ class basic_json
             result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
 
             // iterate the result between the quotes
-            for (const typename string_t::value_type* i = m_start + 1; i < m_cursor - 1; ++i)
+            for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
             {
                 // process escaped characters
                 if (*i == '\\')
@@ -2817,7 +2818,8 @@ class basic_json
                         case 'u':
                         {
                             // get code xxxx from uxxxx
-                            auto codepoint = std::strtoul(std::string(i + 1, 4).c_str(), nullptr, 16);
+                            auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
+                                                          4).c_str(), nullptr, 16);
 
                             if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
                             {
@@ -2828,7 +2830,8 @@ class basic_json
                                 }
 
                                 // get code yyyy from uxxxx\uyyyy
-                                auto codepoint2 = std::strtoul(std::string(i + 7, 4).c_str(), nullptr, 16);
+                                auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
+                                                               (i + 7), 4).c_str(), nullptr, 16);
                                 result += to_unicode(codepoint, codepoint2);
                                 // skip the next 11 characters (xxxx\uyyyy)
                                 i += 11;
@@ -2848,7 +2851,7 @@ class basic_json
                 {
                     // all other characters are just copied to the end of the
                     // string
-                    result.append(1, *i);
+                    result.append(1, static_cast<typename string_t::value_type>(*i));
                 }
             }
 
@@ -2875,13 +2878,13 @@ class basic_json
         inline number_float_t get_number() const
         {
             // conversion
-            lexer_char_t* endptr;
-            const auto float_val = std::strtod(reinterpret_cast<const lexer_char_t*>(m_start),
+            typename string_t::value_type* endptr;
+            const auto float_val = std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start),
                                                &endptr);
 
             // return float_val if the whole number was translated and NAN
             // otherwise
-            return (endptr == m_cursor) ? float_val : NAN;
+            return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
         }
 
       private:
diff --git a/test/unit.cpp b/test/unit.cpp
index e1a38065..5e2ff903 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -5652,6 +5652,7 @@ TEST_CASE("parser class")
                 CHECK(json::parser("\"\\u2000\"").parse().get<json::string_t>() == " ");
                 CHECK(json::parser("\"\\uFFFF\"").parse().get<json::string_t>() == "￿");
                 CHECK(json::parser("\"\\u20AC\"").parse().get<json::string_t>() == "€");
+                CHECK(json::parser("\"€\"").parse().get<json::string_t>() == "€");
 
                 CHECK(json::parse("\"\\ud80c\\udc60\"").get<json::string_t>() == u8"\U00013060");
                 CHECK(json::parse("\"\\ud83c\\udf1e\"").get<json::string_t>() == "🌞");