@@ -913,6 +913,7 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
913913#include <string> // string
914914#include <tuple> // tuple, make_tuple
915915#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
916+ #include <unordered_map> // unordered_map
916917#include <utility> // pair, declval
917918#include <valarray> // valarray
918919
@@ -1186,10 +1187,29 @@ void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
11861187 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
11871188}
11881189
1189- template <typename BasicJsonType, typename Key, typename Value,
1190+ template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
11901191 typename = enable_if_t<not std::is_constructible<
11911192 typename BasicJsonType::string_t, Key>::value>>
1192- void from_json(const BasicJsonType& j, std::map<Key, Value>& m)
1193+ void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1194+ {
1195+ if (JSON_UNLIKELY(not j.is_array()))
1196+ {
1197+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1198+ }
1199+ for (const auto& p : j)
1200+ {
1201+ if (JSON_UNLIKELY(not p.is_array()))
1202+ {
1203+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1204+ }
1205+ m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1206+ }
1207+ }
1208+
1209+ template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1210+ typename = enable_if_t<not std::is_constructible<
1211+ typename BasicJsonType::string_t, Key>::value>>
1212+ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
11931213{
11941214 if (JSON_UNLIKELY(not j.is_array()))
11951215 {
@@ -1973,10 +1993,8 @@ class input_adapter
19731993#include <clocale> // localeconv
19741994#include <cstddef> // size_t
19751995#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
1996+ #include <cstdio> // snprintf
19761997#include <initializer_list> // initializer_list
1977- #include <ios> // hex, uppercase
1978- #include <iomanip> // setw, setfill
1979- #include <sstream> // stringstream
19801998#include <string> // char_traits, string
19811999#include <vector> // vector
19822000
@@ -3146,10 +3164,9 @@ class lexer
31463164 if ('\x00' <= c and c <= '\x1F')
31473165 {
31483166 // escape control characters
3149- std::stringstream ss;
3150- ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
3151- << std::hex << static_cast<int>(c) << ">";
3152- result += ss.str();
3167+ char cs[9];
3168+ snprintf(cs, 9, "<U+%.4X>", c);
3169+ result += cs;
31533170 }
31543171 else
31553172 {
@@ -5619,12 +5636,10 @@ class output_adapter
56195636#include <cmath> // ldexp
56205637#include <cstddef> // size_t
56215638#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5639+ #include <cstdio> // snprintf
56225640#include <cstring> // memcpy
5623- #include <iomanip> // setw, setfill
5624- #include <ios> // hex
56255641#include <iterator> // back_inserter
56265642#include <limits> // numeric_limits
5627- #include <sstream> // stringstream
56285643#include <string> // char_traits, string
56295644#include <utility> // make_pair, move
56305645
@@ -7283,9 +7298,9 @@ class binary_reader
72837298 */
72847299 std::string get_token_string() const
72857300 {
7286- std::stringstream ss ;
7287- ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
7288- return ss.str() ;
7301+ char cr[3] ;
7302+ snprintf(cr, 3, "%.2X", current) ;
7303+ return std::string{cr} ;
72897304 }
72907305
72917306 private:
@@ -8272,11 +8287,8 @@ class binary_writer
82728287#include <cstddef> // size_t, ptrdiff_t
82738288#include <cstdint> // uint8_t
82748289#include <cstdio> // snprintf
8275- #include <iomanip> // setfill
8276- #include <iterator> // next
82778290#include <limits> // numeric_limits
82788291#include <string> // string
8279- #include <sstream> // stringstream
82808292#include <type_traits> // is_same
82818293
82828294// #include <nlohmann/detail/exceptions.hpp>
@@ -9753,9 +9765,9 @@ class serializer
97539765
97549766 case UTF8_REJECT: // decode found invalid UTF-8 byte
97559767 {
9756- std::stringstream ss ;
9757- ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>( byte);
9758- JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str() ));
9768+ std::string sn(3, '\0') ;
9769+ snprintf(&sn[0], sn.size(), "%.2X", byte);
9770+ JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn ));
97599771 }
97609772
97619773 default: // decode found yet incomplete multi-byte code point
@@ -9781,9 +9793,9 @@ class serializer
97819793 else
97829794 {
97839795 // we finish reading, but do not accept: string was incomplete
9784- std::stringstream ss ;
9785- ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>( static_cast<uint8_t>(s.back()));
9786- JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str() ));
9796+ std::string sn(3, '\0') ;
9797+ snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
9798+ JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn ));
97879799 }
97889800 }
97899801
0 commit comments