mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-04-21 16:28:19 +02:00
Improved templates for std::unordered_map and std::unordered_set so they handle all sorts of those
This commit is contained in:
parent
7e6a498c14
commit
f986370634
@ -32,15 +32,15 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
|
|
||||||
namespace adaptor {
|
namespace adaptor {
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct as<
|
struct as<
|
||||||
std::unordered_map<K, V>,
|
std::unordered_map<K, V, OtherTypes...>,
|
||||||
typename std::enable_if<msgpack::has_as<K>::value && msgpack::has_as<V>::value>::type> {
|
typename std::enable_if<msgpack::has_as<K>::value && msgpack::has_as<V>::value>::type> {
|
||||||
std::unordered_map<K, V> operator()(msgpack::object const& o) const {
|
std::unordered_map<K, V, OtherTypes...> operator()(msgpack::object const& o) const {
|
||||||
if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
||||||
msgpack::object_kv* p(o.via.map.ptr);
|
msgpack::object_kv* p(o.via.map.ptr);
|
||||||
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
||||||
std::unordered_map<K, V> v;
|
std::unordered_map<K, V, OtherTypes...> v;
|
||||||
for (; p != pend; ++p) {
|
for (; p != pend; ++p) {
|
||||||
v.emplace(p->key.as<K>(), p->val.as<V>());
|
v.emplace(p->key.as<K>(), p->val.as<V>());
|
||||||
}
|
}
|
||||||
@ -48,13 +48,13 @@ struct as<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct convert<std::unordered_map<K, V>> {
|
struct convert<std::unordered_map<K, V, OtherTypes...>> {
|
||||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_map<K, V>& v) const {
|
msgpack::object const& operator()(msgpack::object const& o, std::unordered_map<K, V, OtherTypes...>& v) const {
|
||||||
if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
||||||
msgpack::object_kv* p(o.via.map.ptr);
|
msgpack::object_kv* p(o.via.map.ptr);
|
||||||
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
||||||
std::unordered_map<K, V> tmp;
|
std::unordered_map<K, V, OtherTypes...> tmp;
|
||||||
for(; p != pend; ++p) {
|
for(; p != pend; ++p) {
|
||||||
K key;
|
K key;
|
||||||
p->key.convert(key);
|
p->key.convert(key);
|
||||||
@ -65,13 +65,13 @@ struct convert<std::unordered_map<K, V>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct pack<std::unordered_map<K, V>> {
|
struct pack<std::unordered_map<K, V, OtherTypes...>> {
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_map<K,V>& v) const {
|
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_map<K, V, OtherTypes...>& v) const {
|
||||||
uint32_t size = checked_get_container_size(v.size());
|
uint32_t size = checked_get_container_size(v.size());
|
||||||
o.pack_map(size);
|
o.pack_map(size);
|
||||||
for(typename std::unordered_map<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
for(typename std::unordered_map<K, V, OtherTypes...>::const_iterator it(v.begin()), it_end(v.end());
|
||||||
it != it_end; ++it) {
|
it != it_end; ++it) {
|
||||||
o.pack(it->first);
|
o.pack(it->first);
|
||||||
o.pack(it->second);
|
o.pack(it->second);
|
||||||
@ -80,9 +80,9 @@ struct pack<std::unordered_map<K, V>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct object_with_zone<std::unordered_map<K, V>> {
|
struct object_with_zone<std::unordered_map<K, V, OtherTypes...>> {
|
||||||
void operator()(msgpack::object::with_zone& o, const std::unordered_map<K,V>& v) const {
|
void operator()(msgpack::object::with_zone& o, const std::unordered_map<K, V, OtherTypes...>& v) const {
|
||||||
o.type = msgpack::type::MAP;
|
o.type = msgpack::type::MAP;
|
||||||
if(v.empty()) {
|
if(v.empty()) {
|
||||||
o.via.map.ptr = nullptr;
|
o.via.map.ptr = nullptr;
|
||||||
@ -93,7 +93,7 @@ struct object_with_zone<std::unordered_map<K, V>> {
|
|||||||
msgpack::object_kv* const pend = p + size;
|
msgpack::object_kv* const pend = p + size;
|
||||||
o.via.map.ptr = p;
|
o.via.map.ptr = p;
|
||||||
o.via.map.size = size;
|
o.via.map.size = size;
|
||||||
typename std::unordered_map<K,V>::const_iterator it(v.begin());
|
typename std::unordered_map<K, V, OtherTypes...>::const_iterator it(v.begin());
|
||||||
do {
|
do {
|
||||||
p->key = msgpack::object(it->first, o.zone);
|
p->key = msgpack::object(it->first, o.zone);
|
||||||
p->val = msgpack::object(it->second, o.zone);
|
p->val = msgpack::object(it->second, o.zone);
|
||||||
@ -105,15 +105,15 @@ struct object_with_zone<std::unordered_map<K, V>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct as<
|
struct as<
|
||||||
std::unordered_multimap<K, V>,
|
std::unordered_multimap<K, V, OtherTypes...>,
|
||||||
typename std::enable_if<msgpack::has_as<K>::value && msgpack::has_as<V>::value>::type> {
|
typename std::enable_if<msgpack::has_as<K>::value && msgpack::has_as<V>::value>::type> {
|
||||||
std::unordered_multimap<K, V> operator()(msgpack::object const& o) const {
|
std::unordered_multimap<K, V, OtherTypes...> operator()(msgpack::object const& o) const {
|
||||||
if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
||||||
msgpack::object_kv* p(o.via.map.ptr);
|
msgpack::object_kv* p(o.via.map.ptr);
|
||||||
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
||||||
std::unordered_multimap<K, V> v;
|
std::unordered_multimap<K, V, OtherTypes...> v;
|
||||||
for (; p != pend; ++p) {
|
for (; p != pend; ++p) {
|
||||||
v.emplace(p->key.as<K>(), p->val.as<V>());
|
v.emplace(p->key.as<K>(), p->val.as<V>());
|
||||||
}
|
}
|
||||||
@ -121,13 +121,13 @@ struct as<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct convert<std::unordered_multimap<K, V>> {
|
struct convert<std::unordered_multimap<K, V, OtherTypes...>> {
|
||||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_multimap<K, V>& v) const {
|
msgpack::object const& operator()(msgpack::object const& o, std::unordered_multimap<K, V, OtherTypes...>& v) const {
|
||||||
if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
||||||
msgpack::object_kv* p(o.via.map.ptr);
|
msgpack::object_kv* p(o.via.map.ptr);
|
||||||
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
||||||
std::unordered_multimap<K, V> tmp;
|
std::unordered_multimap<K, V, OtherTypes...> tmp;
|
||||||
for(; p != pend; ++p) {
|
for(; p != pend; ++p) {
|
||||||
std::pair<K, V> value;
|
std::pair<K, V> value;
|
||||||
p->key.convert(value.first);
|
p->key.convert(value.first);
|
||||||
@ -139,13 +139,13 @@ struct convert<std::unordered_multimap<K, V>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct pack<std::unordered_multimap<K, V>> {
|
struct pack<std::unordered_multimap<K, V, OtherTypes...>> {
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_multimap<K,V>& v) const {
|
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_multimap<K, V, OtherTypes...>& v) const {
|
||||||
uint32_t size = checked_get_container_size(v.size());
|
uint32_t size = checked_get_container_size(v.size());
|
||||||
o.pack_map(size);
|
o.pack_map(size);
|
||||||
for(typename std::unordered_multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
for(typename std::unordered_multimap<K, V, OtherTypes...>::const_iterator it(v.begin()), it_end(v.end());
|
||||||
it != it_end; ++it) {
|
it != it_end; ++it) {
|
||||||
o.pack(it->first);
|
o.pack(it->first);
|
||||||
o.pack(it->second);
|
o.pack(it->second);
|
||||||
@ -154,9 +154,9 @@ struct pack<std::unordered_multimap<K, V>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V, typename... OtherTypes>
|
||||||
struct object_with_zone<std::unordered_multimap<K, V>> {
|
struct object_with_zone<std::unordered_multimap<K, V, OtherTypes...>> {
|
||||||
void operator()(msgpack::object::with_zone& o, const std::unordered_multimap<K,V>& v) const {
|
void operator()(msgpack::object::with_zone& o, const std::unordered_multimap<K, V, OtherTypes...>& v) const {
|
||||||
o.type = msgpack::type::MAP;
|
o.type = msgpack::type::MAP;
|
||||||
if(v.empty()) {
|
if(v.empty()) {
|
||||||
o.via.map.ptr = nullptr;
|
o.via.map.ptr = nullptr;
|
||||||
@ -167,7 +167,7 @@ struct object_with_zone<std::unordered_multimap<K, V>> {
|
|||||||
msgpack::object_kv* const pend = p + size;
|
msgpack::object_kv* const pend = p + size;
|
||||||
o.via.map.ptr = p;
|
o.via.map.ptr = p;
|
||||||
o.via.map.size = size;
|
o.via.map.size = size;
|
||||||
typename std::unordered_multimap<K,V>::const_iterator it(v.begin());
|
typename std::unordered_multimap<K, V, OtherTypes...>::const_iterator it(v.begin());
|
||||||
do {
|
do {
|
||||||
p->key = msgpack::object(it->first, o.zone);
|
p->key = msgpack::object(it->first, o.zone);
|
||||||
p->val = msgpack::object(it->second, o.zone);
|
p->val = msgpack::object(it->second, o.zone);
|
||||||
|
@ -32,44 +32,44 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
|
|
||||||
namespace adaptor {
|
namespace adaptor {
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct as<std::unordered_set<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
struct as<std::unordered_set<Key, OtherTypes...>, typename std::enable_if<msgpack::has_as<Key>::value>::type> {
|
||||||
std::unordered_set<T> operator()(msgpack::object const& o) const {
|
std::unordered_set<Key, OtherTypes...> operator()(msgpack::object const& o) const {
|
||||||
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||||
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
||||||
msgpack::object* const pbegin = o.via.array.ptr;
|
msgpack::object* const pbegin = o.via.array.ptr;
|
||||||
std::unordered_set<T> v;
|
std::unordered_set<Key, OtherTypes...> v;
|
||||||
while (p > pbegin) {
|
while (p > pbegin) {
|
||||||
--p;
|
--p;
|
||||||
v.insert(p->as<T>());
|
v.insert(p->as<Key>());
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct convert<std::unordered_set<T>> {
|
struct convert<std::unordered_set<Key, OtherTypes...>> {
|
||||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_set<T>& v) const {
|
msgpack::object const& operator()(msgpack::object const& o, std::unordered_set<Key, OtherTypes...>& v) const {
|
||||||
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||||
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
||||||
msgpack::object* const pbegin = o.via.array.ptr;
|
msgpack::object* const pbegin = o.via.array.ptr;
|
||||||
std::unordered_set<T> tmp;
|
std::unordered_set<Key, OtherTypes...> tmp;
|
||||||
while(p > pbegin) {
|
while(p > pbegin) {
|
||||||
--p;
|
--p;
|
||||||
tmp.insert(p->as<T>());
|
tmp.insert(p->as<Key>());
|
||||||
}
|
}
|
||||||
v = std::move(tmp);
|
v = std::move(tmp);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct pack<std::unordered_set<T>> {
|
struct pack<std::unordered_set<Key, OtherTypes...>> {
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_set<T>& v) const {
|
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_set<Key, OtherTypes...>& v) const {
|
||||||
uint32_t size = checked_get_container_size(v.size());
|
uint32_t size = checked_get_container_size(v.size());
|
||||||
o.pack_array(size);
|
o.pack_array(size);
|
||||||
for(typename std::unordered_set<T>::const_iterator it(v.begin()), it_end(v.end());
|
for(typename std::unordered_set<Key, OtherTypes...>::const_iterator it(v.begin()), it_end(v.end());
|
||||||
it != it_end; ++it) {
|
it != it_end; ++it) {
|
||||||
o.pack(*it);
|
o.pack(*it);
|
||||||
}
|
}
|
||||||
@ -77,9 +77,9 @@ struct pack<std::unordered_set<T>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct object_with_zone<std::unordered_set<T>> {
|
struct object_with_zone<std::unordered_set<Key, OtherTypes...>> {
|
||||||
void operator()(msgpack::object::with_zone& o, const std::unordered_set<T>& v) const {
|
void operator()(msgpack::object::with_zone& o, const std::unordered_set<Key, OtherTypes...>& v) const {
|
||||||
o.type = msgpack::type::ARRAY;
|
o.type = msgpack::type::ARRAY;
|
||||||
if(v.empty()) {
|
if(v.empty()) {
|
||||||
o.via.array.ptr = nullptr;
|
o.via.array.ptr = nullptr;
|
||||||
@ -90,7 +90,7 @@ struct object_with_zone<std::unordered_set<T>> {
|
|||||||
msgpack::object* const pend = p + size;
|
msgpack::object* const pend = p + size;
|
||||||
o.via.array.ptr = p;
|
o.via.array.ptr = p;
|
||||||
o.via.array.size = size;
|
o.via.array.size = size;
|
||||||
typename std::unordered_set<T>::const_iterator it(v.begin());
|
typename std::unordered_set<Key, OtherTypes...>::const_iterator it(v.begin());
|
||||||
do {
|
do {
|
||||||
*p = msgpack::object(*it, o.zone);
|
*p = msgpack::object(*it, o.zone);
|
||||||
++p;
|
++p;
|
||||||
@ -101,44 +101,44 @@ struct object_with_zone<std::unordered_set<T>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct as<std::unordered_multiset<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
struct as<std::unordered_multiset<Key, OtherTypes...>, typename std::enable_if<msgpack::has_as<Key>::value>::type> {
|
||||||
std::unordered_multiset<T> operator()(msgpack::object const& o) const {
|
std::unordered_multiset<Key, OtherTypes...> operator()(msgpack::object const& o) const {
|
||||||
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||||
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
||||||
msgpack::object* const pbegin = o.via.array.ptr;
|
msgpack::object* const pbegin = o.via.array.ptr;
|
||||||
std::unordered_multiset<T> v;
|
std::unordered_multiset<Key, OtherTypes...> v;
|
||||||
while (p > pbegin) {
|
while (p > pbegin) {
|
||||||
--p;
|
--p;
|
||||||
v.insert(p->as<T>());
|
v.insert(p->as<Key>());
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct convert<std::unordered_multiset<T>> {
|
struct convert<std::unordered_multiset<Key, OtherTypes...>> {
|
||||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_multiset<T>& v) const {
|
msgpack::object const& operator()(msgpack::object const& o, std::unordered_multiset<Key, OtherTypes...>& v) const {
|
||||||
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||||
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
msgpack::object* p = o.via.array.ptr + o.via.array.size;
|
||||||
msgpack::object* const pbegin = o.via.array.ptr;
|
msgpack::object* const pbegin = o.via.array.ptr;
|
||||||
std::unordered_multiset<T> tmp;
|
std::unordered_multiset<Key, OtherTypes...> tmp;
|
||||||
while(p > pbegin) {
|
while(p > pbegin) {
|
||||||
--p;
|
--p;
|
||||||
tmp.insert(p->as<T>());
|
tmp.insert(p->as<Key>());
|
||||||
}
|
}
|
||||||
v = std::move(tmp);
|
v = std::move(tmp);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct pack<std::unordered_multiset<T>> {
|
struct pack<std::unordered_multiset<Key, OtherTypes...>> {
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_multiset<T>& v) const {
|
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::unordered_multiset<Key, OtherTypes...>& v) const {
|
||||||
uint32_t size = checked_get_container_size(v.size());
|
uint32_t size = checked_get_container_size(v.size());
|
||||||
o.pack_array(size);
|
o.pack_array(size);
|
||||||
for(typename std::unordered_multiset<T>::const_iterator it(v.begin()), it_end(v.end());
|
for(typename std::unordered_multiset<Key, OtherTypes...>::const_iterator it(v.begin()), it_end(v.end());
|
||||||
it != it_end; ++it) {
|
it != it_end; ++it) {
|
||||||
o.pack(*it);
|
o.pack(*it);
|
||||||
}
|
}
|
||||||
@ -146,9 +146,9 @@ struct pack<std::unordered_multiset<T>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Key, typename... OtherTypes>
|
||||||
struct object_with_zone<std::unordered_multiset<T>> {
|
struct object_with_zone<std::unordered_multiset<Key, OtherTypes...>> {
|
||||||
void operator()(msgpack::object::with_zone& o, const std::unordered_multiset<T>& v) const {
|
void operator()(msgpack::object::with_zone& o, const std::unordered_multiset<Key, OtherTypes...>& v) const {
|
||||||
o.type = msgpack::type::ARRAY;
|
o.type = msgpack::type::ARRAY;
|
||||||
if(v.empty()) {
|
if(v.empty()) {
|
||||||
o.via.array.ptr = nullptr;
|
o.via.array.ptr = nullptr;
|
||||||
@ -159,7 +159,7 @@ struct object_with_zone<std::unordered_multiset<T>> {
|
|||||||
msgpack::object* const pend = p + size;
|
msgpack::object* const pend = p + size;
|
||||||
o.via.array.ptr = p;
|
o.via.array.ptr = p;
|
||||||
o.via.array.size = size;
|
o.via.array.size = size;
|
||||||
typename std::unordered_multiset<T>::const_iterator it(v.begin());
|
typename std::unordered_multiset<Key, OtherTypes...>::const_iterator it(v.begin());
|
||||||
do {
|
do {
|
||||||
*p = msgpack::object(*it, o.zone);
|
*p = msgpack::object(*it, o.zone);
|
||||||
++p;
|
++p;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user