diff --git a/CMakeLists.txt b/CMakeLists.txt index bf0f32b5..8af0b372 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,6 +146,7 @@ IF (MSGPACK_ENABLE_CXX) include/msgpack/detail/cpp03_zone.hpp include/msgpack/detail/cpp11_zone.hpp include/msgpack/fbuffer.hpp + include/msgpack/meta.hpp include/msgpack/object.hpp include/msgpack/object_fwd.hpp include/msgpack/pack.hpp @@ -201,8 +202,8 @@ IF (MSGPACK_BUILD_TESTS) ENDIF () IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - SET_PROPERTY (TARGET msgpack APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -g -O3 -DPIC") - SET_PROPERTY (TARGET msgpack-static APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -g -O3" ) + SET_PROPERTY (TARGET msgpack APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Wno-mismatched-tags -Werror -g -O3 -DPIC") + SET_PROPERTY (TARGET msgpack-static APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Wno-mismatched-tags -Werror -g -O3" ) ENDIF () IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]") diff --git a/configure.in b/configure.in index 63812344..e5d4e152 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_SUBST(CFLAGS) CFLAGS="-O3 -Wall -Wextra -Werror $CFLAGS" AC_SUBST(CXXFLAGS) -CXXFLAGS="-O3 -Wall -Wextra -Werror $CXXFLAGS" +CXXFLAGS="-O3 -Wall -Wextra -Wno-mismatched-tags -Werror $CXXFLAGS" AC_PROG_CC diff --git a/include/msgpack/adaptor/cpp11/array.hpp b/include/msgpack/adaptor/cpp11/array.hpp index d1bc7ca5..5f15453e 100644 --- a/include/msgpack/adaptor/cpp11/array.hpp +++ b/include/msgpack/adaptor/cpp11/array.hpp @@ -33,6 +33,56 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +namespace detail { + +template struct seq {}; + +template +struct gen_seq : gen_seq {}; + +template +struct gen_seq<0, Is...> : seq {}; + +template +inline std::array concat( + std::array&& a1, + std::array&& a2, + seq, + seq) { + return {{ std::move(a1[I1])..., std::move(a2[I2])... }}; +} + +template +inline std::array concat(std::array&& a1, std::array&& a2) { + return concat(std::move(a1), std::move(a2), gen_seq(), gen_seq()); +} + +template +struct as_impl { + static std::array as(msgpack::object const& o) { + msgpack::object* p = o.via.array.ptr + N - 1; + return concat(as_impl::as(o), std::array{{p->as()}}); + } +}; + +template +struct as_impl { + static std::array as(msgpack::object const&) { + return std::array(); + } +}; + +} // namespace detail + +template +struct as, typename std::enable_if::value>::type> { + std::array 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::as_impl::as(o); + } +}; + template struct convert> { msgpack::object const& operator()(msgpack::object const& o, std::array& v) const { diff --git a/include/msgpack/adaptor/cpp11/forward_list.hpp b/include/msgpack/adaptor/cpp11/forward_list.hpp index 337fc20a..d4cdfceb 100644 --- a/include/msgpack/adaptor/cpp11/forward_list.hpp +++ b/include/msgpack/adaptor/cpp11/forward_list.hpp @@ -33,6 +33,21 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +template +struct as, typename std::enable_if::value>::type> { + std::forward_list operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + std::forward_list v; + msgpack::object* p = o.via.array.ptr + o.via.array.size; + msgpack::object* const pend = o.via.array.ptr; + while (p != pend) { + --p; + v.push_front(p->as()); + } + return v; + } +}; + template struct convert> { msgpack::object const& operator()(msgpack::object const& o, std::forward_list& v) const { diff --git a/include/msgpack/adaptor/cpp11/tuple.hpp b/include/msgpack/adaptor/cpp11/tuple.hpp index f7a7ea37..b4db3e75 100644 --- a/include/msgpack/adaptor/cpp11/tuple.hpp +++ b/include/msgpack/adaptor/cpp11/tuple.hpp @@ -21,6 +21,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/adaptor/adaptor_base.hpp" #include "msgpack/adaptor/check_container_size.hpp" +#include "msgpack/meta.hpp" #include @@ -41,15 +42,6 @@ struct StdTuplePacker { } }; -template -struct StdTuplePacker { - static void pack ( - msgpack::packer& o, - const Tuple& v) { - o.pack(std::get<0>(v)); - } -}; - template struct StdTuplePacker { static void pack ( @@ -77,6 +69,32 @@ struct pack> { // --- Convert from tuple to object --- +template +struct StdTupleAs; + +template +struct StdTupleAsImpl { + static std::tuple as(msgpack::object const& o) { + return std::tuple_cat( + std::make_tuple(o.via.array.ptr[o.via.array.size - sizeof...(Args) - 1].as()), + StdTupleAs::as(o)); + } +}; + +template +struct StdTupleAs { + static std::tuple as(msgpack::object const& o) { + return StdTupleAsImpl::as(o); + } +}; + +template <> +struct StdTupleAs<> { + static std::tuple<> as (msgpack::object const&) { + return std::tuple<>(); + } +}; + template struct StdTupleConverter { static void convert( @@ -87,15 +105,6 @@ struct StdTupleConverter { } }; -template -struct StdTupleConverter { - static void convert ( - msgpack::object const& o, - Tuple& v) { - o.via.array.ptr[0].convert(v))>::type>(std::get<0>(v)); - } -}; - template struct StdTupleConverter { static void convert ( @@ -106,6 +115,16 @@ struct StdTupleConverter { namespace adaptor { +template +struct as, typename std::enable_if::value>::type> { + std::tuple operator()( + msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + if (o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); } + return StdTupleAs::as(o); + } +}; + template struct convert> { msgpack::object const& operator()( @@ -131,15 +150,6 @@ struct StdTupleToObjectWithZone { } }; -template -struct StdTupleToObjectWithZone { - static void convert ( - msgpack::object::with_zone& o, - const Tuple& v) { - o.via.array.ptr[0] = msgpack::object(std::get<0>(v), o.zone); - } -}; - template struct StdTupleToObjectWithZone { static void convert ( diff --git a/include/msgpack/adaptor/cpp11/unordered_map.hpp b/include/msgpack/adaptor/cpp11/unordered_map.hpp index 3fe22907..9dd704bd 100644 --- a/include/msgpack/adaptor/cpp11/unordered_map.hpp +++ b/include/msgpack/adaptor/cpp11/unordered_map.hpp @@ -32,6 +32,22 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +template +struct as< + std::unordered_map, + typename std::enable_if::value && msgpack::has_as::value>::type> { + std::unordered_map 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::unordered_map v; + for (; p != pend; ++p) { + v.emplace(p->key.as(), p->val.as()); + } + return v; + } +}; + template struct convert> { msgpack::object const& operator()(msgpack::object const& o, std::unordered_map& v) const { @@ -89,6 +105,22 @@ struct object_with_zone> { }; +template +struct as< + std::unordered_multimap, + typename std::enable_if::value && msgpack::has_as::value>::type> { + std::unordered_multimap 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::unordered_multimap v; + for (; p != pend; ++p) { + v.emplace(p->key.as(), p->val.as()); + } + return v; + } +}; + template struct convert> { msgpack::object const& operator()(msgpack::object const& o, std::unordered_multimap& v) const { diff --git a/include/msgpack/adaptor/cpp11/unordered_set.hpp b/include/msgpack/adaptor/cpp11/unordered_set.hpp index b38ae339..8735dc15 100644 --- a/include/msgpack/adaptor/cpp11/unordered_set.hpp +++ b/include/msgpack/adaptor/cpp11/unordered_set.hpp @@ -32,6 +32,21 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +template +struct as, typename std::enable_if::value>::type> { + std::unordered_set operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + msgpack::object* p = o.via.array.ptr + o.via.array.size; + msgpack::object* const pbegin = o.via.array.ptr; + std::unordered_set v; + while (p > pbegin) { + --p; + v.insert(p->as()); + } + return v; + } +}; + template struct convert> { msgpack::object const& operator()(msgpack::object const& o, std::unordered_set& v) const { @@ -86,6 +101,21 @@ struct object_with_zone> { }; +template +struct as, typename std::enable_if::value>::type> { + std::unordered_multiset operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + msgpack::object* p = o.via.array.ptr + o.via.array.size; + msgpack::object* const pbegin = o.via.array.ptr; + std::unordered_multiset v; + while (p > pbegin) { + --p; + v.insert(p->as()); + } + return v; + } +}; + template struct convert> { msgpack::object const& operator()(msgpack::object const& o, std::unordered_multiset& v) const { diff --git a/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp b/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp index 88e57c08..3aab03c8 100644 --- a/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp +++ b/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2014 FURUHASHI Sadayuki and KONDO Takatoshi +// Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/meta.hpp" #include @@ -36,9 +37,7 @@ namespace type { using std::tuple_element; using std::uses_allocator; using std::ignore; - using std::make_tuple; using std::tie; - using std::forward_as_tuple; using std::swap; template< class... Types > @@ -84,8 +83,18 @@ namespace type { get() && { return std::get(*this); } }; - template< class... Tuples > - auto tuple_cat(Tuples&&... args) -> + template + inline tuple make_tuple(Args&&... args) { + return tuple(args...); + } + + template + inline tuple forward_as_tuple (Args&&... args) noexcept { + return tuple(std::forward(args)...); + } + + template + inline auto tuple_cat(Tuples&&... args) -> decltype( std::tuple_cat(std::forward::type::base>(args)...) ) { @@ -124,11 +133,11 @@ struct MsgpackTuplePacker { namespace adaptor { template -struct pack> { +struct pack> { template msgpack::packer& operator()( msgpack::packer& o, - const type::tuple& v) const { + const msgpack::type::tuple& v) const { o.pack_array(sizeof...(Args)); MsgpackTuplePacker::pack(o, v); return o; @@ -139,6 +148,32 @@ struct pack> { // --- Convert from tuple to object --- +template +struct MsgpackTupleAs; + +template +struct MsgpackTupleAsImpl { + static msgpack::type::tuple as(msgpack::object const& o) { + return msgpack::type::tuple_cat( + msgpack::type::make_tuple(o.via.array.ptr[o.via.array.size - sizeof...(Args) - 1].as()), + MsgpackTupleAs::as(o)); + } +}; + +template +struct MsgpackTupleAs { + static msgpack::type::tuple as(msgpack::object const& o) { + return MsgpackTupleAsImpl::as(o); + } +}; + +template <> +struct MsgpackTupleAs<> { + static msgpack::type::tuple<> as (msgpack::object const&) { + return msgpack::type::tuple<>(); + } +}; + template struct MsgpackTupleConverter { static void convert( @@ -169,10 +204,20 @@ struct MsgpackTupleConverter { namespace adaptor { template -struct convert> { +struct as, typename std::enable_if::value>::type> { + msgpack::type::tuple operator()( + msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + if (o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); } + return MsgpackTupleAs::as(o); + } +}; + +template +struct convert> { msgpack::object const& operator()( msgpack::object const& o, - type::tuple& v) const { + msgpack::type::tuple& v) const { if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } if(o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); } MsgpackTupleConverter::convert(o, v); @@ -213,10 +258,10 @@ struct MsgpackTupleToObjectWithZone { namespace adaptor { template - struct object_with_zone> { + struct object_with_zone> { void operator()( msgpack::object::with_zone& o, - type::tuple const& v) const { + msgpack::type::tuple const& v) const { o.type = msgpack::type::ARRAY; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object)*sizeof...(Args))); o.via.array.size = sizeof...(Args); diff --git a/include/msgpack/adaptor/list.hpp b/include/msgpack/adaptor/list.hpp index 2df460c6..938e6d75 100644 --- a/include/msgpack/adaptor/list.hpp +++ b/include/msgpack/adaptor/list.hpp @@ -32,15 +32,33 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +#if !defined(MSGPACK_USE_CPP03) + +template +struct as, typename std::enable_if::value>::type> { + std::list operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + std::list v; + msgpack::object* p = o.via.array.ptr; + msgpack::object* const pend = o.via.array.ptr + o.via.array.size; + for (; p < pend; ++p) { + v.push_back(p->as()); + } + return v; + } +}; + +#endif // !defined(MSGPACK_USE_CPP03) + template struct convert > { msgpack::object const& operator()(msgpack::object const& o, std::list& v) const { - if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } v.resize(o.via.array.size); msgpack::object* p = o.via.array.ptr; msgpack::object* const pend = o.via.array.ptr + o.via.array.size; typename std::list::iterator it = v.begin(); - for(; p < pend; ++p, ++it) { + for (; p < pend; ++p, ++it) { p->convert(*it); } return o; @@ -53,7 +71,7 @@ struct pack > { msgpack::packer& operator()(msgpack::packer& o, const std::list& v) const { uint32_t size = checked_get_container_size(v.size()); o.pack_array(size); - for(typename std::list::const_iterator it(v.begin()), it_end(v.end()); + for (typename std::list::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); } @@ -65,10 +83,11 @@ template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const std::list& v) const { o.type = msgpack::type::ARRAY; - if(v.empty()) { + if (v.empty()) { o.via.array.ptr = nullptr; o.via.array.size = 0; - } else { + } + else { uint32_t size = checked_get_container_size(v.size()); msgpack::object* p = static_cast(o.zone.allocate_align(sizeof(msgpack::object)*size)); msgpack::object* const pend = p + size; diff --git a/include/msgpack/adaptor/map.hpp b/include/msgpack/adaptor/map.hpp index 53ee1a74..26b176b8 100644 --- a/include/msgpack/adaptor/map.hpp +++ b/include/msgpack/adaptor/map.hpp @@ -35,7 +35,11 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace type { template -class assoc_vector : public std::vector< std::pair > {}; +class assoc_vector : public std::vector< std::pair > { +#if !defined(MSGPACK_USE_CPP03) + using std::vector>::vector; +#endif // !defined(MSGPACK_USE_CPP03) +}; namespace detail { template @@ -49,15 +53,37 @@ namespace detail { namespace adaptor { +#if !defined(MSGPACK_USE_CPP03) + +template +struct as< + type::assoc_vector, + typename std::enable_if::value && msgpack::has_as::value>::type> { + type::assoc_vector operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); } + type::assoc_vector 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(), p->val.as()); + } + std::sort(v.begin(), v.end(), type::detail::pair_first_less()); + return v; + } +}; + +#endif // !defined(MSGPACK_USE_CPP03) + template struct convert > { msgpack::object const& operator()(msgpack::object const& o, type::assoc_vector& v) const { - if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); } + if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); } v.resize(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; std::pair* it(&v.front()); - for(; p < pend; ++p, ++it) { + for (; p < pend; ++p, ++it) { p->key.convert(it->first); p->val.convert(it->second); } @@ -72,7 +98,7 @@ struct pack > { msgpack::packer& operator()(msgpack::packer& o, const type::assoc_vector& v) const { uint32_t size = checked_get_container_size(v.size()); o.pack_map(size); - for(typename type::assoc_vector::const_iterator it(v.begin()), it_end(v.end()); + for (typename type::assoc_vector::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(it->first); o.pack(it->second); @@ -85,10 +111,11 @@ template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const type::assoc_vector& v) const { o.type = msgpack::type::MAP; - if(v.empty()) { + if (v.empty()) { o.via.map.ptr = nullptr; o.via.map.size = 0; - } else { + } + else { uint32_t size = checked_get_container_size(v.size()); msgpack::object_kv* p = static_cast(o.zone.allocate_align(sizeof(msgpack::object_kv)*size)); msgpack::object_kv* const pend = p + size; @@ -105,14 +132,34 @@ struct object_with_zone > { } }; +#if !defined(MSGPACK_USE_CPP03) + +template +struct as< + std::map, + typename std::enable_if::value && msgpack::has_as::value>::type> { + std::map 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 v; + for (; p != pend; ++p) { + v.emplace(p->key.as(), p->val.as()); + } + return v; + } +}; + +#endif // !defined(MSGPACK_USE_CPP03) + template struct convert > { msgpack::object const& operator()(msgpack::object const& o, std::map& 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* const pend(o.via.map.ptr + o.via.map.size); std::map tmp; - for(; p != pend; ++p) { + for (; p != pend; ++p) { K key; p->key.convert(key); #if __cplusplus >= 201103L @@ -136,7 +183,7 @@ struct pack > { msgpack::packer& operator()(msgpack::packer& o, const std::map& v) const { uint32_t size = checked_get_container_size(v.size()); o.pack_map(size); - for(typename std::map::const_iterator it(v.begin()), it_end(v.end()); + for (typename std::map::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(it->first); o.pack(it->second); @@ -149,10 +196,11 @@ template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const std::map& v) const { o.type = msgpack::type::MAP; - if(v.empty()) { + if (v.empty()) { o.via.map.ptr = nullptr; o.via.map.size = 0; - } else { + } + else { uint32_t size = checked_get_container_size(v.size()); msgpack::object_kv* p = static_cast(o.zone.allocate_align(sizeof(msgpack::object_kv)*size)); msgpack::object_kv* const pend = p + size; @@ -169,15 +217,34 @@ struct object_with_zone > { } }; +#if !defined(MSGPACK_USE_CPP03) + +template +struct as< + std::multimap, + typename std::enable_if::value && msgpack::has_as::value>::type> { + std::multimap 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 v; + for (; p != pend; ++p) { + v.emplace(p->key.as(), p->val.as()); + } + return v; + } +}; + +#endif // !defined(MSGPACK_USE_CPP03) template struct convert > { msgpack::object const& operator()(msgpack::object const& o, std::multimap& 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* const pend(o.via.map.ptr + o.via.map.size); std::multimap tmp; - for(; p != pend; ++p) { + for (; p != pend; ++p) { std::pair value; p->key.convert(value.first); p->val.convert(value.second); @@ -202,7 +269,7 @@ struct pack > { msgpack::packer& operator()(msgpack::packer& o, const std::multimap& v) const { uint32_t size = checked_get_container_size(v.size()); o.pack_map(size); - for(typename std::multimap::const_iterator it(v.begin()), it_end(v.end()); + for (typename std::multimap::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(it->first); o.pack(it->second); @@ -215,10 +282,11 @@ template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const std::multimap& v) const { o.type = msgpack::type::MAP; - if(v.empty()) { + if (v.empty()) { o.via.map.ptr = nullptr; o.via.map.size = 0; - } else { + } + else { uint32_t size = checked_get_container_size(v.size()); msgpack::object_kv* p = static_cast(o.zone.allocate_align(sizeof(msgpack::object_kv)*size)); msgpack::object_kv* const pend = p + size; diff --git a/include/msgpack/adaptor/pair.hpp b/include/msgpack/adaptor/pair.hpp index f7a6784d..4ddc56a6 100644 --- a/include/msgpack/adaptor/pair.hpp +++ b/include/msgpack/adaptor/pair.hpp @@ -30,6 +30,19 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +#if !defined(MSGPACK_USE_CPP03) + +template +struct as> { + std::pair operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + if (o.via.array.size != 2) { throw msgpack::type_error(); } + return std::make_pair(o.via.array.ptr[0].as(), o.via.array.ptr[1].as()); + } +}; + +#endif // !defined(MSGPACK_USE_CPP03) + template struct convert > { msgpack::object const& operator()(msgpack::object const& o, std::pair& v) const { diff --git a/include/msgpack/adaptor/set.hpp b/include/msgpack/adaptor/set.hpp index 82aa2f55..eb43d630 100644 --- a/include/msgpack/adaptor/set.hpp +++ b/include/msgpack/adaptor/set.hpp @@ -32,14 +32,33 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +#if !defined(MSGPACK_USE_CPP03) + +template +struct as, typename std::enable_if::value>::type> { + std::set operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + msgpack::object* p = o.via.array.ptr + o.via.array.size; + msgpack::object* const pbegin = o.via.array.ptr; + std::set v; + while (p > pbegin) { + --p; + v.insert(p->as()); + } + return v; + } +}; + +#endif // !defined(MSGPACK_USE_CPP03) + template struct convert > { msgpack::object const& operator()(msgpack::object const& o, std::set& 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* const pbegin = o.via.array.ptr; std::set tmp; - while(p > pbegin) { + while (p > pbegin) { --p; tmp.insert(p->as()); } @@ -58,7 +77,7 @@ struct pack > { msgpack::packer& operator()(msgpack::packer& o, const std::set& v) const { uint32_t size = checked_get_container_size(v.size()); o.pack_array(size); - for(typename std::set::const_iterator it(v.begin()), it_end(v.end()); + for (typename std::set::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); } @@ -70,10 +89,11 @@ template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const std::set& v) const { o.type = msgpack::type::ARRAY; - if(v.empty()) { + if (v.empty()) { o.via.array.ptr = nullptr; o.via.array.size = 0; - } else { + } + else { uint32_t size = checked_get_container_size(v.size()); msgpack::object* p = static_cast(o.zone.allocate_align(sizeof(msgpack::object)*size)); msgpack::object* const pend = p + size; @@ -89,14 +109,33 @@ struct object_with_zone > { } }; +#if !defined(MSGPACK_USE_CPP03) + +template +struct as, typename std::enable_if::value>::type> { + std::multiset operator()(msgpack::object const& o) const { + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + msgpack::object* p = o.via.array.ptr + o.via.array.size; + msgpack::object* const pbegin = o.via.array.ptr; + std::multiset v; + while (p > pbegin) { + --p; + v.insert(p->as()); + } + return v; + } +}; + +#endif // !defined(MSGPACK_USE_CPP03) + template struct convert > { msgpack::object const& operator()(msgpack::object const& o, std::multiset& 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* const pbegin = o.via.array.ptr; std::multiset tmp; - while(p > pbegin) { + while (p > pbegin) { --p; tmp.insert(p->as()); } @@ -115,7 +154,7 @@ struct pack > { msgpack::packer& operator()(msgpack::packer& o, const std::multiset& v) const { uint32_t size = checked_get_container_size(v.size()); o.pack_array(size); - for(typename std::multiset::const_iterator it(v.begin()), it_end(v.end()); + for (typename std::multiset::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); } @@ -127,7 +166,7 @@ template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const std::multiset& v) const { o.type = msgpack::type::ARRAY; - if(v.empty()) { + if (v.empty()) { o.via.array.ptr = nullptr; o.via.array.size = 0; } else { diff --git a/include/msgpack/adaptor/vector.hpp b/include/msgpack/adaptor/vector.hpp index 69fa1026..e8b4ba4c 100644 --- a/include/msgpack/adaptor/vector.hpp +++ b/include/msgpack/adaptor/vector.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,30 +33,33 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { #if !defined(MSGPACK_USE_CPP03) + template -struct as> { +struct as, typename std::enable_if::value>::type> { std::vector operator()(const msgpack::object& o) const { if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } std::vector v; + v.reserve(o.via.array.size); 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; do { - v.emplace_back(p->as()); + v.push_back(p->as()); ++p; } while (p < pend); } return v; } }; -#endif + +#endif // !defined(MSGPACK_USE_CPP03) template struct convert > { msgpack::object const& operator()(msgpack::object const& o, std::vector& v) const { - if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } v.resize(o.via.array.size); - if(o.via.array.size > 0) { + 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; typename std::vector::iterator it = v.begin(); @@ -76,7 +79,7 @@ struct pack > { msgpack::packer& operator()(msgpack::packer& o, const std::vector& v) const { uint32_t size = checked_get_container_size(v.size()); o.pack_array(size); - for(typename std::vector::const_iterator it(v.begin()), it_end(v.end()); + for (typename std::vector::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); } @@ -88,10 +91,11 @@ template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const std::vector& v) const { o.type = msgpack::type::ARRAY; - if(v.empty()) { + if (v.empty()) { o.via.array.ptr = nullptr; o.via.array.size = 0; - } else { + } + else { uint32_t size = checked_get_container_size(v.size()); msgpack::object* p = static_cast(o.zone.allocate_align(sizeof(msgpack::object)*size)); msgpack::object* const pend = p + size; diff --git a/include/msgpack/meta.hpp b/include/msgpack/meta.hpp new file mode 100644 index 00000000..d26018e7 --- /dev/null +++ b/include/msgpack/meta.hpp @@ -0,0 +1,51 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2015 KONDO Takatoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef MSGPACK_META_HPP +#define MSGPACK_META_HPP + +#if !defined(MSGPACK_USE_CPP03) + +#include + +namespace msgpack { + +/// @cond +MSGPACK_API_VERSION_NAMESPACE(v1) { +/// @endcond + +namespace detail { +template struct bool_pack; + +template struct all_of_imp + : std::is_same, bool_pack>{}; + +} // namespace detail + +template