| 1 | ////////////////////////////////////////////////////////////////////////////// | 
| 2 | // | 
| 3 | // (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost | 
| 4 | // Software License, Version 1.0. (See accompanying file | 
| 5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 
| 6 | // | 
| 7 | // See http://www.boost.org/libs/container for documentation. | 
| 8 | // | 
| 9 | ////////////////////////////////////////////////////////////////////////////// | 
| 10 |  | 
| 11 | #ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP | 
| 12 | #define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP | 
| 13 |  | 
| 14 | #ifndef BOOST_CONFIG_HPP | 
| 15 | #  include <boost/config.hpp> | 
| 16 | #endif | 
| 17 |  | 
| 18 | #if defined(BOOST_HAS_PRAGMA_ONCE) | 
| 19 | #  pragma once | 
| 20 | #endif | 
| 21 |  | 
| 22 | #include <boost/container/detail/config_begin.hpp> | 
| 23 | #include <boost/container/detail/workaround.hpp> | 
| 24 | #include <boost/move/utility_core.hpp> | 
| 25 |  | 
| 26 | #include <boost/container/detail/type_traits.hpp> | 
| 27 | #include <cstddef>   //std::size_t | 
| 28 |  | 
| 29 | namespace boost { | 
| 30 | namespace container { | 
| 31 | namespace container_detail { | 
| 32 |  | 
| 33 | template<typename... Values> | 
| 34 | class tuple; | 
| 35 |  | 
| 36 | template<> class tuple<> | 
| 37 | {}; | 
| 38 |  | 
| 39 | template<typename Head, typename... Tail> | 
| 40 | class tuple<Head, Tail...> | 
| 41 |    : private tuple<Tail...> | 
| 42 | { | 
| 43 |    typedef tuple<Tail...> inherited; | 
| 44 |  | 
| 45 |    public: | 
| 46 |    tuple() | 
| 47 |       : inherited(), m_head() | 
| 48 |    {} | 
| 49 |  | 
| 50 |    template<class U, class ...Args> | 
| 51 |    tuple(U &&u, Args && ...args) | 
| 52 |       : inherited(::boost::forward<Args>(args)...), m_head(::boost::forward<U>(u)) | 
| 53 |    {} | 
| 54 |  | 
| 55 |    // Construct tuple from another tuple. | 
| 56 |    template<typename... VValues> | 
| 57 |    tuple(const tuple<VValues...>& other) | 
| 58 |       : inherited(other.tail()), m_head(other.head()) | 
| 59 |    {} | 
| 60 |  | 
| 61 |    template<typename... VValues> | 
| 62 |    tuple& operator=(const tuple<VValues...>& other) | 
| 63 |    { | 
| 64 |       m_head = other.head(); | 
| 65 |       tail() = other.tail(); | 
| 66 |       return this; | 
| 67 |    } | 
| 68 |  | 
| 69 |    typename add_reference<Head>::type head()             {  return m_head; } | 
| 70 |    typename add_reference<const Head>::type head() const {  return m_head; } | 
| 71 |  | 
| 72 |    inherited& tail()             { return *this; } | 
| 73 |    const inherited& tail() const { return *this; } | 
| 74 |  | 
| 75 |    protected: | 
| 76 |    Head m_head; | 
| 77 | }; | 
| 78 |  | 
| 79 |  | 
| 80 | template<typename... Values> | 
| 81 | tuple<Values&&...> forward_as_tuple(Values&&... values) | 
| 82 | { return tuple<Values&&...>(::boost::forward<Values>(values)...); } | 
| 83 |  | 
| 84 | template<int I, typename Tuple> | 
| 85 | struct tuple_element; | 
| 86 |  | 
| 87 | template<int I, typename Head, typename... Tail> | 
| 88 | struct tuple_element<I, tuple<Head, Tail...> > | 
| 89 | { | 
| 90 |    typedef typename tuple_element<I-1, tuple<Tail...> >::type type; | 
| 91 | }; | 
| 92 |  | 
| 93 | template<typename Head, typename... Tail> | 
| 94 | struct tuple_element<0, tuple<Head, Tail...> > | 
| 95 | { | 
| 96 |    typedef Head type; | 
| 97 | }; | 
| 98 |  | 
| 99 | template<int I, typename Tuple> | 
| 100 | class get_impl; | 
| 101 |  | 
| 102 | template<int I, typename Head, typename... Values> | 
| 103 | class get_impl<I, tuple<Head, Values...> > | 
| 104 | { | 
| 105 |    typedef typename tuple_element<I-1, tuple<Values...> >::type   Element; | 
| 106 |    typedef get_impl<I-1, tuple<Values...> >                       Next; | 
| 107 |  | 
| 108 |    public: | 
| 109 |    typedef typename add_reference<Element>::type                  type; | 
| 110 |    typedef typename add_const_reference<Element>::type            const_type; | 
| 111 |    static type get(tuple<Head, Values...>& t)              { return Next::get(t.tail()); } | 
| 112 |    static const_type get(const tuple<Head, Values...>& t)  { return Next::get(t.tail()); } | 
| 113 | }; | 
| 114 |  | 
| 115 | template<typename Head, typename... Values> | 
| 116 | class get_impl<0, tuple<Head, Values...> > | 
| 117 | { | 
| 118 |    public: | 
| 119 |    typedef typename add_reference<Head>::type         type; | 
| 120 |    typedef typename add_const_reference<Head>::type   const_type; | 
| 121 |    static type       get(tuple<Head, Values...>& t)      { return t.head(); } | 
| 122 |    static const_type get(const tuple<Head, Values...>& t){ return t.head(); } | 
| 123 | }; | 
| 124 |  | 
| 125 | template<int I, typename... Values> | 
| 126 | typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t) | 
| 127 | {  return get_impl<I, tuple<Values...> >::get(t);  } | 
| 128 |  | 
| 129 | template<int I, typename... Values> | 
| 130 | typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t) | 
| 131 | {  return get_impl<I, tuple<Values...> >::get(t);  } | 
| 132 |  | 
| 133 | //////////////////////////////////////////////////// | 
| 134 | // Builds an index_tuple<0, 1, 2, ..., Num-1>, that will | 
| 135 | // be used to "unpack" into comma-separated values | 
| 136 | // in a function call. | 
| 137 | //////////////////////////////////////////////////// | 
| 138 |  | 
| 139 | template<std::size_t...> struct index_tuple{ typedef index_tuple type; }; | 
| 140 |  | 
| 141 | template<class S1, class S2> struct concat_index_tuple; | 
| 142 |  | 
| 143 | template<std::size_t... I1, std::size_t... I2> | 
| 144 | struct concat_index_tuple<index_tuple<I1...>, index_tuple<I2...>> | 
| 145 |   : index_tuple<I1..., (sizeof...(I1)+I2)...>{}; | 
| 146 |  | 
| 147 | template<std::size_t N> struct build_number_seq; | 
| 148 |  | 
| 149 | template<std::size_t N>  | 
| 150 | struct build_number_seq | 
| 151 |    : concat_index_tuple<typename build_number_seq<N/2>::type | 
| 152 |                        ,typename build_number_seq<N - N/2 >::type | 
| 153 |    >::type | 
| 154 | {}; | 
| 155 |  | 
| 156 | template<> struct build_number_seq<0> : index_tuple<>{}; | 
| 157 | template<> struct build_number_seq<1> : index_tuple<0>{}; | 
| 158 |  | 
| 159 | }}}   //namespace boost { namespace container { namespace container_detail { | 
| 160 |  | 
| 161 | #include <boost/container/detail/config_end.hpp> | 
| 162 |  | 
| 163 | #endif   //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP | 
| 164 |  |