123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- //
- // MessagePack for C++ static resolution routine
- //
- // Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef MSGPACK_V1_TYPE_MAP_HPP
- #define MSGPACK_V1_TYPE_MAP_HPP
- #include "msgpack/v1/adaptor/map_decl.hpp"
- #include "msgpack/adaptor/adaptor_base.hpp"
- #include <map>
- #include <vector>
- namespace msgpack {
- /// @cond
- MSGPACK_API_VERSION_NAMESPACE(v1) {
- /// @endcond
- namespace type {
- template <typename K, typename V, typename Compare, typename Alloc>
- class assoc_vector : public std::vector< std::pair<K, V>, Alloc > {
- #if !defined(MSGPACK_USE_CPP03)
- using std::vector<std::pair<K, V>, Alloc>::vector;
- #endif // !defined(MSGPACK_USE_CPP03)
- };
- namespace detail {
- template <typename K, typename V, typename Compare, typename Alloc>
- struct pair_first_less {
- bool operator() (const std::pair<K, V>& x, const std::pair<K, V>& y) const
- { return Compare()(x.first, y.first); }
- };
- }
- } //namespace type
- namespace adaptor {
- #if !defined(MSGPACK_USE_CPP03)
- template <typename K, typename V, typename Compare, typename Alloc>
- struct as<
- type::assoc_vector<K, V, Compare, Alloc>,
- typename std::enable_if<msgpack::has_as<K>::value || msgpack::has_as<V>::value>::type> {
- type::assoc_vector<K, V, Compare, Alloc> operator()(msgpack::object const& o) const {
- if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
- type::assoc_vector<K, V, Compare, Alloc> v;
- v.reserve(o.via.map.size);
- msgpack::object_kv* p = o.via.map.ptr;
- msgpack::object_kv* const pend = o.via.map.ptr + o.via.map.size;
- for (; p < pend; ++p) {
- v.emplace_back(p->key.as<K>(), p->val.as<V>());
- }
- std::sort(v.begin(), v.end(), type::detail::pair_first_less<K, V, Compare, Alloc>());
- return v;
- }
- };
- #endif // !defined(MSGPACK_USE_CPP03)
- template <typename K, typename V, typename Compare, typename Alloc>
- struct convert<type::assoc_vector<K, V, Compare, Alloc> > {
- msgpack::object const& operator()(msgpack::object const& o, type::assoc_vector<K, V, Compare, Alloc>& v) const {
- if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
- v.resize(o.via.map.size);
- if (o.via.map.size != 0) {
- msgpack::object_kv* p = o.via.map.ptr;
- msgpack::object_kv* const pend = o.via.map.ptr + o.via.map.size;
- std::pair<K, V>* it(&v.front());
- for (; p < pend; ++p, ++it) {
- p->key.convert(it->first);
- p->val.convert(it->second);
- }
- std::sort(v.begin(), v.end(), type::detail::pair_first_less<K, V, Compare, Alloc>());
- }
- return o;
- }
- };
- template <typename K, typename V, typename Compare, typename Alloc>
- struct pack<type::assoc_vector<K, V, Compare, Alloc> > {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const type::assoc_vector<K, V, Compare, Alloc>& v) const {
- uint32_t size = checked_get_container_size(v.size());
- o.pack_map(size);
- for (typename type::assoc_vector<K, V, Compare, Alloc>::const_iterator it(v.begin()), it_end(v.end());
- it != it_end; ++it) {
- o.pack(it->first);
- o.pack(it->second);
- }
- return o;
- }
- };
- template <typename K, typename V, typename Compare, typename Alloc>
- struct object_with_zone<type::assoc_vector<K, V, Compare, Alloc> > {
- void operator()(msgpack::object::with_zone& o, const type::assoc_vector<K, V, Compare, Alloc>& v) const {
- o.type = msgpack::type::MAP;
- if (v.empty()) {
- o.via.map.ptr = MSGPACK_NULLPTR;
- o.via.map.size = 0;
- }
- else {
- uint32_t size = checked_get_container_size(v.size());
- msgpack::object_kv* p = static_cast<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size, MSGPACK_ZONE_ALIGNOF(msgpack::object_kv)));
- msgpack::object_kv* const pend = p + size;
- o.via.map.ptr = p;
- o.via.map.size = size;
- typename type::assoc_vector<K, V, Compare, Alloc>::const_iterator it(v.begin());
- do {
- p->key = msgpack::object(it->first, o.zone);
- p->val = msgpack::object(it->second, o.zone);
- ++p;
- ++it;
- } while(p < pend);
- }
- }
- };
- #if !defined(MSGPACK_USE_CPP03)
- template <typename K, typename V, typename Compare, typename Alloc>
- struct as<
- std::map<K, V, Compare, Alloc>,
- typename std::enable_if<msgpack::has_as<K>::value || msgpack::has_as<V>::value>::type> {
- std::map<K, V, Compare, Alloc> operator()(msgpack::object const& o) const {
- if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
- msgpack::object_kv* p(o.via.map.ptr);
- msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
- std::map<K, V, Compare, Alloc> v;
- for (; p != pend; ++p) {
- v.emplace(p->key.as<K>(), p->val.as<V>());
- }
- return v;
- }
- };
- #endif // !defined(MSGPACK_USE_CPP03)
- template <typename K, typename V, typename Compare, typename Alloc>
- struct convert<std::map<K, V, Compare, Alloc> > {
- msgpack::object const& operator()(msgpack::object const& o, std::map<K, V, Compare, Alloc>& v) const {
- if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
- msgpack::object_kv* p(o.via.map.ptr);
- msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
- std::map<K, V, Compare, Alloc> tmp;
- for (; p != pend; ++p) {
- K key;
- p->key.convert(key);
- #if __cplusplus >= 201103L
- p->val.convert(tmp[std::move(key)]);
- #else
- p->val.convert(tmp[key]);
- #endif
- }
- #if __cplusplus >= 201103L
- v = std::move(tmp);
- #else
- tmp.swap(v);
- #endif
- return o;
- }
- };
- template <typename K, typename V, typename Compare, typename Alloc>
- struct pack<std::map<K, V, Compare, Alloc> > {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::map<K, V, Compare, Alloc>& v) const {
- uint32_t size = checked_get_container_size(v.size());
- o.pack_map(size);
- for (typename std::map<K, V, Compare, Alloc>::const_iterator it(v.begin()), it_end(v.end());
- it != it_end; ++it) {
- o.pack(it->first);
- o.pack(it->second);
- }
- return o;
- }
- };
- template <typename K, typename V, typename Compare, typename Alloc>
- struct object_with_zone<std::map<K, V, Compare, Alloc> > {
- void operator()(msgpack::object::with_zone& o, const std::map<K, V, Compare, Alloc>& v) const {
- o.type = msgpack::type::MAP;
- if (v.empty()) {
- o.via.map.ptr = MSGPACK_NULLPTR;
- o.via.map.size = 0;
- }
- else {
- uint32_t size = checked_get_container_size(v.size());
- msgpack::object_kv* p = static_cast<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size, MSGPACK_ZONE_ALIGNOF(msgpack::object_kv)));
- msgpack::object_kv* const pend = p + size;
- o.via.map.ptr = p;
- o.via.map.size = size;
- typename std::map<K, V, Compare, Alloc>::const_iterator it(v.begin());
- do {
- #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
- #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
- p->key = msgpack::object(it->first, o.zone);
- p->val = msgpack::object(it->second, o.zone);
- #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
- #pragma GCC diagnostic pop
- #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
- ++p;
- ++it;
- } while(p < pend);
- }
- }
- };
- #if !defined(MSGPACK_USE_CPP03)
- template <typename K, typename V, typename Compare, typename Alloc>
- struct as<
- std::multimap<K, V, Compare, Alloc>,
- typename std::enable_if<msgpack::has_as<K>::value || msgpack::has_as<V>::value>::type> {
- std::multimap<K, V, Compare, Alloc> operator()(msgpack::object const& o) const {
- if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
- msgpack::object_kv* p(o.via.map.ptr);
- msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
- std::multimap<K, V, Compare, Alloc> v;
- for (; p != pend; ++p) {
- v.emplace(p->key.as<K>(), p->val.as<V>());
- }
- return v;
- }
- };
- #endif // !defined(MSGPACK_USE_CPP03)
- template <typename K, typename V, typename Compare, typename Alloc>
- struct convert<std::multimap<K, V, Compare, Alloc> > {
- msgpack::object const& operator()(msgpack::object const& o, std::multimap<K, V, Compare, Alloc>& v) const {
- if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
- msgpack::object_kv* p(o.via.map.ptr);
- msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
- std::multimap<K, V, Compare, Alloc> tmp;
- for (; p != pend; ++p) {
- std::pair<K, V> value;
- p->key.convert(value.first);
- p->val.convert(value.second);
- #if __cplusplus >= 201103L
- tmp.insert(std::move(value));
- #else
- tmp.insert(value);
- #endif
- }
- #if __cplusplus >= 201103L
- v = std::move(tmp);
- #else
- tmp.swap(v);
- #endif
- return o;
- }
- };
- template <typename K, typename V, typename Compare, typename Alloc>
- struct pack<std::multimap<K, V, Compare, Alloc> > {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::multimap<K, V, Compare, Alloc>& v) const {
- uint32_t size = checked_get_container_size(v.size());
- o.pack_map(size);
- for (typename std::multimap<K, V, Compare, Alloc>::const_iterator it(v.begin()), it_end(v.end());
- it != it_end; ++it) {
- o.pack(it->first);
- o.pack(it->second);
- }
- return o;
- }
- };
- template <typename K, typename V, typename Compare, typename Alloc>
- struct object_with_zone<std::multimap<K, V, Compare, Alloc> > {
- void operator()(msgpack::object::with_zone& o, const std::multimap<K, V, Compare, Alloc>& v) const {
- o.type = msgpack::type::MAP;
- if (v.empty()) {
- o.via.map.ptr = MSGPACK_NULLPTR;
- o.via.map.size = 0;
- }
- else {
- uint32_t size = checked_get_container_size(v.size());
- msgpack::object_kv* p = static_cast<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size, MSGPACK_ZONE_ALIGNOF(msgpack::object_kv)));
- msgpack::object_kv* const pend = p + size;
- o.via.map.ptr = p;
- o.via.map.size = size;
- typename std::multimap<K, V, Compare, Alloc>::const_iterator it(v.begin());
- do {
- p->key = msgpack::object(it->first, o.zone);
- p->val = msgpack::object(it->second, o.zone);
- ++p;
- ++it;
- } while(p < pend);
- }
- }
- };
- } // namespace adaptor
- /// @cond
- } // MSGPACK_API_VERSION_NAMESPACE(v1)
- /// @endcond
- } // namespace msgpack
- #endif // MSGPACK_V1_TYPE_MAP_HPP
|