]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/hana/ext/boost/mpl/list.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / hana / ext / boost / mpl / list.hpp
1 /*!
2 @file
3 Adapts `boost::mpl::list` for use with Hana.
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_EXT_BOOST_MPL_LIST_HPP
11 #define BOOST_HANA_EXT_BOOST_MPL_LIST_HPP
12
13 #include <boost/hana/concept/foldable.hpp>
14 #include <boost/hana/config.hpp>
15 #include <boost/hana/core/when.hpp>
16 #include <boost/hana/ext/boost/mpl/integral_c.hpp>
17 #include <boost/hana/fwd/at.hpp>
18 #include <boost/hana/fwd/core/to.hpp>
19 #include <boost/hana/fwd/core/tag_of.hpp>
20 #include <boost/hana/fwd/drop_front.hpp>
21 #include <boost/hana/fwd/equal.hpp>
22 #include <boost/hana/fwd/is_empty.hpp>
23 #include <boost/hana/fwd/less.hpp>
24 #include <boost/hana/integral_constant.hpp>
25 #include <boost/hana/length.hpp>
26 #include <boost/hana/type.hpp>
27 #include <boost/hana/unpack.hpp>
28
29 #include <boost/mpl/at.hpp>
30 #include <boost/mpl/empty.hpp>
31 #include <boost/mpl/equal.hpp>
32 #include <boost/mpl/list.hpp>
33 #include <boost/mpl/sequence_tag.hpp>
34 #include <boost/mpl/size.hpp>
35
36 #include <cstddef>
37 #include <type_traits>
38 #include <utility>
39
40
41 #ifdef BOOST_HANA_DOXYGEN_INVOKED
42 namespace boost { namespace mpl {
43 //! @ingroup group-ext-mpl
44 //! Adapter for Boost.MPL lists.
45 //!
46 //!
47 //! Modeled concepts
48 //! ----------------
49 //! It is possible for MPL lists to model a couple of concepts.
50 //! However, because they are only able to hold types, they lack
51 //! the generality required to model concepts like `Functor`,
52 //! `Sequence` and other related concepts.
53 //!
54 //! 1. `Comparable`\n
55 //! Two MPL lists are equal if and only if they contain the same
56 //! number of types, and if all those types are equal.
57 //! @include example/ext/boost/mpl/list/comparable.cpp
58 //!
59 //! 2. `Foldable`\n
60 //! Folding a MPL list is equivalent to folding it as a `Sequence`.
61 //! @include example/ext/boost/mpl/list/foldable.cpp
62 //!
63 //! 3. `Iterable`\n
64 //! Iterating over a MPL list is just iterating over each of the
65 //! types it contains, as if it were a `Sequence`.
66 //! @include example/ext/boost/mpl/list/iterable.cpp
67 //!
68 //! 4. `Searchable`\n
69 //! A MPL list can be searched as if it were a tuple containing
70 //! `hana::type`s.
71 //! @include example/ext/boost/mpl/list/searchable.cpp
72 //!
73 //!
74 //! Conversion from any `Foldable`
75 //! ------------------------------
76 //! A MPL list can be created from any `Foldable`. More precisely,
77 //! for a `Foldable` `xs` whose linearization is `[x1, ..., xn]`,
78 //! @code
79 //! to<ext::boost::mpl::list_tag>(xs) == mpl::list<t1, ..., tn>{}
80 //! @endcode
81 //! where `tk` is the type of `xk`, or the type contained in `xk` if
82 //! `xk` is a `hana::type`.
83 //! @warning
84 //! The limitations on the size of `mpl::list`s are inherited by
85 //! this conversion utility, and hence trying to convert a `Foldable`
86 //! containing more than [BOOST_MPL_LIMIT_LIST_SIZE][1] elements is
87 //! an error.
88 //! @include example/ext/boost/mpl/list/conversion.cpp
89 //!
90 //! [1]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/limit-list-size.html
91 template <typename ...T>
92 struct list { };
93 }}
94 #endif
95
96
97 BOOST_HANA_NAMESPACE_BEGIN
98 namespace ext { namespace boost { namespace mpl {
99 using list_tag = ::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type;
100 }}}
101
102 template <typename T>
103 struct tag_of<T, when<
104 std::is_same<
105 typename ::boost::mpl::sequence_tag<T>::type,
106 ::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type
107 >::value
108 >> {
109 using type = ext::boost::mpl::list_tag;
110 };
111
112 //////////////////////////////////////////////////////////////////////////
113 // Comparable
114 //////////////////////////////////////////////////////////////////////////
115 template <>
116 struct equal_impl<ext::boost::mpl::list_tag, ext::boost::mpl::list_tag> {
117 template <typename Xs, typename Ys>
118 static constexpr auto apply(Xs const&, Ys const&) {
119 return typename ::boost::mpl::equal<Xs, Ys>::type{};
120 }
121 };
122
123 //////////////////////////////////////////////////////////////////////////
124 // Foldable
125 //////////////////////////////////////////////////////////////////////////
126 template <>
127 struct length_impl<ext::boost::mpl::list_tag> {
128 template <typename Xs>
129 static constexpr auto apply(Xs const&) {
130 return hana::size_c< ::boost::mpl::size<Xs>::type::value>;
131 }
132 };
133
134 //////////////////////////////////////////////////////////////////////////
135 // Iterable
136 //////////////////////////////////////////////////////////////////////////
137 template <>
138 struct at_impl<ext::boost::mpl::list_tag> {
139 template <typename Ts, typename N>
140 static constexpr auto apply(Ts const&, N const&) {
141 constexpr std::size_t n = N::value;
142 using T = typename ::boost::mpl::at_c<Ts, n>::type;
143 return hana::type_c<T>;
144 }
145 };
146
147 template <>
148 struct drop_front_impl<ext::boost::mpl::list_tag> {
149 template <std::size_t n, typename Xs, std::size_t ...i>
150 static constexpr auto drop_front_helper(Xs const&, std::index_sequence<i...>) {
151 return boost::mpl::list<
152 typename boost::mpl::at_c<Xs, n + i>::type...
153 >{};
154 }
155
156 template <typename Xs, typename N>
157 static constexpr auto apply(Xs const& xs, N const&) {
158 constexpr std::size_t n = N::value;
159 constexpr std::size_t len = decltype(hana::length(xs))::value;
160 return drop_front_helper<n>(xs,
161 std::make_index_sequence<(n < len ? len - n : 0)>{});
162 }
163 };
164
165 template <>
166 struct is_empty_impl<ext::boost::mpl::list_tag> {
167 template <typename Xs>
168 static constexpr auto apply(Xs const&)
169 { return typename ::boost::mpl::empty<Xs>::type{}; }
170 };
171
172 //////////////////////////////////////////////////////////////////////////
173 // Conversion from a Foldable
174 //////////////////////////////////////////////////////////////////////////
175 template <typename F>
176 struct to_impl<ext::boost::mpl::list_tag, F, when<hana::Foldable<F>::value>> {
177 template <typename Xs>
178 static constexpr decltype(auto) apply(Xs&& xs) {
179 auto list_type = hana::unpack(static_cast<Xs&&>(xs),
180 hana::template_<::boost::mpl::list>);
181 return typename decltype(list_type)::type{};
182 }
183 };
184 BOOST_HANA_NAMESPACE_END
185
186 #endif // !BOOST_HANA_EXT_BOOST_MPL_LIST_HPP