openMSX
ranges.hh
Go to the documentation of this file.
1 #ifndef RANGES_HH
2 #define RANGES_HH
3 
4 #include <algorithm>
5 #include <iterator> // for std::begin(), std::end()
6 #include <numeric>
7 
8 // Range based versions of the standard algorithms, these will likely become
9 // part of c++20. For example see this post:
10 // http://ericniebler.com/2018/12/05/standard-ranges/
11 // In the future we can remove our implementation and instead use the standard
12 // version (e.g. by a namespace alias like 'namespace ranges = std::ranges').
13 //
14 // All of the range algorithms below do nothing more than delegate to the
15 // corresponding iterator-pair version of the algorithm.
16 //
17 // This list of algorithms is not complete. But it's easy to extend if/when we
18 // need more.
19 
20 namespace ranges {
21 
22 template<typename ForwardRange>
23 [[nodiscard]] bool is_sorted(ForwardRange&& range)
24 {
25  return std::is_sorted(std::begin(range), std::end(range));
26 }
27 
28 template<typename ForwardRange, typename Compare>
29 [[nodiscard]] bool is_sorted(ForwardRange&& range, Compare comp)
30 {
31  return std::is_sorted(std::begin(range), std::end(range), comp);
32 }
33 
34 template<typename RandomAccessRange>
35 void sort(RandomAccessRange&& range)
36 {
37  std::sort(std::begin(range), std::end(range));
38 }
39 
40 template<typename RandomAccessRange, typename Compare>
41 void sort(RandomAccessRange&& range, Compare comp)
42 {
43  std::sort(std::begin(range), std::end(range), comp);
44 }
45 
46 template<typename RandomAccessRange>
47 void stable_sort(RandomAccessRange&& range)
48 {
49  std::stable_sort(std::begin(range), std::end(range));
50 }
51 
52 template<typename RandomAccessRange, typename Compare>
53 void stable_sort(RandomAccessRange&& range, Compare comp)
54 {
55  std::stable_sort(std::begin(range), std::end(range), comp);
56 }
57 
58 template<typename ForwardRange, typename T>
59 [[nodiscard]] bool binary_search(ForwardRange&& range, const T& value)
60 {
61  return std::binary_search(std::begin(range), std::end(range), value);
62 }
63 
64 template<typename ForwardRange, typename T, typename Compare>
65 [[nodiscard]] bool binary_search(ForwardRange&& range, const T& value, Compare comp)
66 {
67  return std::binary_search(std::begin(range), std::end(range), value, comp);
68 }
69 
70 template<typename ForwardRange, typename T>
71 [[nodiscard]] auto lower_bound(ForwardRange&& range, const T& value)
72 {
73  return std::lower_bound(std::begin(range), std::end(range), value);
74 }
75 
76 template<typename ForwardRange, typename T, typename Compare>
77 [[nodiscard]] auto lower_bound(ForwardRange&& range, const T& value, Compare comp)
78 {
79  return std::lower_bound(std::begin(range), std::end(range), value, comp);
80 }
81 
82 template<typename ForwardRange, typename T>
83 [[nodiscard]] auto upper_bound(ForwardRange&& range, const T& value)
84 {
85  return std::upper_bound(std::begin(range), std::end(range), value);
86 }
87 
88 template<typename ForwardRange, typename T, typename Compare>
89 [[nodiscard]] auto upper_bound(ForwardRange&& range, const T& value, Compare comp)
90 {
91  return std::upper_bound(std::begin(range), std::end(range), value, comp);
92 }
93 
94 template<typename ForwardRange, typename T>
95 [[nodiscard]] auto equal_range(ForwardRange&& range, const T& value)
96 {
97  return std::equal_range(std::begin(range), std::end(range), value);
98 }
99 
100 template<typename ForwardRange, typename T, typename Compare>
101 [[nodiscard]] auto equal_range(ForwardRange&& range, const T& value, Compare comp)
102 {
103  return std::equal_range(std::begin(range), std::end(range), value, comp);
104 }
105 
106 template<typename InputRange, typename T>
107 [[nodiscard]] auto find(InputRange&& range, const T& value)
108 {
109  return std::find(std::begin(range), std::end(range), value);
110 }
111 
112 template<typename InputRange, typename UnaryPredicate>
113 [[nodiscard]] auto find_if(InputRange&& range, UnaryPredicate pred)
114 {
115  return std::find_if(std::begin(range), std::end(range), pred);
116 }
117 
118 template<typename InputRange, typename UnaryPredicate>
119 [[nodiscard]] bool all_of(InputRange&& range, UnaryPredicate pred)
120 {
121  return std::all_of(std::begin(range), std::end(range), pred);
122 }
123 
124 template<typename InputRange, typename UnaryPredicate>
125 [[nodiscard]] bool any_of(InputRange&& range, UnaryPredicate pred)
126 {
127  return std::any_of(std::begin(range), std::end(range), pred);
128 }
129 
130 template<typename InputRange, typename UnaryPredicate>
131 [[nodiscard]] bool none_of(InputRange&& range, UnaryPredicate pred)
132 {
133  return std::none_of(std::begin(range), std::end(range), pred);
134 }
135 
136 template<typename ForwardRange>
137 [[nodiscard]] auto unique(ForwardRange&& range)
138 {
139  return std::unique(std::begin(range), std::end(range));
140 }
141 
142 template<typename ForwardRange, typename BinaryPredicate>
143 [[nodiscard]] auto unique(ForwardRange&& range, BinaryPredicate pred)
144 {
145  return std::unique(std::begin(range), std::end(range), pred);
146 }
147 
148 template<typename InputRange, typename OutputIter>
149 auto copy(InputRange&& range, OutputIter out)
150 {
151  return std::copy(std::begin(range), std::end(range), out);
152 }
153 
154 template<typename InputRange, typename OutputIter, typename UnaryPredicate>
155 auto copy_if(InputRange&& range, OutputIter out, UnaryPredicate pred)
156 {
157  return std::copy_if(std::begin(range), std::end(range), out, pred);
158 }
159 
160 template<typename InputRange, typename OutputIter, typename UnaryOperation>
161 auto transform(InputRange&& range, OutputIter out, UnaryOperation op)
162 {
163  return std::transform(std::begin(range), std::end(range), out, op);
164 }
165 
166 template<typename ForwardRange, typename Generator>
167 void generate(ForwardRange&& range, Generator&& g)
168 {
169  std::generate(std::begin(range), std::end(range), std::forward<Generator>(g));
170 }
171 
172 template<typename ForwardRange, typename T>
173 [[nodiscard]] auto remove(ForwardRange&& range, const T& value)
174 {
175  return std::remove(std::begin(range), std::end(range), value);
176 }
177 
178 template<typename ForwardRange, typename UnaryPredicate>
179 [[nodiscard]] auto remove_if(ForwardRange&& range, UnaryPredicate pred)
180 {
181  return std::remove_if(std::begin(range), std::end(range), pred);
182 }
183 
184 template<typename ForwardRange, typename T>
185 void replace(ForwardRange&& range, const T& old_value, const T& new_value)
186 {
187  std::replace(std::begin(range), std::end(range), old_value, new_value);
188 }
189 
190 template<typename ForwardRange, typename UnaryPredicate, typename T>
191 void replace_if(ForwardRange&& range, UnaryPredicate pred, const T& new_value)
192 {
193  std::replace_if(std::begin(range), std::end(range), pred, new_value);
194 }
195 
196 template<typename ForwardRange, typename T>
197 void fill(ForwardRange&& range, const T& value)
198 {
199  std::fill(std::begin(range), std::end(range), value);
200 }
201 
202 // part of c++20
203 template<typename ForwardIt, typename T>
204 constexpr void iota(ForwardIt first, ForwardIt last, T value)
205 {
206  while (first != last) {
207  *first++ = value;
208  ++value;
209  }
210 }
211 
212 template<typename ForwardRange, typename T>
213 constexpr void iota(ForwardRange&& range, T&& value)
214 {
215  iota(std::begin(range), std::end(range), std::forward<T>(value));
216 }
217 
218 template<typename InputRange, typename T>
219 [[nodiscard]] T accumulate(InputRange&& range, T init)
220 {
221  return std::accumulate(std::begin(range), std::end(range), init);
222 }
223 
224 template<typename InputRange, typename T, typename BinaryOperation>
225 [[nodiscard]] T accumulate(InputRange&& range, T init, BinaryOperation op)
226 {
227  return std::accumulate(std::begin(range), std::end(range), init, op);
228 }
229 
230 template<typename InputRange, typename T>
231 [[nodiscard]] auto count(InputRange&& range, const T& value)
232 {
233  return std::count(std::begin(range), std::end(range), value);
234 }
235 
236 template<typename InputRange, typename UnaryPredicate>
237 [[nodiscard]] auto count_if(InputRange&& range, UnaryPredicate pred)
238 {
239  return std::count_if(std::begin(range), std::end(range), pred);
240 }
241 
242 template<typename InputRange1, typename InputRange2, typename OutputIter>
243 auto set_difference(InputRange1&& range1, InputRange2&& range2, OutputIter out)
244 {
245  return std::set_difference(std::begin(range1), std::end(range1),
246  std::begin(range2), std::end(range2),
247  out);
248 }
249 
250 } // namespace ranges
251 
252 #endif
int g
bool comp(const uint8_t *p, const uint8_t *q)
Definition: ranges.hh:20
void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:197
bool binary_search(ForwardRange &&range, const T &value)
Definition: ranges.hh:59
bool any_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:125
auto unique(ForwardRange &&range)
Definition: ranges.hh:137
bool all_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:119
auto unique(ForwardRange &&range, BinaryPredicate pred)
Definition: ranges.hh:143
auto remove(ForwardRange &&range, const T &value)
Definition: ranges.hh:173
void sort(RandomAccessRange &&range, Compare comp)
Definition: ranges.hh:41
void replace(ForwardRange &&range, const T &old_value, const T &new_value)
Definition: ranges.hh:185
bool is_sorted(ForwardRange &&range)
Definition: ranges.hh:23
void replace_if(ForwardRange &&range, UnaryPredicate pred, const T &new_value)
Definition: ranges.hh:191
auto equal_range(ForwardRange &&range, const T &value, Compare comp)
Definition: ranges.hh:101
auto find_if(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:113
bool binary_search(ForwardRange &&range, const T &value, Compare comp)
Definition: ranges.hh:65
bool none_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:131
auto count(InputRange &&range, const T &value)
Definition: ranges.hh:231
auto remove_if(ForwardRange &&range, UnaryPredicate pred)
Definition: ranges.hh:179
constexpr void iota(ForwardIt first, ForwardIt last, T value)
Definition: ranges.hh:204
T accumulate(InputRange &&range, T init)
Definition: ranges.hh:219
void stable_sort(RandomAccessRange &&range)
Definition: ranges.hh:47
auto find(InputRange &&range, const T &value)
Definition: ranges.hh:107
bool is_sorted(ForwardRange &&range, Compare comp)
Definition: ranges.hh:29
auto lower_bound(ForwardRange &&range, const T &value)
Definition: ranges.hh:71
void stable_sort(RandomAccessRange &&range, Compare comp)
Definition: ranges.hh:53
auto upper_bound(ForwardRange &&range, const T &value)
Definition: ranges.hh:83
auto set_difference(InputRange1 &&range1, InputRange2 &&range2, OutputIter out)
Definition: ranges.hh:243
void generate(ForwardRange &&range, Generator &&g)
Definition: ranges.hh:167
auto upper_bound(ForwardRange &&range, const T &value, Compare comp)
Definition: ranges.hh:89
auto transform(InputRange &&range, OutputIter out, UnaryOperation op)
Definition: ranges.hh:161
auto copy_if(InputRange &&range, OutputIter out, UnaryPredicate pred)
Definition: ranges.hh:155
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:149
void sort(RandomAccessRange &&range)
Definition: ranges.hh:35
T accumulate(InputRange &&range, T init, BinaryOperation op)
Definition: ranges.hh:225
auto lower_bound(ForwardRange &&range, const T &value, Compare comp)
Definition: ranges.hh:77
auto count_if(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:237
auto equal_range(ForwardRange &&range, const T &value)
Definition: ranges.hh:95
constexpr auto begin(const zstring_view &x)
Definition: zstring_view.hh:82
constexpr auto end(const zstring_view &x)
Definition: zstring_view.hh:83