mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-11-01 11:52:56 +01:00
Merge pull request #331 from redboltz/add_as_support_for_boost
Added 'as' support for boost containers.
This commit is contained in:
@@ -21,10 +21,18 @@
|
||||
#include "msgpack/versioning.hpp"
|
||||
#include "msgpack/adaptor/adaptor_base.hpp"
|
||||
#include "msgpack/adaptor/check_container_size.hpp"
|
||||
#include "msgpack/meta.hpp"
|
||||
|
||||
#if !defined (MSGPACK_USE_CPP03)
|
||||
#include "msgpack/adaptor/cpp11/tuple.hpp"
|
||||
#endif // #if !defined (MSGPACK_USE_CPP03)
|
||||
|
||||
#include <boost/fusion/support/is_sequence.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/size.hpp>
|
||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at.hpp>
|
||||
#include <boost/fusion/include/mpl.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
|
||||
namespace msgpack {
|
||||
|
||||
@@ -34,11 +42,58 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
#if !defined (MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct as<
|
||||
T,
|
||||
typename msgpack::enable_if<
|
||||
boost::fusion::traits::is_sequence<T>::value &&
|
||||
boost::mpl::fold<
|
||||
T,
|
||||
boost::mpl::bool_<true>,
|
||||
boost::mpl::if_ <
|
||||
boost::mpl::and_<
|
||||
boost::mpl::_1,
|
||||
msgpack::has_as<boost::mpl::_2>
|
||||
>,
|
||||
boost::mpl::bool_<true>,
|
||||
boost::mpl::bool_<false>
|
||||
>
|
||||
>::type::value
|
||||
>::type
|
||||
> {
|
||||
T operator()(msgpack::object const& o) const {
|
||||
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||
if (o.via.array.size != checked_get_container_size(boost::mpl::size<T>::value)) {
|
||||
throw msgpack::type_error();
|
||||
}
|
||||
using tuple_t = decltype(to_tuple(std::declval<T>(), gen_seq<boost::mpl::size<T>::value>()));
|
||||
return to_t(
|
||||
o.as<tuple_t>(),
|
||||
msgpack::gen_seq<boost::mpl::size<T>::value>());
|
||||
}
|
||||
template<std::size_t... Is, typename U>
|
||||
static std::tuple<
|
||||
typename std::remove_reference<
|
||||
typename boost::fusion::result_of::at_c<T, Is>::type
|
||||
>::type...>
|
||||
to_tuple(U const& u, seq<Is...>) {
|
||||
return std::make_tuple(boost::fusion::at_c<Is>(u)...);
|
||||
}
|
||||
template<std::size_t... Is, typename U>
|
||||
static T to_t(U const& u, seq<Is...>) {
|
||||
return T(std::get<Is>(u)...);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined (MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct convert<T, typename msgpack::enable_if<boost::fusion::traits::is_sequence<T>::value>::type > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, T& v) const {
|
||||
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||
if(o.via.array.size != checked_get_container_size(boost::fusion::size(v))) {
|
||||
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
|
||||
if (o.via.array.size != checked_get_container_size(boost::fusion::size(v))) {
|
||||
throw msgpack::type_error();
|
||||
}
|
||||
uint32_t index = 0;
|
||||
|
||||
@@ -22,8 +22,18 @@
|
||||
#include "msgpack/adaptor/adaptor_base.hpp"
|
||||
#include "msgpack/adaptor/check_container_size.hpp"
|
||||
|
||||
// To supress warning on Boost.1.58.0
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || defined(__clang__)
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || defined(__clang__)
|
||||
|
||||
namespace msgpack {
|
||||
|
||||
/// @cond
|
||||
@@ -32,6 +42,18 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
|
||||
namespace adaptor {
|
||||
|
||||
#if !defined (MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct as<boost::optional<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
|
||||
boost::optional<T> operator()(msgpack::object const& o) const {
|
||||
if(o.is_nil()) return boost::none;
|
||||
return o.as<T>();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined (MSGPACK_USE_CPP03)
|
||||
|
||||
template <typename T>
|
||||
struct convert<boost::optional<T> > {
|
||||
msgpack::object const& operator()(msgpack::object const& o, boost::optional<T>& v) const {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "msgpack/versioning.hpp"
|
||||
#include "msgpack/adaptor/adaptor_base.hpp"
|
||||
#include "msgpack/adaptor/check_container_size.hpp"
|
||||
#include "msgpack/meta.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -35,26 +36,20 @@ 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...> {};
|
||||
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,
|
||||
seq<I1...>,
|
||||
seq<I2...>) {
|
||||
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), gen_seq<N1>(), gen_seq<N2>());
|
||||
return concat(std::move(a1), std::move(a2), msgpack::gen_seq<N1>(), msgpack::gen_seq<N2>());
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
@@ -72,6 +67,8 @@ struct as_impl<T, 0> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace array
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
@@ -79,7 +76,7 @@ struct as<std::array<T, N>, typename std::enable_if<msgpack::has_as<T>::value>::
|
||||
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);
|
||||
return detail::array::as_impl<T, N>::as(o);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -40,6 +40,14 @@ template<bool...values> struct all_of_imp
|
||||
template<template <class> class T, class... U>
|
||||
using all_of = detail::all_of_imp<T<U>::value...>;
|
||||
|
||||
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...> {};
|
||||
|
||||
/// @cond
|
||||
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||
/// @endcond
|
||||
|
||||
@@ -100,8 +100,8 @@ private:
|
||||
T>::type;
|
||||
template <typename>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<T>(nullptr));
|
||||
public:
|
||||
using type = decltype(check<T>(nullptr));
|
||||
static constexpr bool value = type::value;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user