mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-05-02 07:31:38 +02:00
Added 'as' support for containers.
This commit is contained in:
parent
87f0da1ff1
commit
a746afa7cc
@ -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]")
|
||||
|
@ -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
|
||||
|
@ -33,6 +33,56 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<std::size_t... Is> struct seq {};
|
||||
|
||||
template<std::size_t N, std::size_t... Is>
|
||||
struct gen_seq : gen_seq<N-1, N-1, Is...> {};
|
||||
|
||||
template<std::size_t... Is>
|
||||
struct gen_seq<0, Is...> : seq<Is...> {};
|
||||
|
||||
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,
|
||||
seq<I1...>,
|
||||
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), gen_seq<N1>(), 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, 0> {
|
||||
static std::array<T, 0> as(msgpack::object const&) {
|
||||
return std::array<T, 0>();
|
||||
}
|
||||
};
|
||||
|
||||
} // 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::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 {
|
||||
|
@ -33,6 +33,21 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
template <typename T>
|
||||
struct as<std::forward_list<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
std::forward_list<T> operator()(msgpack::object const& o) const {
|
||||
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||
std::forward_list<T> 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<T>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct convert<std::forward_list<T>> {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::forward_list<T>& v) const {
|
||||
|
@ -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 <tuple>
|
||||
|
||||
@ -41,15 +42,6 @@ struct StdTuplePacker {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Stream, typename Tuple>
|
||||
struct StdTuplePacker<Stream, Tuple, 1> {
|
||||
static void pack (
|
||||
msgpack::packer<Stream>& o,
|
||||
const Tuple& v) {
|
||||
o.pack(std::get<0>(v));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Stream, typename Tuple>
|
||||
struct StdTuplePacker<Stream, Tuple, 0> {
|
||||
static void pack (
|
||||
@ -77,6 +69,32 @@ struct pack<std::tuple<Args...>> {
|
||||
|
||||
// --- Convert from tuple to object ---
|
||||
|
||||
template <typename... Args>
|
||||
struct StdTupleAs;
|
||||
|
||||
template <typename T, typename... Args>
|
||||
struct StdTupleAsImpl {
|
||||
static std::tuple<T, Args...> as(msgpack::object const& o) {
|
||||
return std::tuple_cat(
|
||||
std::make_tuple(o.via.array.ptr[o.via.array.size - sizeof...(Args) - 1].as<T>()),
|
||||
StdTupleAs<Args...>::as(o));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct StdTupleAs {
|
||||
static std::tuple<Args...> as(msgpack::object const& o) {
|
||||
return StdTupleAsImpl<Args...>::as(o);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StdTupleAs<> {
|
||||
static std::tuple<> as (msgpack::object const&) {
|
||||
return std::tuple<>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t N>
|
||||
struct StdTupleConverter {
|
||||
static void convert(
|
||||
@ -87,15 +105,6 @@ struct StdTupleConverter {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple>
|
||||
struct StdTupleConverter<Tuple, 1> {
|
||||
static void convert (
|
||||
msgpack::object const& o,
|
||||
Tuple& v) {
|
||||
o.via.array.ptr[0].convert<typename std::remove_reference<decltype(std::get<0>(v))>::type>(std::get<0>(v));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple>
|
||||
struct StdTupleConverter<Tuple, 0> {
|
||||
static void convert (
|
||||
@ -106,6 +115,16 @@ struct StdTupleConverter<Tuple, 0> {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
template <typename... Args>
|
||||
struct as<std::tuple<Args...>, typename std::enable_if<msgpack::all_of<msgpack::has_as, Args...>::value>::type> {
|
||||
std::tuple<Args...> 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<Args...>::as(o);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct convert<std::tuple<Args...>> {
|
||||
msgpack::object const& operator()(
|
||||
@ -131,15 +150,6 @@ struct StdTupleToObjectWithZone {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple>
|
||||
struct StdTupleToObjectWithZone<Tuple, 1> {
|
||||
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 <typename Tuple>
|
||||
struct StdTupleToObjectWithZone<Tuple, 0> {
|
||||
static void convert (
|
||||
|
@ -32,6 +32,22 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
template <typename K, typename V>
|
||||
struct as<
|
||||
std::unordered_map<K, V>,
|
||||
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 {
|
||||
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<K, V> v;
|
||||
for (; p != pend; ++p) {
|
||||
v.emplace(p->key.as<K>(), p->val.as<V>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct convert<std::unordered_map<K, V>> {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_map<K, V>& v) const {
|
||||
@ -89,6 +105,22 @@ struct object_with_zone<std::unordered_map<K, V>> {
|
||||
};
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
struct as<
|
||||
std::unordered_multimap<K, V>,
|
||||
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 {
|
||||
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<K, V> v;
|
||||
for (; p != pend; ++p) {
|
||||
v.emplace(p->key.as<K>(), p->val.as<V>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct convert<std::unordered_multimap<K, V>> {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_multimap<K, V>& v) const {
|
||||
|
@ -32,6 +32,21 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
template <typename T>
|
||||
struct as<std::unordered_set<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
std::unordered_set<T> 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<T> v;
|
||||
while (p > pbegin) {
|
||||
--p;
|
||||
v.insert(p->as<T>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct convert<std::unordered_set<T>> {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_set<T>& v) const {
|
||||
@ -86,6 +101,21 @@ struct object_with_zone<std::unordered_set<T>> {
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct as<std::unordered_multiset<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
std::unordered_multiset<T> 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<T> v;
|
||||
while (p > pbegin) {
|
||||
--p;
|
||||
v.insert(p->as<T>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct convert<std::unordered_multiset<T>> {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::unordered_multiset<T>& v) const {
|
||||
|
@ -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 <tuple>
|
||||
|
||||
@ -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<I>(*this); }
|
||||
};
|
||||
|
||||
template< class... Tuples >
|
||||
auto tuple_cat(Tuples&&... args) ->
|
||||
template <class... Args>
|
||||
inline tuple<Args...> make_tuple(Args&&... args) {
|
||||
return tuple<Args...>(args...);
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
inline tuple<Args&&...> forward_as_tuple (Args&&... args) noexcept {
|
||||
return tuple<Args&&...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Tuples>
|
||||
inline auto tuple_cat(Tuples&&... args) ->
|
||||
decltype(
|
||||
std::tuple_cat(std::forward<typename std::remove_reference<Tuples>::type::base>(args)...)
|
||||
) {
|
||||
@ -124,11 +133,11 @@ struct MsgpackTuplePacker<Stream, Tuple, 0> {
|
||||
namespace adaptor {
|
||||
|
||||
template <typename... Args>
|
||||
struct pack<type::tuple<Args...>> {
|
||||
struct pack<msgpack::type::tuple<Args...>> {
|
||||
template <typename Stream>
|
||||
msgpack::packer<Stream>& operator()(
|
||||
msgpack::packer<Stream>& o,
|
||||
const type::tuple<Args...>& v) const {
|
||||
const msgpack::type::tuple<Args...>& v) const {
|
||||
o.pack_array(sizeof...(Args));
|
||||
MsgpackTuplePacker<Stream, decltype(v), sizeof...(Args)>::pack(o, v);
|
||||
return o;
|
||||
@ -139,6 +148,32 @@ struct pack<type::tuple<Args...>> {
|
||||
|
||||
// --- Convert from tuple to object ---
|
||||
|
||||
template <typename... Args>
|
||||
struct MsgpackTupleAs;
|
||||
|
||||
template <typename T, typename... Args>
|
||||
struct MsgpackTupleAsImpl {
|
||||
static msgpack::type::tuple<T, Args...> 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<T>()),
|
||||
MsgpackTupleAs<Args...>::as(o));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct MsgpackTupleAs {
|
||||
static msgpack::type::tuple<Args...> as(msgpack::object const& o) {
|
||||
return MsgpackTupleAsImpl<Args...>::as(o);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MsgpackTupleAs<> {
|
||||
static msgpack::type::tuple<> as (msgpack::object const&) {
|
||||
return msgpack::type::tuple<>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t N>
|
||||
struct MsgpackTupleConverter {
|
||||
static void convert(
|
||||
@ -169,10 +204,20 @@ struct MsgpackTupleConverter<Tuple, 0> {
|
||||
namespace adaptor {
|
||||
|
||||
template <typename... Args>
|
||||
struct convert<type::tuple<Args...>> {
|
||||
struct as<msgpack::type::tuple<Args...>, typename std::enable_if<msgpack::all_of<msgpack::has_as, Args...>::value>::type> {
|
||||
msgpack::type::tuple<Args...> 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<Args...>::as(o);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct convert<msgpack::type::tuple<Args...>> {
|
||||
msgpack::object const& operator()(
|
||||
msgpack::object const& o,
|
||||
type::tuple<Args...>& v) const {
|
||||
msgpack::type::tuple<Args...>& v) const {
|
||||
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||
if(o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); }
|
||||
MsgpackTupleConverter<decltype(v), sizeof...(Args)>::convert(o, v);
|
||||
@ -213,10 +258,10 @@ struct MsgpackTupleToObjectWithZone<Tuple, 0> {
|
||||
namespace adaptor {
|
||||
|
||||
template <typename... Args>
|
||||
struct object_with_zone<type::tuple<Args...>> {
|
||||
struct object_with_zone<msgpack::type::tuple<Args...>> {
|
||||
void operator()(
|
||||
msgpack::object::with_zone& o,
|
||||
type::tuple<Args...> const& v) const {
|
||||
msgpack::type::tuple<Args...> const& v) const {
|
||||
o.type = msgpack::type::ARRAY;
|
||||
o.via.array.ptr = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*sizeof...(Args)));
|
||||
o.via.array.size = sizeof...(Args);
|
||||
|
@ -32,15 +32,33 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct as<std::list<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
std::list<T> operator()(msgpack::object const& o) const {
|
||||
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||
std::list<T> 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<T>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct convert<std::list<T> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::list<T>& 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<T>::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<std::list<T> > {
|
||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::list<T>& v) const {
|
||||
uint32_t size = checked_get_container_size(v.size());
|
||||
o.pack_array(size);
|
||||
for(typename std::list<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
for (typename std::list<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
it != it_end; ++it) {
|
||||
o.pack(*it);
|
||||
}
|
||||
@ -65,10 +83,11 @@ template <typename T>
|
||||
struct object_with_zone<std::list<T> > {
|
||||
void operator()(msgpack::object::with_zone& o, const std::list<T>& 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<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size));
|
||||
msgpack::object* const pend = p + size;
|
||||
|
@ -35,7 +35,11 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
namespace type {
|
||||
|
||||
template <typename K, typename V>
|
||||
class assoc_vector : public std::vector< std::pair<K, V> > {};
|
||||
class assoc_vector : public std::vector< std::pair<K, V> > {
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
using std::vector<std::pair<K, V>>::vector;
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename K, typename V>
|
||||
@ -49,15 +53,37 @@ namespace detail {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename K, typename V>
|
||||
struct as<
|
||||
type::assoc_vector<K, V>,
|
||||
typename std::enable_if<msgpack::has_as<K>::value && msgpack::has_as<V>::value>::type> {
|
||||
type::assoc_vector<K, V> operator()(msgpack::object const& o) const {
|
||||
if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
|
||||
type::assoc_vector<K, V> 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>());
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename K, typename V>
|
||||
struct convert<type::assoc_vector<K, V> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, type::assoc_vector<K,V>& 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<K, V>* 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<type::assoc_vector<K, V> > {
|
||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const type::assoc_vector<K,V>& v) const {
|
||||
uint32_t size = checked_get_container_size(v.size());
|
||||
o.pack_map(size);
|
||||
for(typename type::assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
||||
for (typename type::assoc_vector<K,V>::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 <typename K, typename V>
|
||||
struct object_with_zone<type::assoc_vector<K, V> > {
|
||||
void operator()(msgpack::object::with_zone& o, const type::assoc_vector<K,V>& 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<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size));
|
||||
msgpack::object_kv* const pend = p + size;
|
||||
@ -105,14 +132,34 @@ struct object_with_zone<type::assoc_vector<K, V> > {
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename K, typename V>
|
||||
struct as<
|
||||
std::map<K, V>,
|
||||
typename std::enable_if<msgpack::has_as<K>::value && msgpack::has_as<V>::value>::type> {
|
||||
std::map<K, V> 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> 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>
|
||||
struct convert<std::map<K, V> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::map<K, V>& 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<K, V> tmp;
|
||||
for(; p != pend; ++p) {
|
||||
for (; p != pend; ++p) {
|
||||
K key;
|
||||
p->key.convert(key);
|
||||
#if __cplusplus >= 201103L
|
||||
@ -136,7 +183,7 @@ struct pack<std::map<K, V> > {
|
||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::map<K,V>& v) const {
|
||||
uint32_t size = checked_get_container_size(v.size());
|
||||
o.pack_map(size);
|
||||
for(typename std::map<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
||||
for (typename std::map<K,V>::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 <typename K, typename V>
|
||||
struct object_with_zone<std::map<K, V> > {
|
||||
void operator()(msgpack::object::with_zone& o, const std::map<K,V>& 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<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size));
|
||||
msgpack::object_kv* const pend = p + size;
|
||||
@ -169,15 +217,34 @@ struct object_with_zone<std::map<K, V> > {
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename K, typename V>
|
||||
struct as<
|
||||
std::multimap<K, V>,
|
||||
typename std::enable_if<msgpack::has_as<K>::value && msgpack::has_as<V>::value>::type> {
|
||||
std::multimap<K, V> 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> 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>
|
||||
struct convert<std::multimap<K, V> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::multimap<K, V>& 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<K, V> tmp;
|
||||
for(; p != pend; ++p) {
|
||||
for (; p != pend; ++p) {
|
||||
std::pair<K, V> value;
|
||||
p->key.convert(value.first);
|
||||
p->val.convert(value.second);
|
||||
@ -202,7 +269,7 @@ struct pack<std::multimap<K, V> > {
|
||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::multimap<K,V>& v) const {
|
||||
uint32_t size = checked_get_container_size(v.size());
|
||||
o.pack_map(size);
|
||||
for(typename std::multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
||||
for (typename std::multimap<K,V>::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 <typename K, typename V>
|
||||
struct object_with_zone<std::multimap<K, V> > {
|
||||
void operator()(msgpack::object::with_zone& o, const std::multimap<K,V>& 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<msgpack::object_kv*>(o.zone.allocate_align(sizeof(msgpack::object_kv)*size));
|
||||
msgpack::object_kv* const pend = p + size;
|
||||
|
@ -30,6 +30,19 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct as<std::pair<T1, T2>> {
|
||||
std::pair<T1, T2> 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<T1>(), o.via.array.ptr[1].as<T2>());
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct convert<std::pair<T1, T2> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::pair<T1, T2>& v) const {
|
||||
|
@ -32,14 +32,33 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct as<std::set<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
std::set<T> 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<T> v;
|
||||
while (p > pbegin) {
|
||||
--p;
|
||||
v.insert(p->as<T>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct convert<std::set<T> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::set<T>& 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<T> tmp;
|
||||
while(p > pbegin) {
|
||||
while (p > pbegin) {
|
||||
--p;
|
||||
tmp.insert(p->as<T>());
|
||||
}
|
||||
@ -58,7 +77,7 @@ struct pack<std::set<T> > {
|
||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::set<T>& v) const {
|
||||
uint32_t size = checked_get_container_size(v.size());
|
||||
o.pack_array(size);
|
||||
for(typename std::set<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
for (typename std::set<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
it != it_end; ++it) {
|
||||
o.pack(*it);
|
||||
}
|
||||
@ -70,10 +89,11 @@ template <typename T>
|
||||
struct object_with_zone<std::set<T> > {
|
||||
void operator()(msgpack::object::with_zone& o, const std::set<T>& 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<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size));
|
||||
msgpack::object* const pend = p + size;
|
||||
@ -89,14 +109,33 @@ struct object_with_zone<std::set<T> > {
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct as<std::multiset<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
std::multiset<T> 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<T> v;
|
||||
while (p > pbegin) {
|
||||
--p;
|
||||
v.insert(p->as<T>());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct convert<std::multiset<T> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::multiset<T>& 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<T> tmp;
|
||||
while(p > pbegin) {
|
||||
while (p > pbegin) {
|
||||
--p;
|
||||
tmp.insert(p->as<T>());
|
||||
}
|
||||
@ -115,7 +154,7 @@ struct pack<std::multiset<T> > {
|
||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::multiset<T>& v) const {
|
||||
uint32_t size = checked_get_container_size(v.size());
|
||||
o.pack_array(size);
|
||||
for(typename std::multiset<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
for (typename std::multiset<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
it != it_end; ++it) {
|
||||
o.pack(*it);
|
||||
}
|
||||
@ -127,7 +166,7 @@ template <typename T>
|
||||
struct object_with_zone<std::multiset<T> > {
|
||||
void operator()(msgpack::object::with_zone& o, const std::multiset<T>& v) const {
|
||||
o.type = msgpack::type::ARRAY;
|
||||
if(v.empty()) {
|
||||
if (v.empty()) {
|
||||
o.via.array.ptr = nullptr;
|
||||
o.via.array.size = 0;
|
||||
} else {
|
||||
|
@ -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 <typename T>
|
||||
struct as<std::vector<T>> {
|
||||
struct as<std::vector<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
std::vector<T> operator()(const msgpack::object& o) const {
|
||||
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||
std::vector<T> 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<T>());
|
||||
v.push_back(p->as<T>());
|
||||
++p;
|
||||
} while (p < pend);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct convert<std::vector<T> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, std::vector<T>& 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<T>::iterator it = v.begin();
|
||||
@ -76,7 +79,7 @@ struct pack<std::vector<T> > {
|
||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::vector<T>& v) const {
|
||||
uint32_t size = checked_get_container_size(v.size());
|
||||
o.pack_array(size);
|
||||
for(typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
for (typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end());
|
||||
it != it_end; ++it) {
|
||||
o.pack(*it);
|
||||
}
|
||||
@ -88,10 +91,11 @@ template <typename T>
|
||||
struct object_with_zone<std::vector<T> > {
|
||||
void operator()(msgpack::object::with_zone& o, const std::vector<T>& 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<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size));
|
||||
msgpack::object* const pend = p + size;
|
||||
|
51
include/msgpack/meta.hpp
Normal file
51
include/msgpack/meta.hpp
Normal file
@ -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 <type_traits>
|
||||
|
||||
namespace msgpack {
|
||||
|
||||
/// @cond
|
||||
MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
/// @endcond
|
||||
|
||||
namespace detail {
|
||||
template<bool...> struct bool_pack;
|
||||
|
||||
template<bool...values> struct all_of_imp
|
||||
: std::is_same<bool_pack<values..., true>, bool_pack<true, values...>>{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<template <class> class T, class... U>
|
||||
using all_of = detail::all_of_imp<T<U>::value...>;
|
||||
|
||||
/// @cond
|
||||
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||
/// @endcond
|
||||
|
||||
} // namespace msgpack
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
#endif // MSGPACK_META_HPP
|
@ -86,7 +86,7 @@ struct object_ext {
|
||||
struct object;
|
||||
|
||||
namespace adaptor {
|
||||
template <typename T>
|
||||
template <typename T, typename Enabler = void>
|
||||
struct as;
|
||||
} // namespace adaptor
|
||||
|
||||
|
@ -98,6 +98,7 @@ nobase_include_HEADERS += \
|
||||
../include/msgpack/detail/cpp11_zone.hpp \
|
||||
../include/msgpack/fbuffer.hpp \
|
||||
../include/msgpack/iterator.hpp \
|
||||
../include/msgpack/meta.hpp \
|
||||
../include/msgpack/object.hpp \
|
||||
../include/msgpack/object_fwd.hpp \
|
||||
../include/msgpack/pack.hpp \
|
||||
|
@ -64,7 +64,7 @@ FOREACH (source_file ${check_PROGRAMS})
|
||||
)
|
||||
ADD_TEST (${source_file_we} ${source_file_we})
|
||||
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -g -O3")
|
||||
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -Wno-mismatched-tags -g -O3")
|
||||
ENDIF ()
|
||||
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||
|
@ -192,6 +192,18 @@ struct no_def_con {
|
||||
MSGPACK_DEFINE(i);
|
||||
};
|
||||
|
||||
inline bool operator==(no_def_con const& lhs, no_def_con const& rhs) {
|
||||
return lhs.i == rhs.i;
|
||||
}
|
||||
|
||||
inline bool operator!=(no_def_con const& lhs, no_def_con const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(no_def_con const& lhs, no_def_con const& rhs) {
|
||||
return lhs.i < rhs.i;
|
||||
}
|
||||
|
||||
namespace msgpack {
|
||||
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
|
||||
namespace adaptor {
|
||||
@ -207,6 +219,14 @@ struct as<no_def_con> {
|
||||
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
|
||||
} // msgpack
|
||||
|
||||
namespace std {
|
||||
template <> struct hash<no_def_con> {
|
||||
size_t operator()(const no_def_con & x) const {
|
||||
return hash<int>()(x.i);
|
||||
}
|
||||
};
|
||||
} // std
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON, simple_buffer)
|
||||
{
|
||||
no_def_con val1(42);
|
||||
@ -216,16 +236,29 @@ TEST(MSGPACK_NO_DEF_CON, simple_buffer)
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
|
||||
no_def_con val2 = ret.get().as<no_def_con>();
|
||||
EXPECT_EQ(val1.i, val2.i);
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
struct no_def_con_composite {
|
||||
no_def_con_composite() = delete;
|
||||
no_def_con_composite(int i):ndc(i) {}
|
||||
no_def_con_composite(no_def_con const& a):ndc(a) {}
|
||||
no_def_con ndc;
|
||||
MSGPACK_DEFINE(ndc);
|
||||
};
|
||||
|
||||
inline bool operator==(no_def_con_composite const& lhs, no_def_con_composite const& rhs) {
|
||||
return lhs.ndc == rhs.ndc;
|
||||
}
|
||||
|
||||
inline bool operator!=(no_def_con_composite const& lhs, no_def_con_composite const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(no_def_con_composite const& lhs, no_def_con_composite const& rhs) {
|
||||
return lhs.ndc < rhs.ndc;
|
||||
}
|
||||
|
||||
namespace msgpack {
|
||||
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
|
||||
namespace adaptor {
|
||||
@ -249,7 +282,7 @@ TEST(MSGPACK_NO_DEF_CON_COMPOSITE, simple_buffer)
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
no_def_con_composite val2 = ret.get().as<no_def_con_composite>();
|
||||
EXPECT_EQ(val1.ndc.i, val2.ndc.i);
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
struct no_def_con_inherit : no_def_con {
|
||||
@ -281,7 +314,191 @@ TEST(MSGPACK_NO_DEF_CON_INHERIT, simple_buffer)
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
no_def_con_inherit val2 = ret.get().as<no_def_con_inherit>();
|
||||
EXPECT_EQ(val1.i, val2.i);
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_VECTOR, simple_buffer)
|
||||
{
|
||||
std::vector<no_def_con> val1 { 1, 2, 3 };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::vector<no_def_con> val2 = ret.get().as<std::vector<no_def_con>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_LIST, simple_buffer)
|
||||
{
|
||||
std::list<no_def_con> val1 { 1, 2, 3 };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::list<no_def_con> val2 = ret.get().as<std::list<no_def_con>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_SET, simple_buffer)
|
||||
{
|
||||
std::set<no_def_con> val1 { 1, 2, 3 };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::set<no_def_con> val2 = ret.get().as<std::set<no_def_con>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_MULTISET, simple_buffer)
|
||||
{
|
||||
std::multiset<no_def_con> val1 { 1, 2, 3 };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::multiset<no_def_con> val2 = ret.get().as<std::multiset<no_def_con>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_ASSOC_VECTOR, simple_buffer)
|
||||
{
|
||||
msgpack::type::assoc_vector<no_def_con, no_def_con_composite> val1 { {1, 2}, {3, 4}, {5, 6}};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
msgpack::type::assoc_vector<no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<msgpack::type::assoc_vector<no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_MAP, simple_buffer)
|
||||
{
|
||||
std::map<no_def_con, no_def_con_composite> val1 { {1, 2}, {3, 4}, {5, 6}};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::map<no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<std::map<no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_MULTIMAP, simple_buffer)
|
||||
{
|
||||
std::multimap<no_def_con, no_def_con_composite> val1 { {1, 2}, {3, 4}, {5, 6}};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::multimap<no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<std::multimap<no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_PAIR, simple_buffer)
|
||||
{
|
||||
std::pair<no_def_con, no_def_con_composite> val1 {1, 2};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::pair<no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<std::pair<no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_TUPLE, simple_buffer)
|
||||
{
|
||||
std::tuple<no_def_con, no_def_con, no_def_con_composite> val1 {1, 2, 3};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::tuple<no_def_con, no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<std::tuple<no_def_con, no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_MSGPACK_TUPLE, simple_buffer)
|
||||
{
|
||||
msgpack::type::tuple<no_def_con, no_def_con, no_def_con_composite> val1 {1, 2, 3};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
msgpack::type::tuple<no_def_con, no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<msgpack::type::tuple<no_def_con, no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_FORWARD_LIST, simple_buffer)
|
||||
{
|
||||
std::forward_list<no_def_con> val1 { 1, 2, 3 };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::forward_list<no_def_con> val2 = ret.get().as<std::forward_list<no_def_con>>();
|
||||
EXPECT_TRUE(val1 == val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_UNORDERED_SET, simple_buffer)
|
||||
{
|
||||
std::unordered_set<no_def_con> val1 { 1, 2, 3 };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::unordered_set<no_def_con> val2 = ret.get().as<std::unordered_set<no_def_con>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_UNORDERED_MULTISET, simple_buffer)
|
||||
{
|
||||
std::unordered_multiset<no_def_con> val1 { 1, 2, 3 };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::unordered_multiset<no_def_con> val2 = ret.get().as<std::unordered_multiset<no_def_con>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_UNORDERED_MAP, simple_buffer)
|
||||
{
|
||||
std::unordered_map<no_def_con, no_def_con_composite> val1 { {1, 2}, {3, 4}, {5, 6}};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::unordered_map<no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<std::unordered_map<no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_UNORDERED_MULTIMAP, simple_buffer)
|
||||
{
|
||||
std::unordered_multimap<no_def_con, no_def_con_composite> val1 { {1, 2}, {3, 4}, {5, 6}};
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::unordered_multimap<no_def_con, no_def_con_composite> val2
|
||||
= ret.get().as<std::unordered_multimap<no_def_con, no_def_con_composite>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
TEST(MSGPACK_NO_DEF_CON_ARRAY, simple_buffer)
|
||||
{
|
||||
std::array<no_def_con, 3> val1 { { 1, 2, 3 } };
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, val1);
|
||||
msgpack::unpacked ret;
|
||||
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
||||
std::array<no_def_con, 3> val2 = ret.get().as<std::array<no_def_con, 3>>();
|
||||
EXPECT_EQ(val1, val2);
|
||||
}
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
Loading…
x
Reference in New Issue
Block a user