1// 2// MessagePack for C++ static resolution routine 3// 4// Copyright (C) 2008-2015 FURUHASHI Sadayuki 5// 6// Distributed under the Boost Software License, Version 1.0. 7// (See accompanying file LICENSE_1_0.txt or copy at 8// http://www.boost.org/LICENSE_1_0.txt) 9// 10#ifndef MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP 11#define MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP 12 13#include "msgpack/versioning.hpp" 14#include "msgpack/adaptor/adaptor_base.hpp" 15#include "msgpack/adaptor/check_container_size.hpp" 16 17#if defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) 18 19#define MSGPACK_HAS_STD_UNORDERED_MAP 20#include <unordered_map> 21#define MSGPACK_STD_TR1 std 22 23#else // defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) 24 25#if __GNUC__ >= 4 26 27#define MSGPACK_HAS_STD_TR1_UNORDERED_MAP 28 29#include <tr1/unordered_map> 30#define MSGPACK_STD_TR1 std::tr1 31 32#endif // __GNUC__ >= 4 33 34#endif // defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) 35 36#if defined(MSGPACK_STD_TR1) 37 38namespace msgpack { 39 40/// @cond 41MSGPACK_API_VERSION_NAMESPACE(v1) { 42/// @endcond 43 44namespace adaptor { 45 46template <typename K, typename V, typename Hash, typename Pred, typename Alloc> 47struct convert<MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc> > { 48 msgpack::object const& operator()(msgpack::object const& o, MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc>& v) const { 49 if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); } 50 msgpack::object_kv* p(o.via.map.ptr); 51 msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size); 52 MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc> tmp; 53 for(; p != pend; ++p) { 54 K key; 55 p->key.convert(key); 56 p->val.convert(tmp[key]); 57 } 58 tmp.swap(v); 59 return o; 60 } 61}; 62 63template <typename K, typename V, typename Hash, typename Pred, typename Alloc> 64struct pack<MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc> > { 65 template <typename Stream> 66 msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc>& v) const { 67 uint32_t size = checked_get_container_size(v.size()); 68 o.pack_map(size); 69 for(typename MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc>::const_iterator it(v.begin()), it_end(v.end()); 70 it != it_end; ++it) { 71 o.pack(it->first); 72 o.pack(it->second); 73 } 74 return o; 75 } 76}; 77 78template <typename K, typename V, typename Hash, typename Pred, typename Alloc> 79struct object_with_zone<MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc> > { 80 void operator()(msgpack::object::with_zone& o, const MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc>& v) const { 81 o.type = msgpack::type::MAP; 82 if(v.empty()) { 83 o.via.map.ptr = nullptr; 84 o.via.map.size = 0; 85 } else { 86 uint32_t size = checked_get_container_size(v.size()); 87 msgpack::object_kv* p = static_cast<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size)); 88 msgpack::object_kv* const pend = p + size; 89 o.via.map.ptr = p; 90 o.via.map.size = size; 91 typename MSGPACK_STD_TR1::unordered_map<K, V, Hash, Pred, Alloc>::const_iterator it(v.begin()); 92 do { 93 p->key = msgpack::object(it->first, o.zone); 94 p->val = msgpack::object(it->second, o.zone); 95 ++p; 96 ++it; 97 } while(p < pend); 98 } 99 } 100}; 101 102template <typename K, typename V, typename Hash, typename Pred, typename Alloc> 103struct convert<MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc> > { 104 msgpack::object const& operator()(msgpack::object const& o, MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc>& v) const { 105 if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); } 106 msgpack::object_kv* p(o.via.map.ptr); 107 msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size); 108 MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc> tmp; 109 for(; p != pend; ++p) { 110 std::pair<K, V> value; 111 p->key.convert(value.first); 112 p->val.convert(value.second); 113 tmp.insert(value); 114 } 115 tmp.swap(v); 116 return o; 117 } 118}; 119 120template <typename K, typename V, typename Hash, typename Pred, typename Alloc> 121struct pack<MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc> > { 122 template <typename Stream> 123 msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc>& v) const { 124 uint32_t size = checked_get_container_size(v.size()); 125 o.pack_map(size); 126 for(typename MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc>::const_iterator it(v.begin()), it_end(v.end()); 127 it != it_end; ++it) { 128 o.pack(it->first); 129 o.pack(it->second); 130 } 131 return o; 132 } 133}; 134 135template <typename K, typename V, typename Hash, typename Pred, typename Alloc> 136struct object_with_zone<MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc> > { 137 void operator()(msgpack::object::with_zone& o, const MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc>& v) const { 138 o.type = msgpack::type::MAP; 139 if(v.empty()) { 140 o.via.map.ptr = nullptr; 141 o.via.map.size = 0; 142 } else { 143 uint32_t size = checked_get_container_size(v.size()); 144 msgpack::object_kv* p = static_cast<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size)); 145 msgpack::object_kv* const pend = p + size; 146 o.via.map.ptr = p; 147 o.via.map.size = size; 148 typename MSGPACK_STD_TR1::unordered_multimap<K, V, Hash, Pred, Alloc>::const_iterator it(v.begin()); 149 do { 150 p->key = msgpack::object(it->first, o.zone); 151 p->val = msgpack::object(it->second, o.zone); 152 ++p; 153 ++it; 154 } while(p < pend); 155 } 156 } 157}; 158 159} // namespace adaptor 160 161/// @cond 162} // MSGPACK_API_VERSION_NAMESPACE(v1) 163/// @endcond 164 165} // namespace msgpack 166 167#undef MSGPACK_STD_TR1 168 169#endif // MSGPACK_STD_TR1 170 171#endif // MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP 172