1 /*! 2 @file 3 Forward declares `boost::hana::tuple`. 4 5 @copyright Louis Dionne 2013-2017 6 Distributed under the Boost Software License, Version 1.0. 7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 8 */ 9 10 #ifndef BOOST_HANA_FWD_TUPLE_HPP 11 #define BOOST_HANA_FWD_TUPLE_HPP 12 13 #include <boost/hana/config.hpp> 14 #include <boost/hana/fwd/core/make.hpp> 15 #include <boost/hana/fwd/core/to.hpp> 16 #include <boost/hana/fwd/integral_constant.hpp> 17 #include <boost/hana/fwd/type.hpp> 18 19 20 BOOST_HANA_NAMESPACE_BEGIN 21 //! @ingroup group-datatypes 22 //! General purpose index-based heterogeneous sequence with a fixed length. 23 //! 24 //! The tuple is the bread and butter for static metaprogramming. 25 //! Conceptually, it is like a `std::tuple`; it is a container able 26 //! of holding objects of different types and whose size is fixed at 27 //! compile-time. However, Hana's tuple provides much more functionality 28 //! than its `std` counterpart, and it is also much more efficient than 29 //! all standard library implementations tested so far. 30 //! 31 //! Tuples are index-based sequences. If you need an associative 32 //! sequence with a key-based access, then you should consider 33 //! `hana::map` or `hana::set` instead. 34 //! 35 //! @note 36 //! When you use a container, remember not to make assumptions about its 37 //! representation, unless the documentation gives you those guarantees. 38 //! More details [in the tutorial](@ref tutorial-containers-types). 39 //! 40 //! 41 //! Modeled concepts 42 //! ---------------- 43 //! `Sequence`, and all the concepts it refines 44 //! 45 //! 46 //! Provided operators 47 //! ------------------ 48 //! For convenience, the following operators are provided: 49 //! @code 50 //! xs == ys -> equal(xs, ys) 51 //! xs != ys -> not_equal(xs, ys) 52 //! 53 //! xs < ys -> less(xs, ys) 54 //! xs <= ys -> less_equal(xs, ys) 55 //! xs > ys -> greater(xs, ys) 56 //! xs >= ys -> greater_equal(xs, ys) 57 //! 58 //! xs | f -> chain(xs, f) 59 //! 60 //! xs[n] -> at(xs, n) 61 //! @endcode 62 //! 63 //! 64 //! Example 65 //! ------- 66 //! @include example/tuple/tuple.cpp 67 #ifdef BOOST_HANA_DOXYGEN_INVOKED 68 template <typename ...Xn> 69 struct tuple { 70 //! Default constructs the `tuple`. Only exists when all the elements 71 //! of the tuple are default constructible. 72 constexpr tuple(); 73 74 //! Initialize each element of the tuple with the corresponding element 75 //! from `xn...`. Only exists when all the elements of the tuple are 76 //! copy-constructible. 77 //! 78 //! @note 79 //! Unlike the corresponding constructor for `std::tuple`, this 80 //! constructor is not explicit. This allows returning a tuple 81 //! from a function with the brace-initialization syntax. 82 constexpr tuple(Xn const& ...xn); 83 84 //! Initialize each element of the tuple by perfect-forwarding the 85 //! corresponding element in `yn...`. Only exists when all the 86 //! elements of the created tuple are constructible from the 87 //! corresponding perfect-forwarded value. 88 //! 89 //! @note 90 //! Unlike the corresponding constructor for `std::tuple`, this 91 //! constructor is not explicit. This allows returning a tuple 92 //! from a function with the brace-initialization syntax. 93 template <typename ...Yn> 94 constexpr tuple(Yn&& ...yn); 95 96 //! Copy-initialize a tuple from another tuple. Only exists when all 97 //! the elements of the constructed tuple are copy-constructible from 98 //! the corresponding element in the source tuple. 99 template <typename ...Yn> 100 constexpr tuple(tuple<Yn...> const& other); 101 102 //! Move-initialize a tuple from another tuple. Only exists when all 103 //! the elements of the constructed tuple are move-constructible from 104 //! the corresponding element in the source tuple. 105 template <typename ...Yn> 106 constexpr tuple(tuple<Yn...>&& other); 107 108 //! Assign a tuple to another tuple. Only exists when all the elements 109 //! of the destination tuple are assignable from the corresponding 110 //! element in the source tuple. 111 template <typename ...Yn> 112 constexpr tuple& operator=(tuple<Yn...> const& other); 113 114 //! Move-assign a tuple to another tuple. Only exists when all the 115 //! elements of the destination tuple are move-assignable from the 116 //! corresponding element in the source tuple. 117 template <typename ...Yn> 118 constexpr tuple& operator=(tuple<Yn...>&& other); 119 120 //! Equivalent to `hana::chain`. 121 template <typename ...T, typename F> 122 friend constexpr auto operator|(tuple<T...>, F); 123 124 //! Equivalent to `hana::equal` 125 template <typename X, typename Y> 126 friend constexpr auto operator==(X&& x, Y&& y); 127 128 //! Equivalent to `hana::not_equal` 129 template <typename X, typename Y> 130 friend constexpr auto operator!=(X&& x, Y&& y); 131 132 //! Equivalent to `hana::less` 133 template <typename X, typename Y> 134 friend constexpr auto operator<(X&& x, Y&& y); 135 136 //! Equivalent to `hana::greater` 137 template <typename X, typename Y> 138 friend constexpr auto operator>(X&& x, Y&& y); 139 140 //! Equivalent to `hana::less_equal` 141 template <typename X, typename Y> 142 friend constexpr auto operator<=(X&& x, Y&& y); 143 144 //! Equivalent to `hana::greater_equal` 145 template <typename X, typename Y> 146 friend constexpr auto operator>=(X&& x, Y&& y); 147 148 //! Equivalent to `hana::at` 149 template <typename N> 150 constexpr decltype(auto) operator[](N&& n); 151 }; 152 #else 153 template <typename ...Xn> 154 struct tuple; 155 #endif 156 157 //! Tag representing `hana::tuple`s. 158 //! @related tuple 159 struct tuple_tag { }; 160 161 #ifdef BOOST_HANA_DOXYGEN_INVOKED 162 //! Function object for creating a `tuple`. 163 //! @relates hana::tuple 164 //! 165 //! Given zero or more objects `xs...`, `make<tuple_tag>` returns a new tuple 166 //! containing those objects. The elements are held by value inside the 167 //! resulting tuple, and they are hence copied or moved in. This is 168 //! analogous to `std::make_tuple` for creating Hana tuples. 169 //! 170 //! 171 //! Example 172 //! ------- 173 //! @include example/tuple/make.cpp 174 template <> __anon521d12060102(auto&& ...xs) 175 constexpr auto make<tuple_tag> = [](auto&& ...xs) { 176 return tuple<std::decay_t<decltype(xs)>...>{forwarded(xs)...}; 177 }; 178 #endif 179 180 //! Alias to `make<tuple_tag>`; provided for convenience. 181 //! @relates hana::tuple 182 constexpr auto make_tuple = make<tuple_tag>; 183 184 //! Equivalent to `to<tuple_tag>`; provided for convenience. 185 //! @relates hana::tuple 186 constexpr auto to_tuple = to<tuple_tag>; 187 188 //! Create a tuple specialized for holding `hana::type`s. 189 //! @relates hana::tuple 190 //! 191 //! This is functionally equivalent to `make<tuple_tag>(type_c<T>...)`, except 192 //! that using `tuple_t` allows the library to perform some compile-time 193 //! optimizations. Also note that the type of the objects returned by 194 //! `tuple_t` and an equivalent call to `make<tuple_tag>` may differ. 195 //! 196 //! 197 //! Example 198 //! ------- 199 //! @include example/tuple/tuple_t.cpp 200 #ifdef BOOST_HANA_DOXYGEN_INVOKED 201 template <typename ...T> 202 constexpr implementation_defined tuple_t{}; 203 #else 204 template <typename ...T> 205 constexpr hana::tuple<hana::type<T>...> tuple_t{}; 206 #endif 207 208 //! Create a tuple specialized for holding `hana::integral_constant`s. 209 //! @relates hana::tuple 210 //! 211 //! This is functionally equivalent to `make<tuple_tag>(integral_c<T, v>...)`, 212 //! except that using `tuple_c` allows the library to perform some 213 //! compile-time optimizations. Also note that the type of the objects 214 //! returned by `tuple_c` and an equivalent call to `make<tuple_tag>` may differ. 215 //! 216 //! 217 //! Example 218 //! ------- 219 //! @include example/tuple/tuple_c.cpp 220 #ifdef BOOST_HANA_DOXYGEN_INVOKED 221 template <typename T, T ...v> 222 constexpr implementation_defined tuple_c{}; 223 #else 224 template <typename T, T ...v> 225 constexpr hana::tuple<hana::integral_constant<T, v>...> tuple_c{}; 226 #endif 227 BOOST_HANA_NAMESPACE_END 228 229 #endif // !BOOST_HANA_FWD_TUPLE_HPP 230