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 T>
167 [[nodiscard]] auto remove(ForwardRange&& range, const T& value)
168 {
169  return std::remove(std::begin(range), std::end(range), value);
170 }
171 
172 template<typename ForwardRange, typename UnaryPredicate>
173 [[nodiscard]] auto remove_if(ForwardRange&& range, UnaryPredicate pred)
174 {
175  return std::remove_if(std::begin(range), std::end(range), pred);
176 }
177 
178 template<typename ForwardRange, typename T>
179 void replace(ForwardRange&& range, const T& old_value, const T& new_value)
180 {
181  std::replace(std::begin(range), std::end(range), old_value, new_value);
182 }
183 
184 template<typename ForwardRange, typename UnaryPredicate, typename T>
185 void replace_if(ForwardRange&& range, UnaryPredicate pred, const T& new_value)
186 {
187  std::replace_if(std::begin(range), std::end(range), pred, new_value);
188 }
189 
190 template<typename ForwardRange, typename T>
191 void fill(ForwardRange&& range, const T& value)
192 {
193  std::fill(std::begin(range), std::end(range), value);
194 }
195 
196 template<typename InputRange, typename T>
197 [[nodiscard]] T accumulate(InputRange&& range, T init)
198 {
199  return std::accumulate(std::begin(range), std::end(range), init);
200 }
201 
202 template<typename InputRange, typename T, typename BinaryOperation>
203 [[nodiscard]] T accumulate(InputRange&& range, T init, BinaryOperation op)
204 {
205  return std::accumulate(std::begin(range), std::end(range), init, op);
206 }
207 
208 template<typename InputRange, typename T>
209 [[nodiscard]] auto count(InputRange&& range, const T& value)
210 {
211  return std::count(std::begin(range), std::end(range), value);
212 }
213 
214 template<typename InputRange, typename UnaryPredicate>
215 [[nodiscard]] auto count_if(InputRange&& range, UnaryPredicate pred)
216 {
217  return std::count_if(std::begin(range), std::end(range), pred);
218 }
219 
220 template<typename InputRange1, typename InputRange2, typename OutputIter>
221 auto set_difference(InputRange1&& range1, InputRange2&& range2, OutputIter out)
222 {
223  return std::set_difference(std::begin(range1), std::end(range1),
224  std::begin(range2), std::end(range2),
225  out);
226 }
227 
228 } // namespace ranges
229 
230 #endif
bool binary_search(ForwardRange &&range, const T &value)
Definition: ranges.hh:59
auto find(InputRange &&range, const T &value)
Definition: ranges.hh:107
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:149
void stable_sort(RandomAccessRange &&range, Compare comp)
Definition: ranges.hh:53
auto remove(ForwardRange &&range, const T &value)
Definition: ranges.hh:167
auto lower_bound(ForwardRange &&range, const T &value, Compare comp)
Definition: ranges.hh:77
auto unique(ForwardRange &&range)
Definition: ranges.hh:137
auto upper_bound(ForwardRange &&range, const T &value, Compare comp)
Definition: ranges.hh:89
void replace(ForwardRange &&range, const T &old_value, const T &new_value)
Definition: ranges.hh:179
void sort(RandomAccessRange &&range, Compare comp)
Definition: ranges.hh:41
auto copy_if(InputRange &&range, OutputIter out, UnaryPredicate pred)
Definition: ranges.hh:155
auto unique(ForwardRange &&range, BinaryPredicate pred)
Definition: ranges.hh:143
bool none_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:131
auto equal_range(ForwardRange &&range, const T &value, Compare comp)
Definition: ranges.hh:101
void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:191
T accumulate(InputRange &&range, T init)
Definition: ranges.hh:197
auto remove_if(ForwardRange &&range, UnaryPredicate pred)
Definition: ranges.hh:173
auto upper_bound(ForwardRange &&range, const T &value)
Definition: ranges.hh:83
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 is_sorted(ForwardRange &&range)
Definition: ranges.hh:23
auto equal_range(ForwardRange &&range, const T &value)
Definition: ranges.hh:95
bool comp(const uint8_t *p, const uint8_t *q)
auto count_if(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:215
void sort(RandomAccessRange &&range)
Definition: ranges.hh:35
auto set_difference(InputRange1 &&range1, InputRange2 &&range2, OutputIter out)
Definition: ranges.hh:221
bool any_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:125
auto count(InputRange &&range, const T &value)
Definition: ranges.hh:209
void stable_sort(RandomAccessRange &&range)
Definition: ranges.hh:47
bool all_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:119
auto lower_bound(ForwardRange &&range, const T &value)
Definition: ranges.hh:71
T accumulate(InputRange &&range, T init, BinaryOperation op)
Definition: ranges.hh:203
Definition: ranges.hh:20
void replace_if(ForwardRange &&range, UnaryPredicate pred, const T &new_value)
Definition: ranges.hh:185
auto transform(InputRange &&range, OutputIter out, UnaryOperation op)
Definition: ranges.hh:161
bool is_sorted(ForwardRange &&range, Compare comp)
Definition: ranges.hh:29