File indexing completed on 2025-01-18 09:37:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_EXT_STD_ARRAY_HPP
0011 #define BOOST_HANA_EXT_STD_ARRAY_HPP
0012
0013 #include <boost/hana/bool.hpp>
0014 #include <boost/hana/config.hpp>
0015 #include <boost/hana/detail/algorithm.hpp>
0016 #include <boost/hana/fwd/at.hpp>
0017 #include <boost/hana/fwd/core/tag_of.hpp>
0018 #include <boost/hana/fwd/drop_front.hpp>
0019 #include <boost/hana/fwd/equal.hpp>
0020 #include <boost/hana/fwd/is_empty.hpp>
0021 #include <boost/hana/fwd/length.hpp>
0022 #include <boost/hana/fwd/less.hpp>
0023 #include <boost/hana/integral_constant.hpp>
0024
0025 #include <array>
0026 #include <cstddef>
0027 #include <type_traits>
0028 #include <utility>
0029
0030
0031 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0032 namespace std {
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 template <typename T, std::size_t N>
0064 struct array { };
0065 }
0066 #endif
0067
0068
0069 namespace boost { namespace hana {
0070 namespace ext { namespace std { struct array_tag; }}
0071
0072 template <typename T, std::size_t N>
0073 struct tag_of<std::array<T, N>> {
0074 using type = ext::std::array_tag;
0075 };
0076
0077
0078
0079
0080 template <>
0081 struct length_impl<ext::std::array_tag> {
0082 template <typename Xs>
0083 static constexpr auto apply(Xs const&) {
0084 return hana::size_c<std::tuple_size<Xs>::type::value>;
0085 }
0086 };
0087
0088
0089
0090
0091 template <>
0092 struct at_impl<ext::std::array_tag> {
0093 template <typename Xs, typename N>
0094 static constexpr decltype(auto) apply(Xs&& xs, N const&) {
0095 constexpr std::size_t n = N::value;
0096 return std::get<n>(static_cast<Xs&&>(xs));
0097 }
0098 };
0099
0100 template <>
0101 struct drop_front_impl<ext::std::array_tag> {
0102 template <std::size_t n, typename Xs, std::size_t ...i>
0103 static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
0104 using T = typename std::remove_reference<Xs>::type::value_type;
0105 return std::array<T, sizeof...(i)>{{static_cast<Xs&&>(xs)[n + i]...}};
0106 }
0107
0108 template <typename Xs, typename N>
0109 static constexpr auto apply(Xs&& xs, N const&) {
0110 constexpr std::size_t n = N::value;
0111 constexpr std::size_t len = std::tuple_size<
0112 typename std::remove_cv<
0113 typename std::remove_reference<Xs>::type
0114 >::type
0115 >::value;
0116 return drop_front_helper<n>(static_cast<Xs&&>(xs),
0117 std::make_index_sequence<(n < len ? len - n : 0)>{});
0118 }
0119 };
0120
0121 template <>
0122 struct is_empty_impl<ext::std::array_tag> {
0123 template <typename T, std::size_t N>
0124 static constexpr auto apply(std::array<T, N> const&) {
0125 return hana::bool_c<N == 0>;
0126 }
0127 };
0128
0129
0130
0131
0132 template <>
0133 struct equal_impl<ext::std::array_tag, ext::std::array_tag> {
0134 template <typename T, std::size_t n, typename U>
0135 static constexpr bool apply(std::array<T, n> const& xs, std::array<U, n> const& ys)
0136 { return detail::equal(&xs[0], &xs[0] + n, &ys[0], &ys[0] + n); }
0137
0138 template <typename T, typename U>
0139 static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&)
0140 { return hana::true_c; }
0141
0142 template <typename T, std::size_t n, typename U, std::size_t m>
0143 static constexpr auto apply(std::array<T, n> const&, std::array<U, m> const&)
0144 { return hana::false_c; }
0145 };
0146
0147
0148
0149
0150 template <>
0151 struct less_impl<ext::std::array_tag, ext::std::array_tag> {
0152 template <typename T, std::size_t n, typename U, std::size_t m>
0153 static constexpr auto apply(std::array<T, n> const& xs, std::array<U, m> const& ys) {
0154
0155
0156
0157 if (xs.empty()) {
0158 return !ys.empty();
0159 } else {
0160 if (ys.empty()) {
0161 return false;
0162 } else {
0163 return detail::lexicographical_compare(&xs[0], &xs[0] + n,
0164 &ys[0], &ys[0] + m);
0165 }
0166 }
0167 }
0168 };
0169 }}
0170
0171 #endif