// Boost.TypeErasure library // // Copyright 2011-2012 Steven Watanabe // // 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) // // $Id$ #if !defined(BOOST_PP_IS_ITERATING) #ifndef BOOST_TYPE_ERASURE_TUPLE_HPP_INCLUDED #define BOOST_TYPE_ERASURE_TUPLE_HPP_INCLUDED #include #ifdef BOOST_TYPE_ERASURE_DOXYGEN namespace boost { namespace type_erasure { /** * @ref tuple is a Boost.Fusion Random Access Sequence containing * @ref any "anys". @c Concept specifies the \Concept for each * of the elements. The remaining arguments must be (possibly const * and/or reference qualified) placeholders, which are the * @ref placeholder "placeholders" of the elements. */ template class tuple { public: /** * Constructs a tuple. Each element of @c args will * be used to initialize the corresponding @ref any member. * The @ref binding for the tuple elements is determined * by mapping the placeholders in @c T to the corresponding * types in @c U. */ template explicit tuple(U&&... args); }; /** * Returns the Nth @ref any in the tuple. */ template any& get(tuple& arg); /** \overload */ template const any& get(const tuple& arg); } } #elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace type_erasure { template struct cons; template struct cons { template cons(const Binding&) {} }; template struct cons { typedef any value_type; typedef cons rest_type; template cons(const Binding& b, U0&& u0, U&&... u) : value(std::forward(u0), b), rest(b, std::forward(u)...) {} any value; cons rest; }; namespace detail { template struct cons_advance { typedef typename cons_advance::type::rest_type type; static const type& call(const Cons& c) { return cons_advance::call(c).rest; } }; template struct cons_advance<0, Cons> { typedef Cons type; static const type& call(const Cons& c) { return c; } }; template struct make_map; template struct make_map { typedef typename ::boost::mpl::insert< typename ::boost::type_erasure::detail::make_map::type, T0 >::type type; }; template<> struct make_map<> { typedef ::boost::mpl::map0<> type; }; } /** INTERNAL ONLY */ template class tuple_iterator : public ::boost::fusion::iterator_facade< tuple_iterator, ::boost::fusion::random_access_traversal_tag > { public: typedef ::boost::mpl::int_ index; explicit tuple_iterator(Tuple& t_arg) : t(&t_arg) {} template struct value_of { typedef typename Tuple::template value_at >::type type; }; template struct deref { typedef typename Tuple::template at >::type type; static type call(It it) { return Tuple::template at >::call(*it.t); } }; template struct advance { typedef tuple_iterator type; static type call(It it) { return type(*it.t); } }; template struct next : advance > {}; template struct prior : advance > {}; template struct distance { typedef typename ::boost::mpl::minus< typename It2::index, typename It1::index >::type type; static type call(It1, It2) { return type(); } }; private: Tuple* t; }; template class tuple : public ::boost::fusion::sequence_facade< ::boost::type_erasure::tuple, ::boost::fusion::forward_traversal_tag > { public: template explicit tuple(U&&... args) : impl( ::boost::type_erasure::make_binding< typename ::boost::type_erasure::detail::make_map< ::boost::mpl::pair< typename ::boost::remove_const< typename ::boost::remove_reference::type >::type, typename ::boost::remove_const< typename ::boost::remove_reference::type >::type >... >::type >(), std::forward(args)...) {} template struct begin { typedef ::boost::type_erasure::tuple_iterator< Seq, 0 > type; static type call(Seq& seq) { return type(seq); } }; template struct end { typedef ::boost::type_erasure::tuple_iterator< Seq, sizeof...(T) > type; static type call(Seq& seq) { return type(seq); } }; template struct size { typedef ::boost::mpl::int_ type; static type call(Seq& seq) { return type(); } }; template struct empty { typedef ::boost::mpl::bool_ type; static type call(Seq& seq) { return type(); } }; template struct at { typedef typename ::boost::type_erasure::detail::cons_advance< N::value, ::boost::type_erasure::cons >::type::value_type value_type; typedef typename ::boost::mpl::if_< ::boost::is_const, const value_type&, value_type& >::type type; static type call(Seq& seq) { return const_cast( ::boost::type_erasure::detail::cons_advance< N::value, ::boost::type_erasure::cons >::call(seq.impl).value ); } }; template struct value_at { typedef typename ::boost::type_erasure::detail::cons_advance< N::value, ::boost::type_erasure::cons >::type::value_type value_type; }; ::boost::type_erasure::cons impl; }; template typename ::boost::type_erasure::detail::cons_advance< N, ::boost::type_erasure::cons >::type::value_type& get(::boost::type_erasure::tuple& t) { return const_cast< typename ::boost::type_erasure::detail::cons_advance< N, ::boost::type_erasure::cons >::type::value_type& >( ::boost::type_erasure::detail::cons_advance >::call(t.impl).value ); } template const typename ::boost::type_erasure::detail::cons_advance< N, ::boost::type_erasure::cons >::type::value_type& get(const ::boost::type_erasure::tuple& t) { return ::boost::type_erasure::detail::cons_advance< N, ::boost::type_erasure::cons >::call(t.impl).value; } } } #else #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace type_erasure { /** INTERNAL ONLY */ struct na {}; namespace detail { template struct get_impl; template struct tuple_storage; } /** INTERNAL ONLY */ template class tuple_iterator : public ::boost::fusion::iterator_facade< tuple_iterator, ::boost::fusion::random_access_traversal_tag > { public: typedef ::boost::mpl::int_ index; explicit tuple_iterator(Tuple& t_arg) : t(&t_arg) {} template struct value_of { typedef typename ::boost::type_erasure::detail::get_impl< It::index::value, Tuple >::value_type type; }; template struct deref : ::boost::type_erasure::detail::get_impl { typedef typename ::boost::type_erasure::detail::get_impl< It::index::value, Tuple >::type type; static type call(It it) { return ::boost::type_erasure::detail::get_impl< It::index::value, Tuple >::call(*it.t); } }; template struct advance { typedef tuple_iterator type; static type call(It it) { return type(*it.t); } }; template struct next : advance > {}; template struct prior : advance > {}; template struct distance { typedef typename ::boost::mpl::minus< typename It2::index, typename It1::index >::type type; static type call(It1, It2) { return type(); } }; private: Tuple* t; }; /** INTERNAL ONLY */ template struct tuple_base : ::boost::fusion::sequence_facade< Derived, ::boost::fusion::random_access_traversal_tag > { template struct begin { typedef ::boost::type_erasure::tuple_iterator type; static type call(Seq& seq) { return type(seq); } }; template struct end { typedef ::boost::type_erasure::tuple_iterator< Seq, Seq::tuple_size::value > type; static type call(Seq& seq) { return type(seq); } }; template struct size { typedef typename Seq::tuple_size type; static type call(Seq& seq) { return type(); } }; template struct empty { typedef typename boost::mpl::equal_to< typename Seq::tuple_size, boost::mpl::int_<0> >::type type; static type call(Seq& seq) { return type(); } }; template struct at : ::boost::type_erasure::detail::get_impl {}; template struct value_at { typedef typename ::boost::type_erasure::detail::get_impl< N::value, Seq >::value_type type; }; }; template class tuple; template< int N, class Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T) > typename detail::get_impl< N, tuple< Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) > >::type get( tuple< Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) >& arg) { return detail::get_impl< N, tuple< Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) > >::call(arg); } template< int N, class Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T) > typename detail::get_impl< N, const tuple< Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) > >::type get( const tuple< Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) >& arg) { return detail::get_impl< N, const tuple< Concept BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) > >::call(arg); } /** INTERNAL ONLY */ #define BOOST_PP_FILENAME_1 /** INTERNAL ONLY */ #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE) #include BOOST_PP_ITERATE() } } #endif #endif #else #define N BOOST_PP_ITERATION() #define BOOST_TYPE_ERASURE_TAG_TYPEDEF(z, n, data) \ typedef BOOST_PP_CAT(T, n) BOOST_PP_CAT(tag_type, n); \ typedef typename ::boost::remove_reference::type \ BOOST_PP_CAT(tag, n); #define BOOST_TYPE_ERASURE_PAIR(z, n, data) \ ::boost::mpl::pair #define BOOST_TYPE_ERASURE_CONSTRUCT(z, n, data)\ BOOST_PP_CAT(t, n)(BOOST_PP_CAT(u, n), table) #define BOOST_TYPE_ERASURE_TUPLE_MEMBER(z, n, data)\ ::boost::type_erasure::any BOOST_PP_CAT(t, n); #if N == 1 #define BOOST_TYPE_ERASURE_EXPLICIT explicit #else #define BOOST_TYPE_ERASURE_EXPLICIT #endif namespace detail { template struct tuple_storage #if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE #endif { #if N template tuple_storage( const Table& table BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, &u)) : BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONSTRUCT, ~) {} #else template explicit tuple_storage(const Table&) {} #endif BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_TUPLE_MEMBER, `) }; #if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE template struct get_impl { typedef any< typename Tuple::concept_type, typename Tuple::BOOST_PP_CAT(tag_type, N) > value_type; typedef value_type& type; static type call(Tuple& arg) { return arg.impl.BOOST_PP_CAT(t, N); } }; template struct get_impl { typedef any< typename Tuple::concept_type, typename Tuple::BOOST_PP_CAT(tag_type, N) > value_type; typedef const value_type& type; static type call(const Tuple& arg) { return arg.impl.BOOST_PP_CAT(t, N); } }; #endif } template class tuple #if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE #endif : public tuple_base > { typedef Concept concept_type; BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_TAG_TYPEDEF, ~) public: typedef ::boost::mpl::int_ tuple_size; #if N template #endif BOOST_TYPE_ERASURE_EXPLICIT tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)) : impl( ::boost::type_erasure::make_binding< ::boost::mpl::map< BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_PAIR, ~) > >() BOOST_PP_ENUM_TRAILING_PARAMS(N, u) ) {} #if N template BOOST_TYPE_ERASURE_EXPLICIT tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, const U, &u)) : impl( ::boost::type_erasure::make_binding< ::boost::mpl::map< BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_PAIR, ~) > >() BOOST_PP_ENUM_TRAILING_PARAMS(N, u) ) {} #endif private: template friend struct ::boost::type_erasure::detail::get_impl; ::boost::type_erasure::detail::tuple_storage< Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, T) > impl; }; #undef BOOST_TYPE_ERASURE_EXPLICIT #undef BOOST_TYPE_ERASURE_TUPLE_MEMBER #undef BOOST_TYPE_ERASURE_CONSTRUCT #undef BOOST_TYPE_ERASURE_PAIR #undef BOOST_TYPE_ERASURE_TAG_TYPEDEF #undef N #endif