// // MessagePack for C++ static resolution routine // // Copyright (C) 2008 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_TUPLE_HPP__ #define MSGPACK_TYPE_TUPLE_HPP__ #include "msgpack/object.hpp" namespace msgpack { namespace type { // FIXME operator== // FIXME operator!= <% GENERATION_LIMIT = 15 %> template < typename A0 <%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%> > struct tuple; template <typename Tuple, int N> struct tuple_type; template <typename Tuple, int N> struct const_tuple_type; template <typename T> struct tuple_element { typedef T type; tuple_element(T& x) : _x(x) {} type& get() { return _x; } const type& get() const { return _x; } private: type& _x; }; template <typename T> struct const_tuple_element { typedef T type; const_tuple_element(const T& x) : _x(x) {} const type& get() const { return _x; } private: const type& _x; }; <%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(i) {|j|%> template < typename A0 <%1.upto(i) {|k|%>, typename A<%=k%> <%}%>> struct tuple_type<tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>, <%=j%>> : tuple_element<A<%=j%>> { tuple_type(tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : tuple_element<A<%=j%>>(x.a<%=j%>) {} }; <%}%> <%}%> <%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(i) {|j|%> template < typename A0 <%1.upto(i) {|k|%>, typename A<%=k%> <%}%>> struct const_tuple_type<tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>, <%=j%>> : const_tuple_element<A<%=j%>> { const_tuple_type(const tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : const_tuple_element<A<%=j%>>(x.a<%=j%>) {} }; <%}%> <%}%> <%0.upto(GENERATION_LIMIT) {|i|%> template < typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>> tuple< A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>> make_tuple(const A0& a0 <%1.upto(i) {|j|%>, const A<%=j%>& a<%=j%><%}%>) { return tuple< A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>(a0 <%1.upto(i) {|j|%>, a<%=j%><%}%>); } <%}%> <%0.upto(GENERATION_LIMIT) {|i|%> template < typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>> struct tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>> { tuple() {} tuple(const A0& _a0 <%1.upto(i) {|j|%>, const A<%=j%>& _a<%=j%><%}%>) : a0(_a0) <%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {} tuple(object o) { convert(*this, o); } template <int N> typename tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>::type& get() { return tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>(*this).get(); } template <int N> const typename const_tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>::type& get() const { return const_tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>(*this).get(); } <%0.upto(i) {|j|%> A<%=j%> a<%=j%>;<%}%> }; <%}%> <%0.upto(GENERATION_LIMIT) {|i|%> template < typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>> tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& operator<< ( tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& v, object o) { if(o.type != ARRAY) { throw type_error(); } if(o.via.container.size < <%=i+1%>) { throw type_error(); } <%0.upto(i) {|j|%> convert<A<%=j%>>(v.template get<<%=j%>>(), o.via.container.ptr[<%=j%>]);<%}%> return v; } <%}%> // FIXME /* template <typename A0, typename A1 = void, typename A2 = void> struct tuple_just; template <typename A0> struct tuple_just<A0> { A0 a0; static inline void convert(object o, tuple_just<A0>& v) { if(o.type != ARRAY) { throw type_error(); } if(o.v.container.size != 1) { throw type_error(); } msgpack::convert<A0>(o.v.container.ptr[0], v.a0); } }; template <typename A0, typename A1> struct tuple_just<A0, A1> { A0 a0; A1 a1; static inline void convert(object o, tuple_just<A0, A1>& v) { if(o.type != ARRAY) { throw type_error(); } if(o.v.container.size != 2) { throw type_error(); } msgpack::convert<A0>(o.v.container.ptr[0], v.a0); msgpack::convert<A1>(o.v.container.ptr[1], v.a1); } }; */ <%0.upto(GENERATION_LIMIT) {|i|%> template < typename Stream , typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>> const tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& operator>> ( const tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& v, packer<Stream> o) { o.pack_array(<%=i+1%>); <%0.upto(i) {|j|%> pack(v.template get<<%=j%>>(), o);<%}%> return v; } <%}%> } // namespace type } // namespace msgpack #endif /* msgpack/type/tuple.hpp */