]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/ext/std/array.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / ext / std / array.hpp
1 /*!
2 @file
3 Adapts `std::array` for use with Hana.
4
5 @copyright Louis Dionne 2013-2016
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_STD_ARRAY_HPP
11 #define BOOST_HANA_EXT_STD_ARRAY_HPP
12
13 #include <boost/hana/bool.hpp>
14 #include <boost/hana/config.hpp>
15 #include <boost/hana/detail/algorithm.hpp>
16 #include <boost/hana/fwd/at.hpp>
17 #include <boost/hana/fwd/core/tag_of.hpp>
18 #include <boost/hana/fwd/drop_front.hpp>
19 #include <boost/hana/fwd/equal.hpp>
20 #include <boost/hana/fwd/is_empty.hpp>
21 #include <boost/hana/fwd/length.hpp>
22 #include <boost/hana/fwd/less.hpp>
23 #include <boost/hana/integral_constant.hpp>
24
25 #include <array>
26 #include <cstddef>
27 #include <type_traits>
28 #include <utility>
29
30
31 #ifdef BOOST_HANA_DOXYGEN_INVOKED
32 namespace std {
33 //! @ingroup group-ext-std
34 //! Adaptation of `std::array` for Hana.
35 //!
36 //!
37 //!
38 //! Modeled concepts
39 //! ----------------
40 //! 1. `Comparable`\n
41 //! `std::array`s are compared as per `std::equal`, except that two arrays
42 //! with different sizes compare unequal instead of triggering an error
43 //! and the result of the comparison is `constexpr` if both arrays are
44 //! `constexpr`.
45 //! @include example/ext/std/array/comparable.cpp
46 //!
47 //! 2. `Orderable`\n
48 //! `std::array`s are ordered with the usual lexicographical ordering,
49 //! except that two arrays with different size can be ordered instead
50 //! of triggering an error and the result of the comparison is `constexpr`
51 //! if both arrays are `constexpr`.
52 //! @include example/ext/std/array/orderable.cpp
53 //!
54 //! 3. `Foldable`\n
55 //! Folding an array from the left is equivalent to calling
56 //! `std::accumulate` on it, except it can be `constexpr`.
57 //! @include example/ext/std/array/foldable.cpp
58 //!
59 //! 4. `Iterable`\n
60 //! Iterating over a `std::array` is equivalent to iterating over it with
61 //! a normal `for` loop.
62 //! @include example/ext/std/array/iterable.cpp
63 template <typename T, std::size_t N>
64 struct array { };
65 }
66 #endif
67
68
69 BOOST_HANA_NAMESPACE_BEGIN
70 namespace ext { namespace std { struct array_tag; }}
71
72 template <typename T, std::size_t N>
73 struct tag_of<std::array<T, N>> {
74 using type = ext::std::array_tag;
75 };
76
77 //////////////////////////////////////////////////////////////////////////
78 // Foldable
79 //////////////////////////////////////////////////////////////////////////
80 template <>
81 struct length_impl<ext::std::array_tag> {
82 template <typename Xs>
83 static constexpr auto apply(Xs const&) {
84 return hana::size_c<std::tuple_size<Xs>::type::value>;
85 }
86 };
87
88 //////////////////////////////////////////////////////////////////////////
89 // Iterable
90 //////////////////////////////////////////////////////////////////////////
91 template <>
92 struct at_impl<ext::std::array_tag> {
93 template <typename Xs, typename N>
94 static constexpr decltype(auto) apply(Xs&& xs, N const&) {
95 constexpr std::size_t n = N::value;
96 return std::get<n>(static_cast<Xs&&>(xs));
97 }
98 };
99
100 template <>
101 struct drop_front_impl<ext::std::array_tag> {
102 template <std::size_t n, typename Xs, std::size_t ...i>
103 static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
104 using T = typename std::remove_reference<Xs>::type::value_type;
105 return std::array<T, sizeof...(i)>{{static_cast<Xs&&>(xs)[n + i]...}};
106 }
107
108 template <typename Xs, typename N>
109 static constexpr auto apply(Xs&& xs, N const&) {
110 constexpr std::size_t n = N::value;
111 constexpr std::size_t len = std::tuple_size<
112 typename std::remove_cv<
113 typename std::remove_reference<Xs>::type
114 >::type
115 >::value;
116 return drop_front_helper<n>(static_cast<Xs&&>(xs),
117 std::make_index_sequence<(n < len ? len - n : 0)>{});
118 }
119 };
120
121 template <>
122 struct is_empty_impl<ext::std::array_tag> {
123 template <typename T, std::size_t N>
124 static constexpr auto apply(std::array<T, N> const&) {
125 return hana::bool_c<N == 0>;
126 }
127 };
128
129 //////////////////////////////////////////////////////////////////////////
130 // Comparable
131 //////////////////////////////////////////////////////////////////////////
132 template <>
133 struct equal_impl<ext::std::array_tag, ext::std::array_tag> {
134 template <typename T, std::size_t n, typename U>
135 static constexpr bool apply(std::array<T, n> const& xs, std::array<U, n> const& ys)
136 { return detail::equal(&xs[0], &xs[0] + n, &ys[0], &ys[0] + n); }
137
138 template <typename T, typename U>
139 static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&)
140 { return hana::true_c; }
141
142 template <typename T, std::size_t n, typename U, std::size_t m>
143 static constexpr auto apply(std::array<T, n> const&, std::array<U, m> const&)
144 { return hana::false_c; }
145 };
146
147 //////////////////////////////////////////////////////////////////////////
148 // Orderable
149 //////////////////////////////////////////////////////////////////////////
150 template <>
151 struct less_impl<ext::std::array_tag, ext::std::array_tag> {
152 template <typename T, typename U>
153 static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&)
154 { return hana::false_c; }
155
156 template <typename T, std::size_t n, typename U, std::size_t m>
157 static constexpr auto apply(std::array<T, n> const& xs, std::array<U, m> const& ys) {
158 return detail::lexicographical_compare(&xs[0], &xs[0] + n, &ys[0], &ys[0] + m);
159 }
160 };
161 BOOST_HANA_NAMESPACE_END
162
163 #endif // !BOOST_HANA_EXT_STD_ARRAY_HPP