1212#include < vector>
1313#include < array>
1414#include < map>
15- #include < unordered_map>
1615#include < variant>
1716#include < system_error>
1817#if __cpp_lib_bit_cast
@@ -74,10 +73,34 @@ namespace msgpackcpp
7473 constexpr bool is_byte = std::is_same_v<Byte, char > ||
7574 std::is_same_v<Byte, uint8_t > ||
7675 std::is_same_v<Byte, int8_t >;
76+
77+ template <class Byte >
78+ constexpr bool is_binary_value_type = std::is_same_v<Byte, char > || std::is_same_v<Byte, uint8_t >;
79+
80+ // ----------------------------------------------------------------------------------------------------------------
81+
82+ template <class T , class = void >
83+ struct is_map : std::false_type {};
84+
85+ template <class T >
86+ struct is_map <T, std::void_t <typename T::key_type,
87+ typename T::mapped_type,
88+ typename T::value_type >> : std::true_type {};
89+
90+ template <class T >
91+ constexpr bool is_map_v = is_map<T>::value;
92+
93+ // ----------------------------------------------------------------------------------------------------------------
7794
7895 template <class T >
7996 using check_byte = std::enable_if_t <is_byte<T>, bool >;
8097
98+ template <class T >
99+ using check_binary = std::enable_if_t <is_binary_value_type<T>, bool >;
100+
101+ template <class T >
102+ using check_nonbinary = std::enable_if_t <!is_binary_value_type<T>, bool >;
103+
81104 template <class T >
82105 using check_float = std::enable_if_t <std::is_floating_point_v<T>, bool >;
83106
@@ -87,6 +110,9 @@ namespace msgpackcpp
87110 template <class T >
88111 using check_uint = std::enable_if_t <std::is_integral_v<T> && std::is_unsigned_v<T>, bool >;
89112
113+ template <class T >
114+ using check_map = std::enable_if_t <is_map_v<T>, bool >;
115+
90116// ----------------------------------------------------------------------------------------------------------------
91117
92118 class value
@@ -237,29 +263,17 @@ namespace msgpackcpp
237263 template <SINK_TYPE Sink>
238264 void serialize_bin_array (Sink& out, const char * data, const uint32_t len);
239265
240- template <SINK_TYPE Sink, class Alloc >
241- void serialize (Sink& out, const std::vector<char , Alloc>& v);
242-
243- template <SINK_TYPE Sink, class Alloc >
244- void serialize (Sink& out, const std::vector<uint8_t , Alloc>& v);
245-
246- template <SOURCE_TYPE Source, class Alloc >
247- void deserialize (Source& in, std::vector<char , Alloc>& v);
266+ template <SINK_TYPE Sink, class Byte , class Alloc , check_binary<Byte> = true >
267+ void serialize (Sink& out, const std::vector<Byte, Alloc>& v);
248268
249- template <SOURCE_TYPE Source, class Alloc >
250- void deserialize (Source& in, std::vector<uint8_t , Alloc>& v);
269+ template <SOURCE_TYPE Source, class Byte , class Alloc , check_binary<Byte> = true >
270+ void deserialize (Source& in, std::vector<Byte , Alloc>& v);
251271
252- template <SINK_TYPE Sink, std::size_t N>
253- void serialize (Sink& out, const std::array<char , N>& v);
272+ template <SINK_TYPE Sink, class Byte , std::size_t N, check_binary<Byte> = true >
273+ void serialize (Sink& out, const std::array<Byte , N>& v);
254274
255- template <SINK_TYPE Sink, std::size_t N>
256- void serialize (Sink& out, const std::array<uint8_t , N>& v);
257-
258- template <SOURCE_TYPE Source, std::size_t N>
259- void deserialize (Source& in, std::array<char , N>& v);
260-
261- template <SOURCE_TYPE Source, std::size_t N>
262- void deserialize (Source& in, std::array<uint8_t , N>& v);
275+ template <SOURCE_TYPE Source, class Byte , std::size_t N, check_binary<Byte> = true >
276+ void deserialize (Source& in, std::array<Byte, N>& v);
263277
264278// ----------------------------------------------------------------------------------------------------------------
265279
@@ -269,16 +283,16 @@ namespace msgpackcpp
269283 template <SOURCE_TYPE Source>
270284 void deserialize_array_size (Source& in, uint32_t & size);
271285
272- template <SINK_TYPE Sink, class T , class Alloc >
286+ template <SINK_TYPE Sink, class T , class Alloc , check_nonbinary<T> = true >
273287 void serialize (Sink& out, const std::vector<T, Alloc>& v);
274288
275- template <SOURCE_TYPE Source, class T , class Alloc >
289+ template <SOURCE_TYPE Source, class T , class Alloc , check_nonbinary<T> = true >
276290 void deserialize (Source& in, std::vector<T, Alloc>& v);
277291
278- template <SINK_TYPE Sink, class T , std::size_t N>
292+ template <SINK_TYPE Sink, class T , std::size_t N, check_nonbinary<T> = true >
279293 void serialize (Sink& out, const std::array<T, N>& v);
280294
281- template <SOURCE_TYPE Source, class T , std::size_t N>
295+ template <SOURCE_TYPE Source, class T , std::size_t N, check_nonbinary<T> = true >
282296 void deserialize (Source& in, std::array<T, N>& v);
283297
284298// ----------------------------------------------------------------------------------------------------------------
@@ -289,43 +303,11 @@ namespace msgpackcpp
289303 template <SOURCE_TYPE Source>
290304 void deserialize_map_size (Source& in, uint32_t & size);
291305
292- template <
293- SINK_TYPE Sink,
294- class K ,
295- class V ,
296- class Compare = std::less<K>,
297- class Alloc = std::allocator<std::pair<const K, V>>
298- >
299- void serialize (Sink& out, const std::map<K,V,Compare,Alloc>& map);
300-
301- template <
302- SOURCE_TYPE Source,
303- class K ,
304- class V ,
305- class Compare = std::less<K>,
306- class Alloc = std::allocator<std::pair<const K, V>>
307- >
308- void deserialize (Source& in, std::map<K,V,Compare,Alloc>& map);
309-
310- template <
311- SINK_TYPE Sink,
312- class K ,
313- class V ,
314- class Hash = std::hash<K>,
315- class KeyEqual = std::equal_to<K>,
316- class Alloc = std::allocator<std::pair<const K, V>>
317- >
318- void serialize (Sink& out, const std::unordered_map<K,V,Hash,KeyEqual,Alloc>& map);
319-
320- template <
321- SOURCE_TYPE Source,
322- class K ,
323- class V ,
324- class Hash = std::hash<K>,
325- class KeyEqual = std::equal_to<K>,
326- class Alloc = std::allocator<std::pair<const K, V>>
327- >
328- void deserialize (Source& in, std::unordered_map<K,V,Hash,KeyEqual,Alloc>& map);
306+ template <SINK_TYPE Sink, class Map , check_map<Map> = true >
307+ void serialize (Sink& out, const Map& map);
308+
309+ template <SOURCE_TYPE Source, class Map , check_map<Map> = true >
310+ void deserialize (Source& in, Map& map);
329311
330312// ----------------------------------------------------------------------------------------------------------------
331313
@@ -1002,66 +984,35 @@ namespace msgpackcpp
1002984 out (data, len);
1003985 }
1004986
1005- template <SINK_TYPE Sink, class Alloc >
1006- inline void serialize (Sink& out, const std::vector<char , Alloc>& v)
987+ template <SINK_TYPE Sink, class Byte , class Alloc , check_binary<Byte> >
988+ inline void serialize (Sink& out, const std::vector<Byte , Alloc>& v)
1007989 {
1008990 serialize_bin_array (out, (const char *)v.data (), v.size ());
1009991 }
1010992
1011- template <SINK_TYPE Sink, class Alloc >
1012- inline void serialize (Sink& out, const std::vector< uint8_t , Alloc >& v)
993+ template <SINK_TYPE Sink, class Byte , std:: size_t N, check_binary<Byte> >
994+ inline void serialize (Sink& out, const std::array<Byte, N >& v)
1013995 {
1014996 serialize_bin_array (out, (const char *)v.data (), v.size ());
1015997 }
1016998
1017- template <SOURCE_TYPE Source, class Alloc >
1018- inline void deserialize_ (Source& in, uint8_t format, std::vector<char , Alloc>& v)
999+ template <SOURCE_TYPE Source, class Byte , class Alloc , check_binary<Byte> = true >
1000+ inline void deserialize_ (Source& in, uint8_t format, std::vector<Byte , Alloc>& v)
10191001 {
10201002 uint32_t size{};
10211003 deserialize_bin_size_ (in, format, size);
10221004 v.resize (size);
1023- in (v.data (), size);
1024- }
1025-
1026- template <SOURCE_TYPE Source, class Alloc >
1027- inline void deserialize (Source& in, std::vector<char , Alloc>& v)
1028- {
1029- deserialize_ (in, read_format (in), v);
1030- }
1031-
1032- template <SOURCE_TYPE Source, class Alloc >
1033- inline void deserialize (Source& in, std::vector<uint8_t , Alloc>& v)
1034- {
1035- uint32_t size{};
1036- deserialize_bin_size (in, size);
1037- v.resize (size);
10381005 in ((char *)v.data (), size);
10391006 }
10401007
1041- template <SINK_TYPE Sink, std:: size_t N >
1042- inline void serialize (Sink& out, const std::array< char , N >& v)
1008+ template <SOURCE_TYPE Source, class Byte , class Alloc , check_binary<Byte> >
1009+ inline void deserialize (Source& in, std::vector<Byte, Alloc >& v)
10431010 {
1044- serialize_bin_array (out, (const char *)v.data (), v.size ());
1045- }
1046-
1047- template <SINK_TYPE Sink, std::size_t N>
1048- inline void serialize (Sink& out, const std::array<uint8_t , N>& v)
1049- {
1050- serialize_bin_array (out, (const char *)v.data (), v.size ());
1051- }
1052-
1053- template <SOURCE_TYPE Source, std::size_t N>
1054- inline void deserialize (Source& in, std::array<char , N>& v)
1055- {
1056- uint32_t size{};
1057- deserialize_bin_size (in, size);
1058- if (size != N)
1059- throw std::system_error (BAD_SIZE);
1060- in ((char *)v.data (), size);
1011+ deserialize_ (in, read_format (in), v);
10611012 }
10621013
1063- template <SOURCE_TYPE Source, std::size_t N>
1064- inline void deserialize (Source& in, std::array<uint8_t , N>& v)
1014+ template <SOURCE_TYPE Source, class Byte , std::size_t N, check_binary<Byte> >
1015+ inline void deserialize (Source& in, std::array<Byte , N>& v)
10651016 {
10661017 uint32_t size{};
10671018 deserialize_bin_size (in, size);
@@ -1125,15 +1076,15 @@ namespace msgpackcpp
11251076 deserialize_array_size_ (in, read_format (in), size);
11261077 }
11271078
1128- template <SINK_TYPE Sink, class T , class Alloc >
1079+ template <SINK_TYPE Sink, class T , class Alloc , check_nonbinary<T> >
11291080 inline void serialize (Sink& out, const std::vector<T, Alloc>& v)
11301081 {
11311082 serialize_array_size (out, v.size ());
11321083 for (const auto & x : v)
11331084 serialize (out, x);
11341085 }
11351086
1136- template <SOURCE_TYPE Source, class T , class Alloc >
1087+ template <SOURCE_TYPE Source, class T , class Alloc , check_nonbinary<T> >
11371088 inline void deserialize (Source& in, std::vector<T, Alloc>& v)
11381089 {
11391090 uint32_t size{};
@@ -1143,15 +1094,15 @@ namespace msgpackcpp
11431094 deserialize (in, x);
11441095 }
11451096
1146- template <SINK_TYPE Sink, class T , std::size_t N>
1097+ template <SINK_TYPE Sink, class T , std::size_t N, check_nonbinary<T> >
11471098 inline void serialize (Sink& out, const std::array<T, N>& v)
11481099 {
11491100 serialize_array_size (out, v.size ());
11501101 for (const auto & x : v)
11511102 serialize (out, x);
11521103 }
11531104
1154- template <SOURCE_TYPE Source, class T , std::size_t N>
1105+ template <SOURCE_TYPE Source, class T , std::size_t N, check_nonbinary<T> >
11551106 inline void deserialize (Source& in, std::array<T, N>& v)
11561107 {
11571108 uint32_t size{};
@@ -1217,14 +1168,8 @@ namespace msgpackcpp
12171168 deserialize_map_size_ (in, read_format (in), size);
12181169 }
12191170
1220- template <
1221- SINK_TYPE Sink,
1222- class K ,
1223- class V ,
1224- class Compare ,
1225- class Alloc
1226- >
1227- inline void serialize (Sink& out, const std::map<K,V,Compare,Alloc>& map)
1171+ template <SINK_TYPE Sink, class Map , check_map<Map>>
1172+ inline void serialize (Sink& out, const Map& map)
12281173 {
12291174 serialize_map_size (out, map.size ());
12301175
@@ -1235,57 +1180,12 @@ namespace msgpackcpp
12351180 }
12361181 }
12371182
1238- template <
1239- SOURCE_TYPE Source,
1240- class K ,
1241- class V ,
1242- class Compare ,
1243- class Alloc
1244- >
1245- inline void deserialize (Source& in, std::map<K,V,Compare,Alloc>& map)
1246- {
1247- uint32_t size{};
1248- deserialize_map_size (in, size);
1249-
1250- for (uint32_t i = 0 ; i < size ; ++i)
1251- {
1252- K key{};
1253- V val{};
1254- deserialize (in, key);
1255- deserialize (in, val);
1256- map.emplace (std::make_pair (key, val));
1257- }
1258- }
1259-
1260- template <
1261- SINK_TYPE Sink,
1262- class K ,
1263- class V ,
1264- class Hash ,
1265- class KeyEqual ,
1266- class Alloc
1267- >
1268- inline void serialize (Sink& out, const std::unordered_map<K,V,Hash,KeyEqual,Alloc>& map)
1183+ template <SOURCE_TYPE Source, class Map , check_map<Map>>
1184+ inline void deserialize (Source& in, Map& map)
12691185 {
1270- serialize_map_size (out, map.size ());
1186+ using K = typename Map::key_type;
1187+ using V = typename Map::mapped_type;
12711188
1272- for (const auto & [k,v] : map)
1273- {
1274- serialize (out, k);
1275- serialize (out, v);
1276- }
1277- }
1278-
1279- template <
1280- SOURCE_TYPE Source,
1281- class K ,
1282- class V ,
1283- class Hash ,
1284- class KeyEqual ,
1285- class Alloc
1286- >
1287- inline void deserialize (Source& in, std::unordered_map<K,V,Hash,KeyEqual,Alloc>& map)
1288- {
12891189 uint32_t size{};
12901190 deserialize_map_size (in, size);
12911191
0 commit comments