]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*! |
2 | @file | |
3 | Forward declares `boost::hana::tuple`. | |
4 | ||
b32b8144 | 5 | @copyright Louis Dionne 2013-2017 |
7c673cae FG |
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 | //! | |
92f5a8d4 TL |
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 | //! | |
7c673cae FG |
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 <> | |
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 |