1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2014-2015 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_CPP11_ARRAY_HPP
#define MSGPACK_V1_TYPE_CPP11_ARRAY_HPP
#include "msgpack/versioning.hpp"
#include "msgpack/adaptor/adaptor_base.hpp"
#include "msgpack/adaptor/check_container_size.hpp"
#include "msgpack/meta.hpp"
#include <array>
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v1) {
/// @endcond
namespace adaptor {
namespace detail {
namespace array {
template<typename T, std::size_t N1, std::size_t... I1, std::size_t N2, std::size_t... I2>
inline std::array<T, N1+N2> concat(
std::array<T, N1>&& a1,
std::array<T, N2>&& a2,
msgpack::seq<I1...>,
msgpack::seq<I2...>) {
return {{ std::move(a1[I1])..., std::move(a2[I2])... }};
}
template<typename T, std::size_t N1, std::size_t N2>
inline std::array<T, N1+N2> concat(std::array<T, N1>&& a1, std::array<T, N2>&& a2) {
return concat(std::move(a1), std::move(a2), msgpack::gen_seq<N1>(), msgpack::gen_seq<N2>());
}
template <typename T, std::size_t N>
struct as_impl {
static std::array<T, N> as(msgpack::object const& o) {
msgpack::object* p = o.via.array.ptr + N - 1;
return concat(as_impl<T, N-1>::as(o), std::array<T, 1>{{p->as<T>()}});
}
};
template <typename T>
struct as_impl<T, 1> {
static std::array<T, 1> as(msgpack::object const& o) {
msgpack::object* p = o.via.array.ptr;
return std::array<T, 1>{{p->as<T>()}};
}
};
template <typename T>
struct as_impl<T, 0> {
static std::array<T, 0> as(msgpack::object const&) {
return std::array<T, 0>();
}
};
} // namespace array
} // namespace detail
template <typename T, std::size_t N>
struct as<std::array<T, N>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
std::array<T, N> operator()(msgpack::object const& o) const {
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
if(o.via.array.size > N) { throw msgpack::type_error(); }
return detail::array::as_impl<T, N>::as(o);
}
};
template <typename T, std::size_t N>
struct convert<std::array<T, N>> {
msgpack::object const& operator()(msgpack::object const& o, std::array<T, N>& v) const {
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
if(o.via.array.size > N) { throw msgpack::type_error(); }
if(o.via.array.size > 0) {
msgpack::object* p = o.via.array.ptr;
msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
T* it = &v[0];
do {
p->convert(*it);
++p;
++it;
} while(p < pend);
}
return o;
}
};
template <typename T, std::size_t N>
struct pack<std::array<T, N>> {
template <typename Stream>
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::array<T, N>& v) const {
uint32_t size = checked_get_container_size(v.size());
o.pack_array(size);
for(auto const& e : v) o.pack(e);
return o;
}
};
template <typename T, std::size_t N>
struct object_with_zone<std::array<T, N>> {
void operator()(msgpack::object::with_zone& o, const std::array<T, N>& v) const {
o.type = msgpack::type::ARRAY;
if(v.empty()) {
o.via.array.ptr = MSGPACK_NULLPTR;
o.via.array.size = 0;
} else {
uint32_t size = checked_get_container_size(v.size());
msgpack::object* p = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
o.via.array.size = size;
o.via.array.ptr = p;
for (auto const& e : v) *p++ = msgpack::object(e, o.zone);
}
}
};
} // namespace adaptor
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v1)
/// @endcond
} // namespace msgpack
#endif // MSGPACK_V1_TYPE_CPP11_ARRAY_HPP
|