Tatooine
multidim.h
Go to the documentation of this file.
1#ifndef TATOOINE_MULTIDIM_H
2#define TATOOINE_MULTIDIM_H
3//==============================================================================
5#include <tatooine/utility.h>
6
7#include <cassert>
8//==============================================================================
9namespace tatooine {
10//==============================================================================
12 private:
13 std::vector<std::pair<std::size_t, std::size_t>> m_ranges;
14 struct iterator {
15 //--------------------------------------------------------------------------
17 std::vector<std::size_t> m_status;
18 //--------------------------------------------------------------------------
19 iterator(dynamic_multidim const& c, std::vector<std::size_t> status)
20 : m_cont{&c}, m_status{std::move(status)} {}
21 //--------------------------------------------------------------------------
22 iterator(iterator const& other) = default;
23 iterator(iterator&& other) = default;
24 //--------------------------------------------------------------------------
25 auto operator=(iterator const& other) -> iterator& = default;
26 auto operator=(iterator&& other) -> iterator& = default;
27 //--------------------------------------------------------------------------
28 ~iterator() = default;
29 //--------------------------------------------------------------------------
30 void operator++() {
31 ++m_status.front();
32 auto range_it = m_cont->ranges().begin();
33 auto status_it = m_status.begin();
34 for (; range_it != prev(m_cont->ranges().end());
35 ++status_it, ++range_it) {
36 if (range_it->second <= *status_it) {
37 *status_it = 0;
38 ++(*(status_it + 1));
39 }
40 }
41 }
42 //--------------------------------------------------------------------------
43 auto operator==(iterator const& other) const {
44 if (m_cont != other.m_cont) {
45 return false;
46 }
47 for (std::size_t i = 0; i < m_cont->num_dimensions(); ++i) {
48 if (m_status[i] != other.m_status[i]) {
49 return false;
50 }
51 }
52 return true;
53 }
54 //--------------------------------------------------------------------------
55 auto operator!=(iterator const& other) const { return !operator==(other); }
56 //--------------------------------------------------------------------------
57 auto operator*() const -> auto const& { return m_status; }
58 };
59
60 public:
61 //----------------------------------------------------------------------------
63 std::vector<std::pair<std::size_t, std::size_t>> ranges)
64 : m_ranges(std::move(ranges)) {}
65 //----------------------------------------------------------------------------
67 std::vector<std::pair<std::size_t, std::size_t>>&& ranges)
68 : m_ranges(std::move(ranges)) {}
69 //----------------------------------------------------------------------------
70 explicit dynamic_multidim(std::vector<std::size_t> const& res)
71 : m_ranges(res.size(), std::make_pair<std::size_t, std::size_t>(0, 0)) {
72 for (std::size_t i = 0; i < res.size(); ++i) {
73 m_ranges[i].second = res[i];
74 }
75 }
76 //----------------------------------------------------------------------------
77 template <std::size_t N>
79 std::array<std::pair<std::size_t, std::size_t>, N> const& ranges)
80 : m_ranges(ranges.begin(), ranges.end()) {}
81 //----------------------------------------------------------------------------
82 template <std::size_t N>
83 explicit constexpr dynamic_multidim(std::array<std::size_t, N> const& res)
84 : m_ranges(N, std::make_pair<std::size_t, std::size_t>(0, 0)) {
85 for (std::size_t i = 0; i < N; ++i) {
86 m_ranges[i].second = res[i];
87 }
88 }
89 //----------------------------------------------------------------------------
90 template <integral... Ts>
91 explicit constexpr dynamic_multidim(std::pair<Ts, Ts> const&... ranges)
92 : m_ranges{std::make_pair(static_cast<std::size_t>(ranges.first),
93 static_cast<std::size_t>(ranges.second))...} {}
94
95 //----------------------------------------------------------------------------
96 template <integral... Ts>
97 constexpr dynamic_multidim(Ts const (&... ranges)[2]) // NOLINT
98 : m_ranges{std::make_pair(static_cast<std::size_t>(ranges[0]),
99 static_cast<std::size_t>(ranges[1]))...} {}
100
101 //----------------------------------------------------------------------------
102 explicit constexpr dynamic_multidim(integral auto const... res)
103 : m_ranges{std::make_pair(static_cast<std::size_t>(0),
104 static_cast<std::size_t>(res))...} {}
105
106 //----------------------------------------------------------------------------
107 auto operator[](std::size_t i) -> auto& { return m_ranges[i]; }
108 auto operator[](std::size_t i) const -> auto const& { return m_ranges[i]; }
109
110 //----------------------------------------------------------------------------
111 [[nodiscard]] auto ranges()
112 -> std::vector<std::pair<std::size_t, std::size_t>>& {
113 return m_ranges;
114 }
115 [[nodiscard]] auto ranges() const
116 -> std::vector<std::pair<std::size_t, std::size_t>> const& {
117 return m_ranges;
118 }
119 //----------------------------------------------------------------------------
120 auto begin() {
121 return iterator{*this, std::vector<std::size_t>(m_ranges.size(), 0)};
122 }
123 //----------------------------------------------------------------------------
124 auto end() {
125 std::vector<std::size_t> v(m_ranges.size());
126 v.back() = m_ranges.back().second;
127 return iterator{*this, std::move(v)};
128 }
129 //----------------------------------------------------------------------------
130 [[nodiscard]] auto num_dimensions() const -> std::size_t {
131 return m_ranges.size();
132 }
133};
134//==============================================================================
135} // namespace tatooine
136//==============================================================================
137#endif
Definition: concepts.h:21
Definition: algorithm.h:6
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto prev(Iter iter)
Definition: iterator_facade.h:343
Definition: multidim.h:14
void operator++()
Definition: multidim.h:30
iterator(dynamic_multidim const &c, std::vector< std::size_t > status)
Definition: multidim.h:19
iterator(iterator const &other)=default
auto operator*() const -> auto const &
Definition: multidim.h:57
auto operator==(iterator const &other) const
Definition: multidim.h:43
iterator(iterator &&other)=default
std::vector< std::size_t > m_status
Definition: multidim.h:17
dynamic_multidim const * m_cont
Definition: multidim.h:16
auto operator=(iterator const &other) -> iterator &=default
auto operator!=(iterator const &other) const
Definition: multidim.h:55
auto operator=(iterator &&other) -> iterator &=default
Definition: multidim.h:11
auto ranges() -> std::vector< std::pair< std::size_t, std::size_t > > &
Definition: multidim.h:111
auto end()
Definition: multidim.h:124
auto operator[](std::size_t i) const -> auto const &
Definition: multidim.h:108
constexpr dynamic_multidim(std::pair< Ts, Ts > const &... ranges)
Definition: multidim.h:91
dynamic_multidim(std::vector< std::pair< std::size_t, std::size_t > > ranges)
Definition: multidim.h:62
auto num_dimensions() const -> std::size_t
Definition: multidim.h:130
std::vector< std::pair< std::size_t, std::size_t > > m_ranges
Definition: multidim.h:13
auto ranges() const -> std::vector< std::pair< std::size_t, std::size_t > > const &
Definition: multidim.h:115
constexpr dynamic_multidim(Ts const (&... ranges)[2])
Definition: multidim.h:97
constexpr dynamic_multidim(std::array< std::size_t, N > const &res)
Definition: multidim.h:83
constexpr dynamic_multidim(integral auto const ... res)
Definition: multidim.h:102
dynamic_multidim(std::array< std::pair< std::size_t, std::size_t >, N > const &ranges)
Definition: multidim.h:78
dynamic_multidim(std::vector< std::pair< std::size_t, std::size_t > > &&ranges)
Definition: multidim.h:66
auto begin()
Definition: multidim.h:120
auto operator[](std::size_t i) -> auto &
Definition: multidim.h:107
dynamic_multidim(std::vector< std::size_t > const &res)
Definition: multidim.h:70