Skip to content

Commit 01ccb80

Browse files
author
me
committed
more generics
1 parent d01156c commit 01ccb80

File tree

1 file changed

+65
-165
lines changed

1 file changed

+65
-165
lines changed

include/msgpack.h

Lines changed: 65 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
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

Comments
 (0)