From ef09252dff73c01db383f149fce248119c222c59 Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Wed, 8 Apr 2015 14:27:10 +0900 Subject: [PATCH] Added the Boost.Optional adaptor. It is enables when MSGPACK_USE_BOOST is defined. --- .travis.yml | 29 +++-- CMakeLists.txt | 7 ++ ci/build_autotools.sh | 30 +++-- ci/build_cmake.sh | 39 ++++--- include/msgpack/adaptor/boost/optional.hpp | 82 +++++++++++++ include/msgpack/type.hpp | 6 + src/Makefile.am | 1 + test/CMakeLists.txt | 6 + test/Makefile.am | 5 +- test/boost_optional.cpp | 130 +++++++++++++++++++++ 10 files changed, 299 insertions(+), 36 deletions(-) create mode 100644 include/msgpack/adaptor/boost/optional.hpp create mode 100644 test/boost_optional.cpp diff --git a/.travis.yml b/.travis.yml index 78ea246e..e0f6272e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,16 +19,25 @@ install: - sudo apt-get install -y lib32z1-dev - sudo apt-get install -y lib32stdc++6 - wget https://googletest.googlecode.com/files/gtest-1.7.0.zip - - unzip 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/ + - 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/ env: - - ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" - - ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" - - ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" - - ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" - - ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" - - ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" - - ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" - - ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" + - 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="" + - ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="boost" BOOST_INC="/usr/local/boost" + - ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="" + - ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" + - ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" BOOST="" + - ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="boost" BOOST_INC="/usr/local/boost" + - ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="" + - ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" + - ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="" + - ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="boost" BOOST_INC="/usr/local/boost" + - ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="" + - ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" + - ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" BOOST="" + - ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="boost" BOOST_INC="/usr/local/boost" + - ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="" script: - - git clean -xdf && CMAKE_LIBRARY_PATH=${LIBPATH} ${ACTION} ${VERSION} ${ARCH} + - git clean -xdf && CMAKE_LIBRARY_PATH=${LIBPATH} ${ACTION} ${VERSION} ${ARCH} ${BOOST} ${BOOST_INC} diff --git a/CMakeLists.txt b/CMakeLists.txt index 74bc1516..b040d2a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ SET (includedir "\${prefix}/include") OPTION (MSGPACK_CXX11 "Using c++11 compiler" OFF) OPTION (MSGPACK_32BIT "32bit compile" OFF) +OPTION (MSGPACK_BOOST "Using boost libraries" OFF) IF (MSGPACK_CXX11) IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") @@ -40,6 +41,10 @@ IF (MSGPACK_32BIT) ENDIF () ENDIF () +IF (MSGPACK_BOOST) + SET (CMAKE_CXX_FLAGS "-DMSGPACK_USE_BOOST ${CMAKE_CXX_FLAGS}") +ENDIF () + FIND_PACKAGE (GTest) FIND_PACKAGE (ZLIB) FIND_PACKAGE (Threads) @@ -100,6 +105,7 @@ IF (MSGPACK_ENABLE_CXX) include/msgpack.hpp include/msgpack/adaptor/adaptor_base.hpp include/msgpack/adaptor/bool.hpp + include/msgpack/adaptor/boost/optional.hpp include/msgpack/adaptor/char_ptr.hpp include/msgpack/adaptor/check_container_size.hpp include/msgpack/adaptor/cpp11/array.hpp @@ -162,6 +168,7 @@ INCLUDE_DIRECTORIES ( ./ include/ ${CMAKE_CURRENT_BINARY_DIR}/include/ + ${MSGPACK_BOOST_DIR} ) ADD_LIBRARY (msgpack SHARED diff --git a/ci/build_autotools.sh b/ci/build_autotools.sh index a5ac75fd..0bb770ac 100755 --- a/ci/build_autotools.sh +++ b/ci/build_autotools.sh @@ -9,21 +9,27 @@ fi if [ $1 = "cpp11" ] then - if [ $2 = "32" ] - then - ./configure CFLAGS="-m32" CXXFLAGS="-std=c++11 -m32" - else - ./configure CXXFLAGS="-std=c++11" - fi + cpp11="-std=c++11" else - if [ $2 = "32" ] - then - ./configure CFLAGS="-m32" CXXFLAGS="-m32" - else - ./configure - fi + cpp11="" fi +if [ $2 = "32" ] +then + bit32="-m32" +else + bit32="" +fi + +if [ $3 = "boost" ] +then + boost="-DMSGPACK_USE_BOOST" +else + boost="" +fi + +./configure CFLAGS="$bit32" CXXFLAGS="$bit32 $cpp11 $boost -I$4" + ret=$? if [ $ret -ne 0 ] then diff --git a/ci/build_cmake.sh b/ci/build_cmake.sh index a28780f8..1fca59c8 100755 --- a/ci/build_cmake.sh +++ b/ci/build_cmake.sh @@ -18,21 +18,34 @@ fi if [ $1 = "cpp11" ] then - if [ $2 = "32" ] - then - cmake -DMSGPACK_CXX11=ON -DMSGPACK_32BIT=ON .. - else - cmake -DMSGPACK_CXX11=ON .. - fi + cpp11="-DMSGPACK_CXX11=ON" else - if [ $2 = "32" ] - then - cmake -DMSGPACK_32BIT=ON .. - else - cmake .. - fi + cpp11="" fi +if [ $2 = "32" ] +then + bit32="-DMSGPACK_32BIT=ON" +else + bit32="" +fi + +if [ $3 = "boost" ] +then + boost="-DMSGPACK_BOOST=ON" +else + boost="" +fi + +if [ "$4" != "" ] +then + boost_dir="-DMSGPACK_BOOST_DIR=$4" +else + boost_dir="" +fi + +cmake $cpp11 $bit32 $boost $boost_dir .. + ret=$? if [ $ret -ne 0 ] then @@ -63,7 +76,7 @@ then exit $ret fi -if [ $2 != "32" ] +if [ "$2" != "32" ] then ctest -T memcheck | tee memcheck.log diff --git a/include/msgpack/adaptor/boost/optional.hpp b/include/msgpack/adaptor/boost/optional.hpp new file mode 100644 index 00000000..2a3b4899 --- /dev/null +++ b/include/msgpack/adaptor/boost/optional.hpp @@ -0,0 +1,82 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// +// 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_TYPE_BOOST_OPTIONAL_HPP +#define MSGPACK_TYPE_BOOST_OPTIONAL_HPP + +#include "msgpack/versioning.hpp" +#include "msgpack/adaptor/adaptor_base.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + +#include + +namespace msgpack { + +/// @cond +MSGPACK_API_VERSION_NAMESPACE(v1) { +/// @endcond + +namespace adaptor { + +template +struct convert > { + msgpack::object const& operator()(msgpack::object const& o, boost::optional& v) const { + if(o.is_nil()) v = boost::none; + else { + T t; + msgpack::adaptor::convert()(o, t); + v = t; + } + return o; + } +}; + +template +struct pack > { + template + msgpack::packer& operator()(msgpack::packer& o, const boost::optional& v) const { + if (v) o.pack(*v); + else o.pack_nil(); + return o; + } +}; + +template +struct object > { + void operator()(msgpack::object& o, const boost::optional& v) const { + if (v) msgpack::adaptor::object()(o, *v); + else o.type = msgpack::type::NIL; + } +}; + +template +struct object_with_zone > { + void operator()(msgpack::object::with_zone& o, const boost::optional& v) const { + if (v) msgpack::adaptor::object_with_zone()(o, *v); + else o.type = msgpack::type::NIL; + } +}; + +} // namespace adaptor + +/// @cond +} // MSGPACK_API_VERSION_NAMESPACE(v1) +/// @endcond + +} // namespace msgpack + +#endif // MSGPACK_TYPE_BOOST_OPTIONAL_HPP diff --git a/include/msgpack/type.hpp b/include/msgpack/type.hpp index 73f5f6c8..ffd09bbd 100644 --- a/include/msgpack/type.hpp +++ b/include/msgpack/type.hpp @@ -33,3 +33,9 @@ #include "adaptor/cpp11/unordered_set.hpp" #endif // defined(MSGPACK_USE_CPP03) + +#if defined(MSGPACK_USE_BOOST) + +#include "adaptor/boost/optional.hpp" + +#endif // defined(MSGPACK_USE_BOOST) diff --git a/src/Makefile.am b/src/Makefile.am index 7b3f2ea0..81a64b22 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,6 +56,7 @@ nobase_include_HEADERS += \ ../include/msgpack.hpp \ ../include/msgpack/adaptor/adaptor_base.hpp \ ../include/msgpack/adaptor/bool.hpp \ + ../include/msgpack/adaptor/boost/optional.hpp \ ../include/msgpack/adaptor/char_ptr.hpp \ ../include/msgpack/adaptor/check_container_size.hpp \ ../include/msgpack/adaptor/cpp11/array.hpp \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1eddfd26..1392dd8f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,6 +31,12 @@ LIST (APPEND check_PROGRAMS limit.cpp ) +IF (MSGPACK_BOOST) + LIST (APPEND check_PROGRAMS + boost_optional.cpp + ) +ENDIF () + IF (MSGPACK_CXX11) LIST (APPEND check_PROGRAMS msgpack_cpp11.cpp diff --git a/test/Makefile.am b/test/Makefile.am index b5a5e2ed..67657f57 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -26,7 +26,8 @@ check_PROGRAMS = \ reference_cpp11 \ reference \ limit \ - iterator_cpp11 + iterator_cpp11 \ + boost_optional TESTS = $(check_PROGRAMS) @@ -79,4 +80,6 @@ limit_SOURCES = limit.cpp iterator_cpp11_SOURCES = iterator_cpp11.cpp +boost_optional_SOURCES = boost_optional.cpp + EXTRA_DIST = cases.mpac cases_compact.mpac diff --git a/test/boost_optional.cpp b/test/boost_optional.cpp new file mode 100644 index 00000000..f97ffba4 --- /dev/null +++ b/test/boost_optional.cpp @@ -0,0 +1,130 @@ +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(MSGPACK_USE_BOOST) + +TEST(MSGPACK_BOOST, pack_convert_nil) +{ + std::stringstream ss; + boost::optional val1; + msgpack::pack(ss, val1); + msgpack::unpacked ret; + msgpack::unpack(ret, ss.str().data(), ss.str().size()); + boost::optional val2 = ret.get().as >(); + EXPECT_TRUE(val1 == val2); +} + +TEST(MSGPACK_BOOST, pack_convert_int) +{ + std::stringstream ss; + boost::optional val1 = 1; + msgpack::pack(ss, val1); + msgpack::unpacked ret; + msgpack::unpack(ret, ss.str().data(), ss.str().size()); + boost::optional val2 = ret.get().as >(); + EXPECT_TRUE(val1 == val2); +} + +TEST(MSGPACK_BOOST, pack_convert_vector) +{ + typedef boost::optional > ovi_t; + std::stringstream ss; + ovi_t val1; + std::vector v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + val1 = v; + msgpack::pack(ss, val1); + msgpack::unpacked ret; + msgpack::unpack(ret, ss.str().data(), ss.str().size()); + ovi_t val2 = ret.get().as(); + EXPECT_TRUE(val1 == val2); +} + +TEST(MSGPACK_BOOST, pack_convert_vector_optional) +{ + typedef std::vector > voi_t; + std::stringstream ss; + voi_t val1; + val1.resize(3); + val1[0] = 1; + val1[2] = 3; + msgpack::pack(ss, val1); + msgpack::unpacked ret; + msgpack::unpack(ret, ss.str().data(), ss.str().size()); + voi_t val2 = ret.get().as(); + EXPECT_TRUE(val1 == val2); +} + +TEST(MSGPACK_BOOST, object_nil) +{ + boost::optional val1; + msgpack::object obj(val1); + boost::optional val2 = obj.as >(); + EXPECT_TRUE(val1 == val2); +} + +TEST(MSGPACK_BOOST, object_int) +{ + boost::optional val1 = 1; + msgpack::object obj(val1); + boost::optional val2 = obj.as >(); + EXPECT_TRUE(val1 == val2); +} + +// Compile error as expected +/* +TEST(MSGPACK_BOOST, object_vector) +{ + typedef boost::optional > ovi_t; + ovi_t val1; + std::vector v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + val1 = v; + msgpack::object obj(val1); + ovi_t val2 = obj.as(); + EXPECT_TRUE(val1 == val2); +} +*/ + +TEST(MSGPACK_BOOST, object_with_zone_nil) +{ + msgpack::zone z; + boost::optional val1; + msgpack::object obj(val1, z); + boost::optional val2 = obj.as >(); + EXPECT_TRUE(val1 == val2); +} + +TEST(MSGPACK_BOOST, object_with_zone_int) +{ + msgpack::zone z; + boost::optional val1 = 1; + msgpack::object obj(val1, z); + boost::optional val2 = obj.as >(); + EXPECT_TRUE(val1 == val2); +} + +TEST(MSGPACK_BOOST, object_with_zone_vector_optional) +{ + typedef std::vector > voi_t; + msgpack::zone z; + voi_t val1; + val1.resize(3); + val1[0] = 1; + val1[2] = 3; + msgpack::object obj(val1, z); + voi_t val2 = obj.as(); + EXPECT_TRUE(val1 == val2); +} + +#endif // defined(MSGPACK_USE_BOOST)