// // MessagePack for C++ static resolution routine // // Copyright (C) 2008-2016 FURUHASHI Sadayuki and 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_CPP03_MSGPACK_TUPLE_HPP #define MSGPACK_V1_CPP03_MSGPACK_TUPLE_HPP #include "msgpack/v1/adaptor/msgpack_tuple_decl.hpp" namespace msgpack { /// @cond MSGPACK_API_VERSION_NAMESPACE(v1) { /// @endcond namespace type { // FIXME operator== // FIXME operator!= <% GENERATION_LIMIT = 31 %> template struct tuple_type { typedef T type; typedef T value_type; typedef T& reference; typedef const T& const_reference; typedef const T& transparent_reference; }; template struct tuple_type { typedef T type; typedef T& value_type; typedef T& reference; typedef const T& const_reference; typedef T& transparent_reference; }; template struct tuple_type { typedef T type; typedef T& value_type; typedef T& reference; typedef const T& const_reference; typedef const T& transparent_reference; }; /// @cond <%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(i) {|j|%> template , typename A<%=k%><%}%>> struct tuple_element, A<%=k%><%}%>>, <%=j%>> : tuple_type> { tuple_element(tuple, A<%=k%> <%}%>>& x) : m_x(x.a<%=j%>) {} typename tuple_type>::reference get() { return m_x; } typename tuple_type>::const_reference get() const { return m_x; } private: typename tuple_type>::reference m_x; }; <%}%> <%}%> <%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(i) {|j|%> template , typename A<%=k%><%}%>> struct const_tuple_element, A<%=k%><%}%>>, <%=j%>> : tuple_type> { const_tuple_element(const tuple, A<%=k%><%}%>>& x) : m_x(x.a<%=j%>) {} typename tuple_type>::const_reference get() const { return m_x; } private: typename tuple_type>::const_reference m_x; }; <%}%> <%}%> /// @endcond template <> struct tuple<> { tuple() {} tuple(msgpack::object const& o) { o.convert(*this); } typedef tuple<> value_type; std::size_t size() const { return 0; } }; /// @cond <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> struct tuple, A<%=j%><%}%>> { typedef tuple, A<%=j%><%}%>> value_type; std::size_t size() const { return <%=i+1%>; } tuple() {} tuple(typename tuple_type::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type>::transparent_reference _a<%=j%><%}%>) : a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {} tuple(msgpack::object const& o) { o.convert(*this); } template typename tuple_element::reference get() { return tuple_element(*this).get(); } template typename const_tuple_element::const_reference get() const { return const_tuple_element(*this).get(); } <%0.upto(i) {|j|%> A<%=j%> a<%=j%>;<%}%> }; template , typename A<%=j%><%}%>> inline typename type::tuple_element, A<%=j%><%}%>>, N>::reference get(type::tuple, A<%=j%><%}%>>& t) { return t.template get(); } template , typename A<%=j%><%}%>> inline typename type::const_tuple_element, A<%=j%><%}%>>, N>::const_reference get(type::tuple, A<%=j%><%}%>> const& t) { return t.template get(); } <%}%> /// @endcond inline tuple<> make_tuple() { return tuple<>(); } /// @cond <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> tuple, A<%=j%><%}%>> make_tuple(A0 const& a0<%1.upto(i) {|j|%>, A<%=j%> const& a<%=j%><%}%>) { return tuple, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>); } <%}%> /// @endcond } // namespace type namespace adaptor { template <> struct convert > { msgpack::object const& operator()( msgpack::object const& o, type::tuple<>&) const { if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } return o; } }; /// @cond <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> struct convert, A<%=j%><%}%>> > { msgpack::object const& operator()( msgpack::object const& o, type::tuple, A<%=j%><%}%>>& v) const { if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } <%0.upto(i) {|j|%> // In order to avoid clang++'s invalid warning, msgpack::object:: has been added. if(o.via.array.size > <%=j%>) o.via.array.ptr[<%=j%>].msgpack::object::convert>::type>(v.template get<<%=j%>>());<%}%> return o; } }; <%}%> /// @endcond template <> struct pack > { template msgpack::packer& operator()( msgpack::packer& o, const type::tuple<>&) const { o.pack_array(0); return o; } }; /// @cond <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> struct pack, A<%=j%><%}%>> > { template msgpack::packer& operator()( msgpack::packer& o, const type::tuple, A<%=j%><%}%>>& v) const { o.pack_array(<%=i+1%>); <%0.upto(i) {|j|%> o.pack(v.template get<<%=j%>>());<%}%> return o; } }; <%}%> /// @endcond template <> struct object_with_zone > { void operator()( msgpack::object::with_zone& o, const type::tuple<>&) const { o.type = msgpack::type::ARRAY; o.via.array.ptr = MSGPACK_NULLPTR; o.via.array.size = 0; } }; /// @cond <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> struct object_with_zone, A<%=j%><%}%>> > { void operator()( msgpack::object::with_zone& o, const type::tuple, A<%=j%><%}%>>& v) const { o.type = msgpack::type::ARRAY; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object)*<%=i+1%>, MSGPACK_ZONE_ALIGNOF(msgpack::object))); o.via.array.size = <%=i+1%>; <%0.upto(i) {|j|%> o.via.array.ptr[<%=j%>] = msgpack::object(v.template get<<%=j%>>(), o.zone);<%}%> } }; <%}%> /// @endcond } // namespace adaptor /// @cond } // MSGPACK_API_VERSION_NAMESPACE(v1) /// @endcond } // namespace msgpack #endif // MSGPACK_V1_CPP03_MSGPACK_TUPLE_HPP