diff --git a/CMakeLists.txt b/CMakeLists.txt index 3aed68d4..f59968e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,7 @@ IF (MSGPACK_ENABLE_CXX) include/msgpack/adaptor/cpp11/array_char.hpp include/msgpack/adaptor/cpp11/array_unsigned_char.hpp include/msgpack/adaptor/cpp11/forward_list.hpp + include/msgpack/adaptor/cpp11/reference_wrapper.hpp include/msgpack/adaptor/cpp11/shared_ptr.hpp include/msgpack/adaptor/cpp11/tuple.hpp include/msgpack/adaptor/cpp11/unique_ptr.hpp diff --git a/include/msgpack/adaptor/cpp11/reference_wrapper.hpp b/include/msgpack/adaptor/cpp11/reference_wrapper.hpp new file mode 100644 index 00000000..214a6a7f --- /dev/null +++ b/include/msgpack/adaptor/cpp11/reference_wrapper.hpp @@ -0,0 +1,75 @@ +// +// 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_CPP11_REFERENCE_WRAPPER_HPP +#define MSGPACK_CPP11_REFERENCE_WRAPPER_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, std::reference_wrapper& v) const { + msgpack::adaptor::convert()(o, v.get()); + return o; + } +}; + +template +struct pack> { + template + msgpack::packer& operator()(msgpack::packer& o, const std::reference_wrapper& v) const { + o.pack(v.get()); + return o; + } +}; + +template +struct object > { + void operator()(msgpack::object& o, const std::reference_wrapper& v) const { + msgpack::adaptor::object()(o, v.get()); + } +}; + +template +struct object_with_zone> { + void operator()(msgpack::object::with_zone& o, const std::reference_wrapper& v) const { + msgpack::adaptor::object_with_zone()(o, v.get()); + } +}; + +} // namespace adaptor + +/// @cond +} // MSGPACK_API_VERSION_NAMESPACE(v1) +/// @endcond + +} // namespace msgpack + +#endif // MSGPACK_CPP11_REFERENCE_WRAPPER_HPP diff --git a/include/msgpack/type.hpp b/include/msgpack/type.hpp index 2475d43d..7ac236ea 100644 --- a/include/msgpack/type.hpp +++ b/include/msgpack/type.hpp @@ -33,6 +33,7 @@ #include "adaptor/cpp11/array_char.hpp" #include "adaptor/cpp11/array_unsigned_char.hpp" #include "adaptor/cpp11/forward_list.hpp" +#include "adaptor/cpp11/reference_wrapper.hpp" #include "adaptor/cpp11/shared_ptr.hpp" #include "adaptor/cpp11/tuple.hpp" #include "adaptor/cpp11/unique_ptr.hpp" diff --git a/src/Makefile.am b/src/Makefile.am index a6066aaa..13b766da 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -185,6 +185,7 @@ nobase_include_HEADERS += \ ../include/msgpack/adaptor/cpp11/array_char.hpp \ ../include/msgpack/adaptor/cpp11/array_unsigned_char.hpp \ ../include/msgpack/adaptor/cpp11/forward_list.hpp \ + ../include/msgpack/adaptor/cpp11/reference_wrapper.hpp \ ../include/msgpack/adaptor/cpp11/shared_ptr.hpp \ ../include/msgpack/adaptor/cpp11/tuple.hpp \ ../include/msgpack/adaptor/cpp11/unique_ptr.hpp \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 25166ae8..6c0f3202 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -48,9 +48,10 @@ IF (MSGPACK_CXX11) LIST (APPEND check_PROGRAMS iterator_cpp11.cpp msgpack_cpp11.cpp + reference_cpp11.cpp + reference_wrapper_cpp11.cpp shared_ptr_cpp11.cpp unique_ptr_cpp11.cpp - reference_cpp11.cpp ) ENDIF () diff --git a/test/Makefile.am b/test/Makefile.am index 70651449..b2a3767c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -39,6 +39,7 @@ check_PROGRAMS += \ iterator_cpp11 \ msgpack_cpp11 \ reference_cpp11 \ + reference_wrapper_cpp11 \ shared_ptr_cpp11 \ unique_ptr_cpp11 @@ -76,6 +77,7 @@ zone_SOURCES = zone.cpp iterator_cpp11_SOURCES = iterator_cpp11.cpp msgpack_cpp11_SOURCES = msgpack_cpp11.cpp reference_cpp11_SOURCES = reference_cpp11.cpp +reference_wrapper_cpp11_SOURCES = reference_wrapper_cpp11.cpp shared_ptr_cpp11_SOURCES = shared_ptr_cpp11.cpp unique_ptr_cpp11_SOURCES = unique_ptr_cpp11.cpp diff --git a/test/reference_wrapper_cpp11.cpp b/test/reference_wrapper_cpp11.cpp new file mode 100644 index 00000000..b1ed8876 --- /dev/null +++ b/test/reference_wrapper_cpp11.cpp @@ -0,0 +1,59 @@ +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if !defined(MSGPACK_USE_CPP03) + +TEST(MSGPACK_REFERENCE_WRAPPER, pack_convert) +{ + int i1 = 42; + std::reference_wrapper val1(i1); + std::stringstream ss; + msgpack::pack(ss, val1); + msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size()); + int i2 = 0; + std::reference_wrapper val2(i2); + oh.get().convert(val2);; + EXPECT_EQ(i1, i2); +} + +TEST(MSGPACK_REFERENCE_WRAPPER, pack_vector) +{ + int i1 = 42; + std::vector> val1{i1}; + std::stringstream ss; + msgpack::pack(ss, val1); + msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size()); + std::vector val2 = oh.get().as>(); + EXPECT_EQ(val2.size(), 1); + EXPECT_EQ(val1[0], val2[0]); +} + +TEST(MSGPACK_REFERENCE_WRAPPER, object) +{ + int i1 = 42; + std::reference_wrapper val1(i1); + msgpack::object o(val1); + int i2 = 0; + std::reference_wrapper val2(i2); + o.convert(val2); + EXPECT_EQ(i1, i2); +} + +TEST(MSGPACK_REFERENCE_WRAPPER, object_with_zone) +{ + std::string s1 = "ABC"; + std::reference_wrapper val1(s1); + msgpack::zone z; + msgpack::object o(val1, z); + std::string s2 = "DE"; + std::reference_wrapper val2(s2); + o.convert(val2); + EXPECT_EQ(s1, s2); +} + +#endif // !defined(MSGPACK_USE_CPP03)