messagepack implementation for embedded systems (mbed / arduino)
Dependents: hello_message_pack
cpp11_msgpack_tuple.hpp
00001 // 00002 // MessagePack for C++ static resolution routine 00003 // 00004 // Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi 00005 // 00006 // Distributed under the Boost Software License, Version 1.0. 00007 // (See accompanying file LICENSE_1_0.txt or copy at 00008 // http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 #ifndef MSGPACK_CPP11_MSGPACK_TUPLE_HPP 00011 #define MSGPACK_CPP11_MSGPACK_TUPLE_HPP 00012 00013 #include "msgpack/versioning.hpp" 00014 #include "msgpack/object_fwd.hpp" 00015 #include "msgpack/meta.hpp" 00016 00017 #include <tuple> 00018 00019 namespace msgpack { 00020 00021 /// @cond 00022 MSGPACK_API_VERSION_NAMESPACE(v1) { 00023 /// @endcond 00024 00025 namespace type { 00026 // tuple 00027 using std::get; 00028 using std::tuple_size; 00029 using std::tuple_element; 00030 using std::uses_allocator; 00031 using std::ignore; 00032 using std::swap; 00033 00034 template< class... Types > 00035 class tuple : public std::tuple<Types...> { 00036 public: 00037 using base = std::tuple<Types...>; 00038 00039 using base::base; 00040 00041 tuple() = default; 00042 tuple(tuple const&) = default; 00043 tuple(tuple&&) = default; 00044 00045 template<typename... OtherTypes> 00046 tuple(tuple<OtherTypes...> const& other):base(static_cast<std::tuple<OtherTypes...> const&>(other)) {} 00047 template<typename... OtherTypes> 00048 tuple(tuple<OtherTypes...> && other):base(static_cast<std::tuple<OtherTypes...> &&>(other)) {} 00049 00050 tuple& operator=(tuple const&) = default; 00051 tuple& operator=(tuple&&) = default; 00052 00053 template<typename... OtherTypes> 00054 tuple& operator=(tuple<OtherTypes...> const& other) { 00055 *static_cast<base*>(this) = static_cast<std::tuple<OtherTypes...> const&>(other); 00056 return *this; 00057 } 00058 template<typename... OtherTypes> 00059 tuple& operator=(tuple<OtherTypes...> && other) { 00060 *static_cast<base*>(this) = static_cast<std::tuple<OtherTypes...> &&>(other); 00061 return *this; 00062 } 00063 00064 template< std::size_t I> 00065 typename tuple_element<I, base >::type& 00066 get() & { return std::get<I>(*this); } 00067 00068 template< std::size_t I> 00069 typename tuple_element<I, base >::type const& 00070 get() const& { return std::get<I>(*this); } 00071 00072 template< std::size_t I> 00073 typename tuple_element<I, base >::type&& 00074 get() && { return std::get<I>(*this); } 00075 }; 00076 00077 template <class... Args> 00078 inline tuple<Args...> make_tuple(Args&&... args) { 00079 return tuple<Args...>(args...); 00080 } 00081 00082 template<class... Args> 00083 inline tuple<Args&&...> forward_as_tuple (Args&&... args) noexcept { 00084 return tuple<Args&&...>(std::forward<Args>(args)...); 00085 } 00086 00087 template <class... Tuples> 00088 inline auto tuple_cat(Tuples&&... args) -> 00089 decltype( 00090 std::tuple_cat(std::forward<typename std::remove_reference<Tuples>::type::base>(args)...) 00091 ) { 00092 return std::tuple_cat(std::forward<typename std::remove_reference<Tuples>::type::base>(args)...); 00093 } 00094 template <class... Args> 00095 inline tuple<Args&...> tie(Args&... args) { 00096 return tuple<Args&...>(args...); 00097 } 00098 } // namespace type 00099 00100 // --- Pack from tuple to packer stream --- 00101 template <typename Stream, typename Tuple, std::size_t N> 00102 struct MsgpackTuplePacker { 00103 static void pack( 00104 msgpack::packer<Stream> & o, 00105 const Tuple& v) { 00106 MsgpackTuplePacker<Stream, Tuple, N-1>::pack(o, v); 00107 o.pack(type::get<N-1>(v)); 00108 } 00109 }; 00110 00111 template <typename Stream, typename Tuple> 00112 struct MsgpackTuplePacker<Stream, Tuple, 1> { 00113 static void pack ( 00114 msgpack::packer<Stream> & o, 00115 const Tuple& v) { 00116 o.pack(type::get<0>(v)); 00117 } 00118 }; 00119 00120 template <typename Stream, typename Tuple> 00121 struct MsgpackTuplePacker<Stream, Tuple, 0> { 00122 static void pack ( 00123 msgpack::packer<Stream> &, 00124 const Tuple&) { 00125 } 00126 }; 00127 00128 namespace adaptor { 00129 00130 template <typename... Args> 00131 struct pack<msgpack::type::tuple<Args...>> { 00132 template <typename Stream> 00133 msgpack::packer<Stream> & operator()( 00134 msgpack::packer<Stream> & o, 00135 const msgpack::type::tuple<Args...>& v) const { 00136 o.pack_array(sizeof...(Args)); 00137 MsgpackTuplePacker<Stream, decltype(v), sizeof...(Args)>::pack(o, v); 00138 return o; 00139 } 00140 }; 00141 00142 } // namespace adaptor 00143 00144 // --- Convert from tuple to object --- 00145 00146 template <typename... Args> 00147 struct MsgpackTupleAs; 00148 00149 template <typename T, typename... Args> 00150 struct MsgpackTupleAsImpl { 00151 static msgpack::type::tuple<T, Args...> as(msgpack::object const& o) { 00152 return msgpack::type::tuple_cat( 00153 msgpack::type::make_tuple(o.via.array.ptr[o.via.array.size - sizeof...(Args) - 1].as<T>()), 00154 MsgpackTupleAs<Args...>::as(o)); 00155 } 00156 }; 00157 00158 template <typename... Args> 00159 struct MsgpackTupleAs { 00160 static msgpack::type::tuple<Args...> as(msgpack::object const& o) { 00161 return MsgpackTupleAsImpl<Args...>::as(o); 00162 } 00163 }; 00164 00165 template <> 00166 struct MsgpackTupleAs<> { 00167 static msgpack::type::tuple<> as (msgpack::object const&) { 00168 return msgpack::type::tuple<>(); 00169 } 00170 }; 00171 00172 template <typename Tuple, std::size_t N> 00173 struct MsgpackTupleConverter { 00174 static void convert( 00175 msgpack::object const& o, 00176 Tuple& v) { 00177 MsgpackTupleConverter<Tuple, N-1>::convert(o, v); 00178 o.via.array.ptr[N-1].convert<typename std::remove_reference<decltype(type::get<N-1>(v))>::type>(type::get<N-1>(v)); 00179 } 00180 }; 00181 00182 template <typename Tuple> 00183 struct MsgpackTupleConverter<Tuple, 1> { 00184 static void convert ( 00185 msgpack::object const& o, 00186 Tuple& v) { 00187 o.via.array.ptr[0].convert<typename std::remove_reference<decltype(type::get<0>(v))>::type>(type::get<0>(v)); 00188 } 00189 }; 00190 00191 template <typename Tuple> 00192 struct MsgpackTupleConverter<Tuple, 0> { 00193 static void convert ( 00194 msgpack::object const&, 00195 Tuple&) { 00196 } 00197 }; 00198 00199 namespace adaptor { 00200 00201 template <typename... Args> 00202 struct as<msgpack::type::tuple<Args...>, typename std::enable_if<msgpack::all_of<msgpack::has_as, Args...>::value>::type> { 00203 msgpack::type::tuple<Args...> operator()( 00204 msgpack::object const& o) const { 00205 if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } 00206 if (o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); } 00207 return MsgpackTupleAs<Args...>::as(o); 00208 } 00209 }; 00210 00211 template <typename... Args> 00212 struct convert<msgpack::type::tuple<Args...>> { 00213 msgpack::object const& operator()( 00214 msgpack::object const& o, 00215 msgpack::type::tuple<Args...>& v) const { 00216 if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } 00217 if(o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); } 00218 MsgpackTupleConverter<decltype(v), sizeof...(Args)>::convert(o, v); 00219 return o; 00220 } 00221 }; 00222 00223 } // namespace adaptor 00224 00225 // --- Convert from tuple to object with zone --- 00226 template <typename Tuple, std::size_t N> 00227 struct MsgpackTupleToObjectWithZone { 00228 static void convert( 00229 msgpack::object::with_zone& o, 00230 const Tuple& v) { 00231 MsgpackTupleToObjectWithZone<Tuple, N-1>::convert(o, v); 00232 o.via.array.ptr[N-1] = msgpack::object(type::get<N-1>(v), o.zone); 00233 } 00234 }; 00235 00236 template <typename Tuple> 00237 struct MsgpackTupleToObjectWithZone<Tuple, 1> { 00238 static void convert ( 00239 msgpack::object::with_zone& o, 00240 const Tuple& v) { 00241 o.via.array.ptr[0] = msgpack::object(type::get<0>(v), o.zone); 00242 } 00243 }; 00244 00245 template <typename Tuple> 00246 struct MsgpackTupleToObjectWithZone<Tuple, 0> { 00247 static void convert ( 00248 msgpack::object::with_zone&, 00249 const Tuple&) { 00250 } 00251 }; 00252 00253 namespace adaptor { 00254 00255 template <typename... Args> 00256 struct object_with_zone<msgpack::type::tuple<Args...>> { 00257 void operator()( 00258 msgpack::object::with_zone& o, 00259 msgpack::type::tuple<Args...> const& v) const { 00260 o.type = msgpack::type::ARRAY; 00261 o.via.array.ptr = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*sizeof...(Args))); 00262 o.via.array.size = sizeof...(Args); 00263 MsgpackTupleToObjectWithZone<decltype(v), sizeof...(Args)>::convert(o, v); 00264 } 00265 }; 00266 00267 } // namespace adaptor 00268 00269 /// @cond 00270 } // MSGPACK_API_VERSION_NAMESPACE(v1) 00271 ///@endcond 00272 00273 } // namespace msgpack 00274 00275 #endif // MSGPACK_CPP11_MSGPACK_TUPLE_HPP 00276
Generated on Tue Jul 12 2022 22:51:45 by 1.7.2