From b4db293181f63803aff78937e5712bef26d5a07c Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Sat, 11 Nov 2017 15:44:31 +0900 Subject: [PATCH] Fixed #644. Added `as()` checking to MSGPACK_DEFINE family. --- Files.cmake | 1 + .../adaptor/detail/cpp11_convert_helper.hpp | 45 +++++++++++++++++++ .../v1/adaptor/detail/cpp11_define_array.hpp | 38 +++++++++++++++- .../v1/adaptor/detail/cpp11_define_map.hpp | 3 +- 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 include/msgpack/v1/adaptor/detail/cpp11_convert_helper.hpp diff --git a/Files.cmake b/Files.cmake index d055a231..cf2f5c14 100644 --- a/Files.cmake +++ b/Files.cmake @@ -541,6 +541,7 @@ IF (MSGPACK_ENABLE_CXX) include/msgpack/v1/adaptor/detail/cpp03_define_map_decl.hpp include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple.hpp include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple_decl.hpp + include/msgpack/v1/adaptor/detail/cpp11_convert_helper.hpp include/msgpack/v1/adaptor/detail/cpp11_define_array.hpp include/msgpack/v1/adaptor/detail/cpp11_define_array_decl.hpp include/msgpack/v1/adaptor/detail/cpp11_define_map.hpp diff --git a/include/msgpack/v1/adaptor/detail/cpp11_convert_helper.hpp b/include/msgpack/v1/adaptor/detail/cpp11_convert_helper.hpp new file mode 100644 index 00000000..f9e29ea6 --- /dev/null +++ b/include/msgpack/v1/adaptor/detail/cpp11_convert_helper.hpp @@ -0,0 +1,45 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2017 KONDO Takatoshi +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +#ifndef MSGPACK_V1_CPP11_CONVERT_HELPER_HPP +#define MSGPACK_V1_CPP11_CONVERT_HELPER_HPP + +#include + +#include + +namespace msgpack { +/// @cond +MSGPACK_API_VERSION_NAMESPACE(v1) { +/// @endcond +namespace type { + +template +inline typename std::enable_if< + has_as::value +>::type +convert_helper(msgpack::object const& o, T& t) { + t = o.as(); +} +template +inline typename std::enable_if< + !has_as::value +>::type +convert_helper(msgpack::object const& o, T& t) { + o.convert(t); +} + +} // namespace type + +/// @cond +} // MSGPACK_API_VERSION_NAMESPACE(v1) +/// @endcond +} // namespace msgpack + +#endif // MSGPACK_V1_CPP11_CONVERT_HELPER_HPP diff --git a/include/msgpack/v1/adaptor/detail/cpp11_define_array.hpp b/include/msgpack/v1/adaptor/detail/cpp11_define_array.hpp index 702fea45..feddec52 100644 --- a/include/msgpack/v1/adaptor/detail/cpp11_define_array.hpp +++ b/include/msgpack/v1/adaptor/detail/cpp11_define_array.hpp @@ -11,6 +11,7 @@ #define MSGPACK_V1_CPP11_DEFINE_ARRAY_HPP #include "msgpack/v1/adaptor/detail/cpp11_define_array_decl.hpp" +#include "msgpack/v1/adaptor/detail/cpp11_convert_helper.hpp" #include @@ -20,6 +21,39 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { /// @endcond namespace type { +namespace detail { +template +struct get; + +template +struct get> +{ + using type = typename get>::type; +}; + +template +struct get<0, std::tuple> +{ + using type = T; +}; + +template +inline typename std::enable_if< + has_as::value +>::type +unpack_impl(msgpack::object const& o, T& t) { + t = o.as(); +} +template +inline typename std::enable_if< + !has_as::value +>::type +unpack_impl(msgpack::object const& o, T& t) { + o.convert(t); +} + +} // namespace detail + template struct define_array_imp { template @@ -31,7 +65,7 @@ struct define_array_imp { define_array_imp::unpack(o, t); const size_t size = o.via.array.size; if(size <= N-1) { return; } - o.via.array.ptr[N-1].convert(std::get(t)); + convert_helper(o.via.array.ptr[N-1], std::get(t)); } static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) { define_array_imp::object(o, z, t); @@ -48,7 +82,7 @@ struct define_array_imp { static void unpack(msgpack::object const& o, Tuple& t) { const size_t size = o.via.array.size; if(size <= 0) { return; } - o.via.array.ptr[0].convert(std::get<0>(t)); + convert_helper(o.via.array.ptr[0], std::get<0>(t)); } static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) { o->via.array.ptr[0] = msgpack::object(std::get<0>(t), z); diff --git a/include/msgpack/v1/adaptor/detail/cpp11_define_map.hpp b/include/msgpack/v1/adaptor/detail/cpp11_define_map.hpp index 0fca1d87..835e1d88 100644 --- a/include/msgpack/v1/adaptor/detail/cpp11_define_map.hpp +++ b/include/msgpack/v1/adaptor/detail/cpp11_define_map.hpp @@ -11,6 +11,7 @@ #define MSGPACK_V1_CPP11_DEFINE_MAP_HPP #include "msgpack/v1/adaptor/detail/cpp11_define_map_decl.hpp" +#include "msgpack/v1/adaptor/detail/cpp11_convert_helper.hpp" #include #include @@ -34,7 +35,7 @@ struct define_map_imp { define_map_imp::unpack(o, t, kvmap); auto it = kvmap.find(std::get(t)); if (it != kvmap.end()) { - it->second->convert(std::get(t)); + convert_helper(*it->second, std::get(t)); } } static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) {