]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/include/boost/hana/ext/std/tuple.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / ext / std / tuple.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Adapts `std::tuple` for use with Hana.
4
5@copyright Louis Dionne 2013-2016
6Distributed 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_EXT_STD_TUPLE_HPP
11#define BOOST_HANA_EXT_STD_TUPLE_HPP
12
13#include <boost/hana/bool.hpp>
14#include <boost/hana/config.hpp>
15#include <boost/hana/detail/decay.hpp>
16#include <boost/hana/fwd/at.hpp>
17#include <boost/hana/fwd/core/make.hpp>
18#include <boost/hana/fwd/core/tag_of.hpp>
19#include <boost/hana/fwd/drop_front.hpp>
20#include <boost/hana/fwd/empty.hpp>
21#include <boost/hana/fwd/flatten.hpp>
22#include <boost/hana/fwd/front.hpp>
23#include <boost/hana/fwd/is_empty.hpp>
24#include <boost/hana/fwd/length.hpp>
25#include <boost/hana/fwd/lift.hpp>
26#include <boost/hana/integral_constant.hpp>
27
28#include <cstddef>
29#include <tuple>
30#include <type_traits>
31#include <utility>
32
33
34#ifdef BOOST_HANA_CONFIG_HAS_NO_STD_TUPLE_ADAPTER
35# error The adapter for std::tuple is not supported with versions of \
36 libc++ prior to the one shipped with Clang 3.7 because of a bug \
37 in the tuple implementation.
38#endif
39
40
41#ifdef BOOST_HANA_DOXYGEN_INVOKED
42namespace std {
43 //! @ingroup group-ext-std
44 //! Adapter for `std::tuple`s.
45 //!
46 //!
47 //! Modeled concepts
48 //! ----------------
49 //! A `std::tuple` is a model of the `Sequence` concept, and all the
50 //! concepts it refines. That makes it essentially the same as a Hana
51 //! tuple, although the complexity of some operations might differ from
52 //! that of Hana's tuple.
53 //!
54 //! @include example/ext/std/tuple.cpp
55 template <typename ...T>
56 struct tuple { };
57}
58#endif
59
60
61BOOST_HANA_NAMESPACE_BEGIN
62 namespace ext { namespace std { struct tuple_tag; }}
63
64 template <typename ...Xs>
65 struct tag_of<std::tuple<Xs...>> {
66 using type = ext::std::tuple_tag;
67 };
68
69 //////////////////////////////////////////////////////////////////////////
70 // make
71 //////////////////////////////////////////////////////////////////////////
72 template <>
73 struct make_impl<ext::std::tuple_tag> {
74 template <typename ...Xs>
75 static constexpr decltype(auto) apply(Xs&& ...xs) {
76 return std::make_tuple(static_cast<Xs&&>(xs)...);
77 }
78 };
79
80 //////////////////////////////////////////////////////////////////////////
81 // Applicative
82 //////////////////////////////////////////////////////////////////////////
83 template <>
84 struct lift_impl<ext::std::tuple_tag> {
85 template <typename X>
86 static constexpr auto apply(X&& x) {
87 return std::tuple<typename detail::decay<X>::type>{
88 static_cast<X&&>(x)};
89 }
90 };
91
92 //////////////////////////////////////////////////////////////////////////
93 // Monad
94 //////////////////////////////////////////////////////////////////////////
95 template <>
96 struct flatten_impl<ext::std::tuple_tag> {
97 template <typename Xs, std::size_t ...i>
98 static constexpr decltype(auto)
99 flatten_helper(Xs&& xs, std::index_sequence<i...>) {
100#if defined(BOOST_HANA_CONFIG_LIBCPP_HAS_BUG_22806)
101 return std::tuple_cat(std::get<i>(xs)...);
102#else
103 return std::tuple_cat(std::get<i>(static_cast<Xs&&>(xs))...);
104#endif
105 }
106
107 template <typename Xs>
108 static constexpr decltype(auto) apply(Xs&& xs) {
109 using Raw = typename std::remove_reference<Xs>::type;
110 constexpr std::size_t Length = std::tuple_size<Raw>::value;
111 return flatten_helper(static_cast<Xs&&>(xs),
112 std::make_index_sequence<Length>{});
113 }
114 };
115
116 //////////////////////////////////////////////////////////////////////////
117 // MonadPlus
118 //////////////////////////////////////////////////////////////////////////
119 template <>
120 struct empty_impl<ext::std::tuple_tag> {
121 static constexpr auto apply()
122 { return std::tuple<>{}; }
123 };
124
125 //////////////////////////////////////////////////////////////////////////
126 // Iterable
127 //////////////////////////////////////////////////////////////////////////
128 template <>
129 struct front_impl<ext::std::tuple_tag> {
130 template <typename Xs>
131 static constexpr decltype(auto) apply(Xs&& xs) {
132 return std::get<0>(static_cast<Xs&&>(xs));
133 }
134 };
135
136 template <>
137 struct drop_front_impl<ext::std::tuple_tag> {
138 template <std::size_t n, typename Xs, std::size_t ...i>
139 static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
140 return std::make_tuple(
141 hana::at_c<n + i>(static_cast<Xs&&>(xs))...
142 );
143 }
144
145 template <typename Xs, typename N>
146 static constexpr auto apply(Xs&& xs, N const&) {
147 using Raw = typename std::remove_reference<Xs>::type;
148 constexpr std::size_t n = N::value;
149 constexpr auto len = std::tuple_size<Raw>::value;
150 return drop_front_helper<n>(static_cast<Xs&&>(xs),
151 std::make_index_sequence<(n < len ? len - n : 0)>{});
152 }
153 };
154
155 template <>
156 struct is_empty_impl<ext::std::tuple_tag> {
157 template <typename ...Xs>
158 static constexpr auto apply(std::tuple<Xs...> const&)
159 { return hana::bool_c<sizeof...(Xs) == 0>; }
160 };
161
162 template <>
163 struct at_impl<ext::std::tuple_tag> {
164 template <typename Xs, typename N>
165 static constexpr decltype(auto) apply(Xs&& xs, N const&) {
166 constexpr std::size_t index = N::value;
167 return std::get<index>(static_cast<Xs&&>(xs));
168 }
169 };
170
171 //////////////////////////////////////////////////////////////////////////
172 // Foldable
173 //////////////////////////////////////////////////////////////////////////
174 template <>
175 struct length_impl<ext::std::tuple_tag> {
176 template <typename ...Xs>
177 static constexpr auto apply(std::tuple<Xs...> const&) {
178 return hana::size_c<sizeof...(Xs)>;
179 }
180 };
181
182 //////////////////////////////////////////////////////////////////////////
183 // Sequence
184 //////////////////////////////////////////////////////////////////////////
185 template <>
186 struct Sequence<ext::std::tuple_tag> {
187 static constexpr bool value = true;
188 };
189BOOST_HANA_NAMESPACE_END
190
191#endif // !BOOST_HANA_EXT_STD_TUPLE_HPP