]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*! |
2 | @file | |
3 | Defines `boost::hana::detail::array`. | |
4 | ||
b32b8144 | 5 | @copyright Louis Dionne 2013-2017 |
7c673cae FG |
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_DETAIL_ARRAY_HPP | |
11 | #define BOOST_HANA_DETAIL_ARRAY_HPP | |
12 | ||
13 | #include <boost/hana/config.hpp> | |
14 | #include <boost/hana/detail/algorithm.hpp> | |
15 | #include <boost/hana/functional/placeholder.hpp> | |
16 | ||
17 | #include <cstddef> | |
18 | ||
19 | ||
1e59de90 | 20 | namespace boost { namespace hana { namespace detail { |
7c673cae FG |
21 | template <typename N> |
22 | constexpr N factorial(N n) { | |
23 | N result = 1; | |
24 | while (n != 0) | |
25 | result *= n--; | |
26 | return result; | |
27 | } | |
28 | ||
29 | //! @ingroup group-details | |
30 | //! A minimal `std::array` with better `constexpr` support. | |
31 | //! | |
32 | //! We also provide some algorithms from the `constexpr/algorithm.hpp` | |
33 | //! header as member functions to make them easier to use in constexpr | |
34 | //! contexts, since a `constexpr` `array` can't be mutated in place. | |
35 | template <typename T, std::size_t Size> | |
36 | struct array { | |
37 | T elems_[Size > 0 ? Size : 1]; | |
38 | ||
39 | constexpr T& operator[](std::size_t n) | |
40 | { return elems_[n]; } | |
41 | ||
42 | constexpr T const& operator[](std::size_t n) const | |
43 | { return elems_[n]; } | |
44 | ||
45 | constexpr std::size_t size() const noexcept | |
46 | { return Size; } | |
47 | ||
48 | constexpr T* begin() noexcept { return elems_; } | |
49 | constexpr T const* begin() const noexcept { return elems_; } | |
50 | constexpr T* end() noexcept { return elems_ + Size; } | |
51 | constexpr T const* end() const noexcept { return elems_ + Size; } | |
52 | ||
53 | // Algorithms from constexpr/algorithm.hpp | |
54 | constexpr array reverse() const { | |
55 | array result = *this; | |
56 | detail::reverse(result.begin(), result.end()); | |
57 | return result; | |
58 | } | |
59 | ||
60 | template <typename BinaryPred> | |
61 | constexpr auto permutations(BinaryPred pred) const { | |
62 | array<array<T, Size>, detail::factorial(Size)> result{}; | |
63 | auto out = result.begin(); | |
64 | array copy = *this; | |
65 | ||
66 | do *out++ = copy; | |
67 | while (detail::next_permutation(copy.begin(), copy.end(), pred)); | |
68 | ||
69 | return result; | |
70 | } | |
71 | ||
72 | constexpr auto permutations() const | |
73 | { return this->permutations(hana::_ < hana::_); } | |
74 | ||
75 | ||
76 | template <typename BinaryPred> | |
77 | constexpr auto sort(BinaryPred pred) const { | |
78 | array result = *this; | |
79 | detail::sort(result.begin(), result.end(), pred); | |
80 | return result; | |
81 | } | |
82 | ||
83 | constexpr auto sort() const | |
84 | { return this->sort(hana::_ < hana::_); } | |
85 | ||
86 | template <typename U> | |
87 | constexpr auto iota(U value) const { | |
88 | array result = *this; | |
89 | detail::iota(result.begin(), result.end(), value); | |
90 | return result; | |
91 | } | |
92 | }; | |
93 | ||
94 | template <typename T, std::size_t M, typename U, std::size_t N> | |
95 | constexpr bool operator==(array<T, M> a, array<U, N> b) | |
96 | { return M == N && detail::equal(a.begin(), a.end(), b.begin(), b.end()); } | |
97 | ||
98 | template <typename T, std::size_t M, typename U, std::size_t N> | |
99 | constexpr bool operator<(array<T, M> a, array<U, N> b) { | |
100 | return M < N || detail::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); | |
101 | } | |
102 | ||
1e59de90 | 103 | } }} // end namespace boost::hana |
7c673cae FG |
104 | |
105 | #endif // !BOOST_HANA_DETAIL_ARRAY_HPP |