From 2034427cfd342cf7a57d3e0e1ddd527eea46058e Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Fri, 31 Jul 2015 16:56:07 +0900 Subject: [PATCH] Added 'as' support for boost containers. --- .travis.yml | 6 +- include/msgpack/adaptor/boost/fusion.hpp | 59 +++++++++++- include/msgpack/adaptor/boost/optional.hpp | 22 +++++ include/msgpack/adaptor/cpp11/array.hpp | 19 ++-- include/msgpack/meta.hpp | 8 ++ include/msgpack/object_fwd.hpp | 2 +- test/boost_fusion.cpp | 106 +++++++++++++++++++++ test/boost_optional.cpp | 45 +++++++++ 8 files changed, 250 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index f7009acd..62091bee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_install: - sudo apt-get update install: - sudo apt-get install -qq gcc-4.8-multilib g++-4.8-multilib - - sudo apt-get install --allow-unauthenticated -qq clang-3.4 + - sudo apt-get install --allow-unauthenticated -qq clang-3.5 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90 - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 90 - sudo apt-get install -y lib32gcc1 @@ -21,9 +21,9 @@ install: - sudo apt-get install -y bzip2 - sudo apt-get install -y libc6-dbg - wget https://googletest.googlecode.com/files/gtest-1.7.0.zip - - wget http://sourceforge.net/projects/boost/files/boost/1.57.0/ + - wget http://sourceforge.net/projects/boost/files/boost/1.58.0/ - wget http://valgrind.org/downloads/valgrind-3.10.1.tar.bz2 && tar xjf valgrind-3.10.1.tar.bz2 && cd valgrind-3.10.1 && ./configure && make && sudo make install && cd .. - - unzip -q gtest-1.7.0.zip && cd gtest-1.7.0 && sudo cp -r include/gtest /usr/local/include && g++ src/gtest-all.cc -I. -Iinclude -c && g++ src/gtest_main.cc -I. -Iinclude -c && ar -rv libgtest.a gtest-all.o && ar -rv libgtest_main.a gtest_main.o && sudo mv *.a /usr/local/lib && g++ -m32 src/gtest-all.cc -I. -Iinclude -c && g++ -m32 src/gtest_main.cc -I. -Iinclude -c && ar -rv libgtest.a gtest-all.o && ar -rv libgtest_main.a gtest_main.o && sudo mkdir /usr/local/lib32 && sudo mv *.a /usr/local/lib32 && cd .. && wget http://sourceforge.net/projects/boost/files/boost/1.57.0/boost_1_57_0.zip && unzip -q boost_1_57_0.zip && sudo mkdir /usr/local/boost && sudo cp -r boost_1_57_0/boost /usr/local/boost/ + - unzip -q gtest-1.7.0.zip && cd gtest-1.7.0 && sudo cp -r include/gtest /usr/local/include && g++ src/gtest-all.cc -I. -Iinclude -c && g++ src/gtest_main.cc -I. -Iinclude -c && ar -rv libgtest.a gtest-all.o && ar -rv libgtest_main.a gtest_main.o && sudo mv *.a /usr/local/lib && g++ -m32 src/gtest-all.cc -I. -Iinclude -c && g++ -m32 src/gtest_main.cc -I. -Iinclude -c && ar -rv libgtest.a gtest-all.o && ar -rv libgtest_main.a gtest_main.o && sudo mkdir /usr/local/lib32 && sudo mv *.a /usr/local/lib32 && cd .. && wget http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.zip && unzip -q boost_1_58_0.zip && sudo mkdir /usr/local/boost && sudo cp -r boost_1_58_0/boost /usr/local/boost/ env: - ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" - ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="" diff --git a/include/msgpack/adaptor/boost/fusion.hpp b/include/msgpack/adaptor/boost/fusion.hpp index b0f0e7df..aba6a7b6 100644 --- a/include/msgpack/adaptor/boost/fusion.hpp +++ b/include/msgpack/adaptor/boost/fusion.hpp @@ -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 #include #include +#include +#include +#include namespace msgpack { @@ -34,11 +42,58 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +#if !defined (MSGPACK_USE_CPP03) + +template +struct as< + T, + typename msgpack::enable_if< + boost::fusion::traits::is_sequence::value && + boost::mpl::fold< + T, + boost::mpl::bool_, + boost::mpl::if_ < + boost::mpl::and_< + boost::mpl::_1, + msgpack::has_as + >, + boost::mpl::bool_, + boost::mpl::bool_ + > + >::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::value)) { + throw msgpack::type_error(); + } + using tuple_t = decltype(to_tuple(std::declval(), gen_seq::value>())); + return to_t( + o.as(), + msgpack::gen_seq::value>()); + } + template + static std::tuple< + typename std::remove_reference< + typename boost::fusion::result_of::at_c::type + >::type...> + to_tuple(U const& u, seq) { + return std::make_tuple(boost::fusion::at_c(u)...); + } + template + static T to_t(U const& u, seq) { + return T(std::get(u)...); + } +}; + +#endif // !defined (MSGPACK_USE_CPP03) + template struct convert::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; diff --git a/include/msgpack/adaptor/boost/optional.hpp b/include/msgpack/adaptor/boost/optional.hpp index 9a3dbb83..6a7376f8 100644 --- a/include/msgpack/adaptor/boost/optional.hpp +++ b/include/msgpack/adaptor/boost/optional.hpp @@ -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 +#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 +struct as, typename std::enable_if::value>::type> { + boost::optional operator()(msgpack::object const& o) const { + if(o.is_nil()) return boost::none; + return o.as(); + } +}; + +#endif // !defined (MSGPACK_USE_CPP03) + template struct convert > { msgpack::object const& operator()(msgpack::object const& o, boost::optional& v) const { diff --git a/include/msgpack/adaptor/cpp11/array.hpp b/include/msgpack/adaptor/cpp11/array.hpp index 5f15453e..fe057eb3 100644 --- a/include/msgpack/adaptor/cpp11/array.hpp +++ b/include/msgpack/adaptor/cpp11/array.hpp @@ -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 @@ -35,26 +36,20 @@ namespace adaptor { namespace detail { -template struct seq {}; - -template -struct gen_seq : gen_seq {}; - -template -struct gen_seq<0, Is...> : seq {}; +namespace array { template inline std::array concat( std::array&& a1, std::array&& a2, - seq, - seq) { + msgpack::seq, + msgpack::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()); + return concat(std::move(a1), std::move(a2), msgpack::gen_seq(), msgpack::gen_seq()); } template @@ -72,6 +67,8 @@ struct as_impl { } }; +} // namespace array + } // namespace detail template @@ -79,7 +76,7 @@ struct as, typename std::enable_if::value>:: 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); + return detail::array::as_impl::as(o); } }; diff --git a/include/msgpack/meta.hpp b/include/msgpack/meta.hpp index d26018e7..618a83fc 100644 --- a/include/msgpack/meta.hpp +++ b/include/msgpack/meta.hpp @@ -40,6 +40,14 @@ template struct all_of_imp template