tuple.hpp 8.1 KB

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