diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index 7c0e6939b2..38572336bd 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -69,15 +69,15 @@ class binary_writer { case value_t::null: { - oa->write_character(static_cast(0xF6)); + oa->write_character(to_char_type(0xF6)); break; } case value_t::boolean: { oa->write_character(j.m_value.boolean - ? static_cast(0xF5) - : static_cast(0xF4)); + ? to_char_type(0xF5) + : to_char_type(0xF4)); break; } @@ -94,22 +94,22 @@ class binary_writer } else if (j.m_value.number_integer <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x18)); + oa->write_character(to_char_type(0x18)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x19)); + oa->write_character(to_char_type(0x19)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x1A)); + oa->write_character(to_char_type(0x1A)); write_number(static_cast(j.m_value.number_integer)); } else { - oa->write_character(static_cast(0x1B)); + oa->write_character(to_char_type(0x1B)); write_number(static_cast(j.m_value.number_integer)); } } @@ -124,22 +124,22 @@ class binary_writer } else if (positive_number <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x38)); + oa->write_character(to_char_type(0x38)); write_number(static_cast(positive_number)); } else if (positive_number <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x39)); + oa->write_character(to_char_type(0x39)); write_number(static_cast(positive_number)); } else if (positive_number <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x3A)); + oa->write_character(to_char_type(0x3A)); write_number(static_cast(positive_number)); } else { - oa->write_character(static_cast(0x3B)); + oa->write_character(to_char_type(0x3B)); write_number(static_cast(positive_number)); } } @@ -154,22 +154,22 @@ class binary_writer } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x18)); + oa->write_character(to_char_type(0x18)); write_number(static_cast(j.m_value.number_unsigned)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x19)); + oa->write_character(to_char_type(0x19)); write_number(static_cast(j.m_value.number_unsigned)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x1A)); + oa->write_character(to_char_type(0x1A)); write_number(static_cast(j.m_value.number_unsigned)); } else { - oa->write_character(static_cast(0x1B)); + oa->write_character(to_char_type(0x1B)); write_number(static_cast(j.m_value.number_unsigned)); } break; @@ -192,23 +192,23 @@ class binary_writer } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x78)); + oa->write_character(to_char_type(0x78)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x79)); + oa->write_character(to_char_type(0x79)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x7A)); + oa->write_character(to_char_type(0x7A)); write_number(static_cast(N)); } // LCOV_EXCL_START else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x7B)); + oa->write_character(to_char_type(0x7B)); write_number(static_cast(N)); } // LCOV_EXCL_STOP @@ -230,23 +230,23 @@ class binary_writer } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x98)); + oa->write_character(to_char_type(0x98)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x99)); + oa->write_character(to_char_type(0x99)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x9A)); + oa->write_character(to_char_type(0x9A)); write_number(static_cast(N)); } // LCOV_EXCL_START else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x9B)); + oa->write_character(to_char_type(0x9B)); write_number(static_cast(N)); } // LCOV_EXCL_STOP @@ -269,23 +269,23 @@ class binary_writer } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xB8)); + oa->write_character(to_char_type(0xB8)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xB9)); + oa->write_character(to_char_type(0xB9)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xBA)); + oa->write_character(to_char_type(0xBA)); write_number(static_cast(N)); } // LCOV_EXCL_START else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xBB)); + oa->write_character(to_char_type(0xBB)); write_number(static_cast(N)); } // LCOV_EXCL_STOP @@ -313,15 +313,15 @@ class binary_writer { case value_t::null: // nil { - oa->write_character(static_cast(0xC0)); + oa->write_character(to_char_type(0xC0)); break; } case value_t::boolean: // true and false { oa->write_character(j.m_value.boolean - ? static_cast(0xC3) - : static_cast(0xC2)); + ? to_char_type(0xC3) + : to_char_type(0xC2)); break; } @@ -340,25 +340,25 @@ class binary_writer else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 8 - oa->write_character(static_cast(0xCC)); + oa->write_character(to_char_type(0xCC)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 16 - oa->write_character(static_cast(0xCD)); + oa->write_character(to_char_type(0xCD)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 32 - oa->write_character(static_cast(0xCE)); + oa->write_character(to_char_type(0xCE)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 64 - oa->write_character(static_cast(0xCF)); + oa->write_character(to_char_type(0xCF)); write_number(static_cast(j.m_value.number_integer)); } } @@ -373,28 +373,28 @@ class binary_writer j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 8 - oa->write_character(static_cast(0xD0)); + oa->write_character(to_char_type(0xD0)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer >= (std::numeric_limits::min)() and j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 16 - oa->write_character(static_cast(0xD1)); + oa->write_character(to_char_type(0xD1)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer >= (std::numeric_limits::min)() and j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 32 - oa->write_character(static_cast(0xD2)); + oa->write_character(to_char_type(0xD2)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer >= (std::numeric_limits::min)() and j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 64 - oa->write_character(static_cast(0xD3)); + oa->write_character(to_char_type(0xD3)); write_number(static_cast(j.m_value.number_integer)); } } @@ -411,25 +411,25 @@ class binary_writer else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 8 - oa->write_character(static_cast(0xCC)); + oa->write_character(to_char_type(0xCC)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 16 - oa->write_character(static_cast(0xCD)); + oa->write_character(to_char_type(0xCD)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 32 - oa->write_character(static_cast(0xCE)); + oa->write_character(to_char_type(0xCE)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 64 - oa->write_character(static_cast(0xCF)); + oa->write_character(to_char_type(0xCF)); write_number(static_cast(j.m_value.number_integer)); } break; @@ -454,19 +454,19 @@ class binary_writer else if (N <= (std::numeric_limits::max)()) { // str 8 - oa->write_character(static_cast(0xD9)); + oa->write_character(to_char_type(0xD9)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // str 16 - oa->write_character(static_cast(0xDA)); + oa->write_character(to_char_type(0xDA)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // str 32 - oa->write_character(static_cast(0xDB)); + oa->write_character(to_char_type(0xDB)); write_number(static_cast(N)); } @@ -489,13 +489,13 @@ class binary_writer else if (N <= (std::numeric_limits::max)()) { // array 16 - oa->write_character(static_cast(0xDC)); + oa->write_character(to_char_type(0xDC)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // array 32 - oa->write_character(static_cast(0xDD)); + oa->write_character(to_char_type(0xDD)); write_number(static_cast(N)); } @@ -519,13 +519,13 @@ class binary_writer else if (N <= (std::numeric_limits::max)()) { // map 16 - oa->write_character(static_cast(0xDE)); + oa->write_character(to_char_type(0xDE)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // map 32 - oa->write_character(static_cast(0xDF)); + oa->write_character(to_char_type(0xDF)); write_number(static_cast(N)); } @@ -558,7 +558,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('Z')); + oa->write_character(to_char_type('Z')); } break; } @@ -568,8 +568,8 @@ class binary_writer if (add_prefix) { oa->write_character(j.m_value.boolean - ? static_cast('T') - : static_cast('F')); + ? to_char_type('T') + : to_char_type('F')); } break; } @@ -596,7 +596,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('S')); + oa->write_character(to_char_type('S')); } write_number_with_ubjson_prefix(j.m_value.string->size(), true); oa->write_characters( @@ -609,7 +609,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('[')); + oa->write_character(to_char_type('[')); } bool prefix_required = true; @@ -626,14 +626,14 @@ class binary_writer if (same_prefix) { prefix_required = false; - oa->write_character(static_cast('$')); + oa->write_character(to_char_type('$')); oa->write_character(first_prefix); } } if (use_count) { - oa->write_character(static_cast('#')); + oa->write_character(to_char_type('#')); write_number_with_ubjson_prefix(j.m_value.array->size(), true); } @@ -644,7 +644,7 @@ class binary_writer if (not use_count) { - oa->write_character(static_cast(']')); + oa->write_character(to_char_type(']')); } break; @@ -654,7 +654,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('{')); + oa->write_character(to_char_type('{')); } bool prefix_required = true; @@ -671,14 +671,14 @@ class binary_writer if (same_prefix) { prefix_required = false; - oa->write_character(static_cast('$')); + oa->write_character(to_char_type('$')); oa->write_character(first_prefix); } } if (use_count) { - oa->write_character(static_cast('#')); + oa->write_character(to_char_type('#')); write_number_with_ubjson_prefix(j.m_value.object->size(), true); } @@ -693,7 +693,7 @@ class binary_writer if (not use_count) { - oa->write_character(static_cast('}')); + oa->write_character(to_char_type('}')); } break; @@ -731,7 +731,7 @@ class binary_writer void write_bson_entry_header(const typename BasicJsonType::string_t& name, std::uint8_t element_type) { - oa->write_character(static_cast(element_type)); // boolean + oa->write_character(to_char_type(element_type)); // boolean oa->write_characters( reinterpret_cast(name.c_str()), name.size() + 1u); @@ -744,7 +744,7 @@ class binary_writer const bool value) { write_bson_entry_header(name, 0x08); - oa->write_character(value ? static_cast(0x01) : static_cast(0x00)); + oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00)); } /*! @@ -900,7 +900,7 @@ class binary_writer write_bson_element(std::to_string(array_index++), el); } - oa->write_character(static_cast(0x00)); + oa->write_character(to_char_type(0x00)); } /*! @@ -1026,7 +1026,7 @@ class binary_writer write_bson_element(el.first, el.second); } - oa->write_character(static_cast(0x00)); + oa->write_character(to_char_type(0x00)); } ////////// @@ -1035,12 +1035,12 @@ class binary_writer static constexpr CharType get_cbor_float_prefix(float /*unused*/) { - return static_cast(0xFA); // Single-Precision Float + return to_char_type(0xFA); // Single-Precision Float } static constexpr CharType get_cbor_float_prefix(double /*unused*/) { - return static_cast(0xFB); // Double-Precision Float + return to_char_type(0xFB); // Double-Precision Float } ///////////// @@ -1049,12 +1049,12 @@ class binary_writer static constexpr CharType get_msgpack_float_prefix(float /*unused*/) { - return static_cast(0xCA); // float 32 + return to_char_type(0xCA); // float 32 } static constexpr CharType get_msgpack_float_prefix(double /*unused*/) { - return static_cast(0xCB); // float 64 + return to_char_type(0xCB); // float 64 } //////////// @@ -1084,7 +1084,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('i')); // int8 + oa->write_character(to_char_type('i')); // int8 } write_number(static_cast(n)); } @@ -1092,7 +1092,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('U')); // uint8 + oa->write_character(to_char_type('U')); // uint8 } write_number(static_cast(n)); } @@ -1100,7 +1100,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('I')); // int16 + oa->write_character(to_char_type('I')); // int16 } write_number(static_cast(n)); } @@ -1108,7 +1108,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('l')); // int32 + oa->write_character(to_char_type('l')); // int32 } write_number(static_cast(n)); } @@ -1116,7 +1116,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('L')); // int64 + oa->write_character(to_char_type('L')); // int64 } write_number(static_cast(n)); } @@ -1137,7 +1137,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('i')); // int8 + oa->write_character(to_char_type('i')); // int8 } write_number(static_cast(n)); } @@ -1145,7 +1145,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('U')); // uint8 + oa->write_character(to_char_type('U')); // uint8 } write_number(static_cast(n)); } @@ -1153,7 +1153,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('I')); // int16 + oa->write_character(to_char_type('I')); // int16 } write_number(static_cast(n)); } @@ -1161,7 +1161,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('l')); // int32 + oa->write_character(to_char_type('l')); // int32 } write_number(static_cast(n)); } @@ -1169,7 +1169,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('L')); // int64 + oa->write_character(to_char_type('L')); // int64 } write_number(static_cast(n)); } @@ -1277,7 +1277,6 @@ class binary_writer /* @brief write a number to output input - @param[in] n number of type @a NumberType @tparam NumberType the type of the number @tparam OutputIsLittleEndian Set to true if output data is @@ -1304,6 +1303,46 @@ class binary_writer oa->write_characters(vec.data(), sizeof(NumberType)); } + // The following to_char_type functions are implement the conversion + // between uint8_t and CharType. In case CharType is not unsigned, + // such a conversion is required to allow values greater than 128. + // See for a discussion. + template < typename C = CharType, + enable_if_t < std::is_signed::value and std::is_signed::value > * = nullptr > + static constexpr CharType to_char_type(std::uint8_t x) noexcept + { + return *reinterpret_cast(&x); + } + + template < typename C = CharType, + enable_if_t < std::is_signed::value and std::is_unsigned::value > * = nullptr > + static CharType to_char_type(std::uint8_t x) noexcept + { + static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t"); + static_assert(std::is_pod::value, "CharType must be POD"); + CharType result; + std::memcpy(&result, &x, sizeof(x)); + return result; + } + + template::value>* = nullptr> + static constexpr CharType to_char_type(std::uint8_t x) noexcept + { + return x; + } + + template < typename InputCharType, typename C = CharType, + enable_if_t < + std::is_signed::value and + std::is_signed::value and + std::is_same::type>::value + > * = nullptr > + static constexpr CharType to_char_type(InputCharType x) noexcept + { + return x; + } + private: /// whether we can assume little endianess const bool is_little_endian = binary_reader::little_endianess(); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 79f74e4cfa..5791f518f9 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -8349,15 +8349,15 @@ class binary_writer { case value_t::null: { - oa->write_character(static_cast(0xF6)); + oa->write_character(to_char_type(0xF6)); break; } case value_t::boolean: { oa->write_character(j.m_value.boolean - ? static_cast(0xF5) - : static_cast(0xF4)); + ? to_char_type(0xF5) + : to_char_type(0xF4)); break; } @@ -8374,22 +8374,22 @@ class binary_writer } else if (j.m_value.number_integer <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x18)); + oa->write_character(to_char_type(0x18)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x19)); + oa->write_character(to_char_type(0x19)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x1A)); + oa->write_character(to_char_type(0x1A)); write_number(static_cast(j.m_value.number_integer)); } else { - oa->write_character(static_cast(0x1B)); + oa->write_character(to_char_type(0x1B)); write_number(static_cast(j.m_value.number_integer)); } } @@ -8404,22 +8404,22 @@ class binary_writer } else if (positive_number <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x38)); + oa->write_character(to_char_type(0x38)); write_number(static_cast(positive_number)); } else if (positive_number <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x39)); + oa->write_character(to_char_type(0x39)); write_number(static_cast(positive_number)); } else if (positive_number <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x3A)); + oa->write_character(to_char_type(0x3A)); write_number(static_cast(positive_number)); } else { - oa->write_character(static_cast(0x3B)); + oa->write_character(to_char_type(0x3B)); write_number(static_cast(positive_number)); } } @@ -8434,22 +8434,22 @@ class binary_writer } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x18)); + oa->write_character(to_char_type(0x18)); write_number(static_cast(j.m_value.number_unsigned)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x19)); + oa->write_character(to_char_type(0x19)); write_number(static_cast(j.m_value.number_unsigned)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x1A)); + oa->write_character(to_char_type(0x1A)); write_number(static_cast(j.m_value.number_unsigned)); } else { - oa->write_character(static_cast(0x1B)); + oa->write_character(to_char_type(0x1B)); write_number(static_cast(j.m_value.number_unsigned)); } break; @@ -8472,23 +8472,23 @@ class binary_writer } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x78)); + oa->write_character(to_char_type(0x78)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x79)); + oa->write_character(to_char_type(0x79)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x7A)); + oa->write_character(to_char_type(0x7A)); write_number(static_cast(N)); } // LCOV_EXCL_START else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x7B)); + oa->write_character(to_char_type(0x7B)); write_number(static_cast(N)); } // LCOV_EXCL_STOP @@ -8510,23 +8510,23 @@ class binary_writer } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x98)); + oa->write_character(to_char_type(0x98)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x99)); + oa->write_character(to_char_type(0x99)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x9A)); + oa->write_character(to_char_type(0x9A)); write_number(static_cast(N)); } // LCOV_EXCL_START else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0x9B)); + oa->write_character(to_char_type(0x9B)); write_number(static_cast(N)); } // LCOV_EXCL_STOP @@ -8549,23 +8549,23 @@ class binary_writer } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xB8)); + oa->write_character(to_char_type(0xB8)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xB9)); + oa->write_character(to_char_type(0xB9)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xBA)); + oa->write_character(to_char_type(0xBA)); write_number(static_cast(N)); } // LCOV_EXCL_START else if (N <= (std::numeric_limits::max)()) { - oa->write_character(static_cast(0xBB)); + oa->write_character(to_char_type(0xBB)); write_number(static_cast(N)); } // LCOV_EXCL_STOP @@ -8593,15 +8593,15 @@ class binary_writer { case value_t::null: // nil { - oa->write_character(static_cast(0xC0)); + oa->write_character(to_char_type(0xC0)); break; } case value_t::boolean: // true and false { oa->write_character(j.m_value.boolean - ? static_cast(0xC3) - : static_cast(0xC2)); + ? to_char_type(0xC3) + : to_char_type(0xC2)); break; } @@ -8620,25 +8620,25 @@ class binary_writer else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 8 - oa->write_character(static_cast(0xCC)); + oa->write_character(to_char_type(0xCC)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 16 - oa->write_character(static_cast(0xCD)); + oa->write_character(to_char_type(0xCD)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 32 - oa->write_character(static_cast(0xCE)); + oa->write_character(to_char_type(0xCE)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 64 - oa->write_character(static_cast(0xCF)); + oa->write_character(to_char_type(0xCF)); write_number(static_cast(j.m_value.number_integer)); } } @@ -8653,28 +8653,28 @@ class binary_writer j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 8 - oa->write_character(static_cast(0xD0)); + oa->write_character(to_char_type(0xD0)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer >= (std::numeric_limits::min)() and j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 16 - oa->write_character(static_cast(0xD1)); + oa->write_character(to_char_type(0xD1)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer >= (std::numeric_limits::min)() and j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 32 - oa->write_character(static_cast(0xD2)); + oa->write_character(to_char_type(0xD2)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_integer >= (std::numeric_limits::min)() and j.m_value.number_integer <= (std::numeric_limits::max)()) { // int 64 - oa->write_character(static_cast(0xD3)); + oa->write_character(to_char_type(0xD3)); write_number(static_cast(j.m_value.number_integer)); } } @@ -8691,25 +8691,25 @@ class binary_writer else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 8 - oa->write_character(static_cast(0xCC)); + oa->write_character(to_char_type(0xCC)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 16 - oa->write_character(static_cast(0xCD)); + oa->write_character(to_char_type(0xCD)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 32 - oa->write_character(static_cast(0xCE)); + oa->write_character(to_char_type(0xCE)); write_number(static_cast(j.m_value.number_integer)); } else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) { // uint 64 - oa->write_character(static_cast(0xCF)); + oa->write_character(to_char_type(0xCF)); write_number(static_cast(j.m_value.number_integer)); } break; @@ -8734,19 +8734,19 @@ class binary_writer else if (N <= (std::numeric_limits::max)()) { // str 8 - oa->write_character(static_cast(0xD9)); + oa->write_character(to_char_type(0xD9)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // str 16 - oa->write_character(static_cast(0xDA)); + oa->write_character(to_char_type(0xDA)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // str 32 - oa->write_character(static_cast(0xDB)); + oa->write_character(to_char_type(0xDB)); write_number(static_cast(N)); } @@ -8769,13 +8769,13 @@ class binary_writer else if (N <= (std::numeric_limits::max)()) { // array 16 - oa->write_character(static_cast(0xDC)); + oa->write_character(to_char_type(0xDC)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // array 32 - oa->write_character(static_cast(0xDD)); + oa->write_character(to_char_type(0xDD)); write_number(static_cast(N)); } @@ -8799,13 +8799,13 @@ class binary_writer else if (N <= (std::numeric_limits::max)()) { // map 16 - oa->write_character(static_cast(0xDE)); + oa->write_character(to_char_type(0xDE)); write_number(static_cast(N)); } else if (N <= (std::numeric_limits::max)()) { // map 32 - oa->write_character(static_cast(0xDF)); + oa->write_character(to_char_type(0xDF)); write_number(static_cast(N)); } @@ -8838,7 +8838,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('Z')); + oa->write_character(to_char_type('Z')); } break; } @@ -8848,8 +8848,8 @@ class binary_writer if (add_prefix) { oa->write_character(j.m_value.boolean - ? static_cast('T') - : static_cast('F')); + ? to_char_type('T') + : to_char_type('F')); } break; } @@ -8876,7 +8876,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('S')); + oa->write_character(to_char_type('S')); } write_number_with_ubjson_prefix(j.m_value.string->size(), true); oa->write_characters( @@ -8889,7 +8889,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('[')); + oa->write_character(to_char_type('[')); } bool prefix_required = true; @@ -8906,14 +8906,14 @@ class binary_writer if (same_prefix) { prefix_required = false; - oa->write_character(static_cast('$')); + oa->write_character(to_char_type('$')); oa->write_character(first_prefix); } } if (use_count) { - oa->write_character(static_cast('#')); + oa->write_character(to_char_type('#')); write_number_with_ubjson_prefix(j.m_value.array->size(), true); } @@ -8924,7 +8924,7 @@ class binary_writer if (not use_count) { - oa->write_character(static_cast(']')); + oa->write_character(to_char_type(']')); } break; @@ -8934,7 +8934,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('{')); + oa->write_character(to_char_type('{')); } bool prefix_required = true; @@ -8951,14 +8951,14 @@ class binary_writer if (same_prefix) { prefix_required = false; - oa->write_character(static_cast('$')); + oa->write_character(to_char_type('$')); oa->write_character(first_prefix); } } if (use_count) { - oa->write_character(static_cast('#')); + oa->write_character(to_char_type('#')); write_number_with_ubjson_prefix(j.m_value.object->size(), true); } @@ -8973,7 +8973,7 @@ class binary_writer if (not use_count) { - oa->write_character(static_cast('}')); + oa->write_character(to_char_type('}')); } break; @@ -9011,7 +9011,7 @@ class binary_writer void write_bson_entry_header(const typename BasicJsonType::string_t& name, std::uint8_t element_type) { - oa->write_character(static_cast(element_type)); // boolean + oa->write_character(to_char_type(element_type)); // boolean oa->write_characters( reinterpret_cast(name.c_str()), name.size() + 1u); @@ -9024,7 +9024,7 @@ class binary_writer const bool value) { write_bson_entry_header(name, 0x08); - oa->write_character(value ? static_cast(0x01) : static_cast(0x00)); + oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00)); } /*! @@ -9180,7 +9180,7 @@ class binary_writer write_bson_element(std::to_string(array_index++), el); } - oa->write_character(static_cast(0x00)); + oa->write_character(to_char_type(0x00)); } /*! @@ -9306,7 +9306,7 @@ class binary_writer write_bson_element(el.first, el.second); } - oa->write_character(static_cast(0x00)); + oa->write_character(to_char_type(0x00)); } ////////// @@ -9315,12 +9315,12 @@ class binary_writer static constexpr CharType get_cbor_float_prefix(float /*unused*/) { - return static_cast(0xFA); // Single-Precision Float + return to_char_type(0xFA); // Single-Precision Float } static constexpr CharType get_cbor_float_prefix(double /*unused*/) { - return static_cast(0xFB); // Double-Precision Float + return to_char_type(0xFB); // Double-Precision Float } ///////////// @@ -9329,12 +9329,12 @@ class binary_writer static constexpr CharType get_msgpack_float_prefix(float /*unused*/) { - return static_cast(0xCA); // float 32 + return to_char_type(0xCA); // float 32 } static constexpr CharType get_msgpack_float_prefix(double /*unused*/) { - return static_cast(0xCB); // float 64 + return to_char_type(0xCB); // float 64 } //////////// @@ -9364,7 +9364,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('i')); // int8 + oa->write_character(to_char_type('i')); // int8 } write_number(static_cast(n)); } @@ -9372,7 +9372,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('U')); // uint8 + oa->write_character(to_char_type('U')); // uint8 } write_number(static_cast(n)); } @@ -9380,7 +9380,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('I')); // int16 + oa->write_character(to_char_type('I')); // int16 } write_number(static_cast(n)); } @@ -9388,7 +9388,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('l')); // int32 + oa->write_character(to_char_type('l')); // int32 } write_number(static_cast(n)); } @@ -9396,7 +9396,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('L')); // int64 + oa->write_character(to_char_type('L')); // int64 } write_number(static_cast(n)); } @@ -9417,7 +9417,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('i')); // int8 + oa->write_character(to_char_type('i')); // int8 } write_number(static_cast(n)); } @@ -9425,7 +9425,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('U')); // uint8 + oa->write_character(to_char_type('U')); // uint8 } write_number(static_cast(n)); } @@ -9433,7 +9433,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('I')); // int16 + oa->write_character(to_char_type('I')); // int16 } write_number(static_cast(n)); } @@ -9441,7 +9441,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('l')); // int32 + oa->write_character(to_char_type('l')); // int32 } write_number(static_cast(n)); } @@ -9449,7 +9449,7 @@ class binary_writer { if (add_prefix) { - oa->write_character(static_cast('L')); // int64 + oa->write_character(to_char_type('L')); // int64 } write_number(static_cast(n)); } @@ -9557,7 +9557,6 @@ class binary_writer /* @brief write a number to output input - @param[in] n number of type @a NumberType @tparam NumberType the type of the number @tparam OutputIsLittleEndian Set to true if output data is @@ -9584,6 +9583,46 @@ class binary_writer oa->write_characters(vec.data(), sizeof(NumberType)); } + // The following to_char_type functions are implement the conversion + // between uint8_t and CharType. In case CharType is not unsigned, + // such a conversion is required to allow values greater than 128. + // See for a discussion. + template < typename C = CharType, + enable_if_t < std::is_signed::value and std::is_signed::value > * = nullptr > + static constexpr CharType to_char_type(std::uint8_t x) noexcept + { + return *reinterpret_cast(&x); + } + + template < typename C = CharType, + enable_if_t < std::is_signed::value and std::is_unsigned::value > * = nullptr > + static CharType to_char_type(std::uint8_t x) noexcept + { + static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t"); + static_assert(std::is_pod::value, "CharType must be POD"); + CharType result; + std::memcpy(&result, &x, sizeof(x)); + return result; + } + + template::value>* = nullptr> + static constexpr CharType to_char_type(std::uint8_t x) noexcept + { + return x; + } + + template < typename InputCharType, typename C = CharType, + enable_if_t < + std::is_signed::value and + std::is_signed::value and + std::is_same::type>::value + > * = nullptr > + static constexpr CharType to_char_type(InputCharType x) noexcept + { + return x; + } + private: /// whether we can assume little endianess const bool is_little_endian = binary_reader::little_endianess();