Pigweed
C/C++ API Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
algorithm.h
Go to the documentation of this file.
1// Copyright 2022 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14//
15// This was forked from
16// https://cs.opensource.google/abseil/abseil-cpp/+/main:absl/algorithm/algorithm.h;drc=12bc53e0318d80569270a5b26ccbc62b52022b89
17#pragma once
18
19#include <algorithm>
20#include <utility>
21
22#include "pw_containers/internal/algorithm_internal.h"
23
45
46namespace pw {
47namespace containers {
48
51template <typename C, typename Pred>
52bool AllOf(const C& c, Pred&& pred) {
53 return std::all_of(std::begin(c), std::end(c), std::forward<Pred>(pred));
54}
55
58template <typename C, typename Pred>
59bool AnyOf(const C& c, Pred&& pred) {
60 return std::any_of(std::begin(c), std::end(c), std::forward<Pred>(pred));
61}
62
65template <typename C, typename Pred>
66bool NoneOf(const C& c, Pred&& pred) {
67 return std::none_of(std::begin(c), std::end(c), std::forward<Pred>(pred));
68}
69
72template <typename C, typename Function>
73std::decay_t<Function> ForEach(C&& c, Function&& f) {
74 return std::for_each(std::begin(c), std::end(c), std::forward<Function>(f));
75}
76
79template <typename C, typename T>
80internal_algorithm::ContainerIter<C> Find(C& c, T&& value) {
81 return std::find(std::begin(c), std::end(c), std::forward<T>(value));
82}
83
86template <typename C, typename Pred>
87internal_algorithm::ContainerIter<C> FindIf(C& c, Pred&& pred) {
88 return std::find_if(std::begin(c), std::end(c), std::forward<Pred>(pred));
89}
90
93template <typename C, typename Pred>
94internal_algorithm::ContainerIter<C> FindIfNot(C& c, Pred&& pred) {
95 return std::find_if_not(std::begin(c), std::end(c), std::forward<Pred>(pred));
96}
97
100template <typename Sequence1, typename Sequence2>
101internal_algorithm::ContainerIter<Sequence1> FindEnd(Sequence1& sequence,
102 Sequence2& subsequence) {
103 return std::find_end(std::begin(sequence),
104 std::end(sequence),
105 std::begin(subsequence),
106 std::end(subsequence));
107}
108
111template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
112internal_algorithm::ContainerIter<Sequence1> FindEnd(Sequence1& sequence,
113 Sequence2& subsequence,
114 BinaryPredicate&& pred) {
115 return std::find_end(std::begin(sequence),
116 std::end(sequence),
117 std::begin(subsequence),
118 std::end(subsequence),
119 std::forward<BinaryPredicate>(pred));
120}
121
125template <typename C1, typename C2>
126internal_algorithm::ContainerIter<C1> FindFirstOf(C1& container, C2& options) {
127 return std::find_first_of(std::begin(container),
128 std::end(container),
129 std::begin(options),
130 std::end(options));
131}
132
135template <typename C1, typename C2, typename BinaryPredicate>
136internal_algorithm::ContainerIter<C1> FindFirstOf(C1& container,
137 C2& options,
138 BinaryPredicate&& pred) {
139 return std::find_first_of(std::begin(container),
140 std::end(container),
141 std::begin(options),
142 std::end(options),
143 std::forward<BinaryPredicate>(pred));
144}
145
148template <typename Sequence>
149internal_algorithm::ContainerIter<Sequence> AdjacentFind(Sequence& sequence) {
150 return std::adjacent_find(std::begin(sequence), std::end(sequence));
151}
152
155template <typename Sequence, typename BinaryPredicate>
156internal_algorithm::ContainerIter<Sequence> AdjacentFind(
157 Sequence& sequence, BinaryPredicate&& pred) {
158 return std::adjacent_find(std::begin(sequence),
159 std::end(sequence),
160 std::forward<BinaryPredicate>(pred));
161}
162
165template <typename C, typename T>
166internal_algorithm::ContainerDifferenceType<const C> Count(const C& c,
167 T&& value) {
168 return std::count(std::begin(c), std::end(c), std::forward<T>(value));
169}
170
173template <typename C, typename Pred>
174internal_algorithm::ContainerDifferenceType<const C> CountIf(const C& c,
175 Pred&& pred) {
176 return std::count_if(std::begin(c), std::end(c), std::forward<Pred>(pred));
177}
178
182template <typename C1, typename C2>
183internal_algorithm::ContainerIterPairType<C1, C2> Mismatch(C1& c1, C2& c2) {
184 auto first1 = std::begin(c1);
185 auto last1 = std::end(c1);
186 auto first2 = std::begin(c2);
187 auto last2 = std::end(c2);
188
189 for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
190 // Negates equality because Cpp17EqualityComparable doesn't require clients
191 // to overload both `operator==` and `operator!=`.
192 if (!(*first1 == *first2)) {
193 break;
194 }
195 }
196
197 return std::make_pair(first1, first2);
198}
199
203template <typename C1, typename C2, typename BinaryPredicate>
204internal_algorithm::ContainerIterPairType<C1, C2> Mismatch(
205 C1& c1, C2& c2, BinaryPredicate pred) {
206 auto first1 = std::begin(c1);
207 auto last1 = std::end(c1);
208 auto first2 = std::begin(c2);
209 auto last2 = std::end(c2);
210
211 for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
212 if (!pred(*first1, *first2)) {
213 break;
214 }
215 }
216
217 return std::make_pair(first1, first2);
218}
219
235
236template <typename C1, typename C2>
237bool Equal(const C1& c1, const C2& c2) {
238 return ((std::size(c1) == std::size(c2)) &&
239 std::equal(std::begin(c1), std::end(c1), std::begin(c2)));
240}
241
244template <typename C1, typename C2, typename BinaryPredicate>
245bool Equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
246 return ((std::size(c1) == std::size(c2)) &&
247 std::equal(std::begin(c1),
248 std::end(c1),
249 std::begin(c2),
250 std::forward<BinaryPredicate>(pred)));
251}
252
255template <typename C1, typename C2>
256bool IsPermutation(const C1& c1, const C2& c2) {
257 using std::begin;
258 using std::end;
259 return c1.size() == c2.size() &&
260 std::is_permutation(begin(c1), end(c1), begin(c2));
261}
262
265template <typename C1, typename C2, typename BinaryPredicate>
266bool IsPermutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
267 using std::begin;
268 using std::end;
269 return c1.size() == c2.size() &&
270 std::is_permutation(begin(c1),
271 end(c1),
272 begin(c2),
273 std::forward<BinaryPredicate>(pred));
274}
275
278template <typename Sequence1, typename Sequence2>
279internal_algorithm::ContainerIter<Sequence1> Search(Sequence1& sequence,
280 Sequence2& subsequence) {
281 return std::search(std::begin(sequence),
282 std::end(sequence),
283 std::begin(subsequence),
284 std::end(subsequence));
285}
286
289template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
290internal_algorithm::ContainerIter<Sequence1> Search(Sequence1& sequence,
291 Sequence2& subsequence,
292 BinaryPredicate&& pred) {
293 return std::search(std::begin(sequence),
294 std::end(sequence),
295 std::begin(subsequence),
296 std::end(subsequence),
297 std::forward<BinaryPredicate>(pred));
298}
299
302template <typename Sequence, typename Size, typename T>
303internal_algorithm::ContainerIter<Sequence> SearchN(Sequence& sequence,
304 Size count,
305 T&& value) {
306 return std::search_n(
307 std::begin(sequence), std::end(sequence), count, std::forward<T>(value));
308}
309
312template <typename Sequence,
313 typename Size,
314 typename T,
315 typename BinaryPredicate>
316internal_algorithm::ContainerIter<Sequence> SearchN(Sequence& sequence,
317 Size count,
318 T&& value,
319 BinaryPredicate&& pred) {
320 return std::search_n(std::begin(sequence),
321 std::end(sequence),
322 count,
323 std::forward<T>(value),
324 std::forward<BinaryPredicate>(pred));
325}
326
327} // namespace containers
328
329#if defined(__cpp_lib_constexpr_algorithms)
330using std::all_of;
331using std::any_of;
332using std::find_if;
333#else
334
337template <typename InputIt, typename Predicate>
338constexpr bool all_of(InputIt first, InputIt last, Predicate pred) {
339 for (; first != last; ++first) {
340 if (!pred(*first)) {
341 return false;
342 }
343 }
344 return true;
345}
346
349template <typename InputIt, typename Predicate>
350constexpr bool any_of(InputIt first, InputIt last, Predicate pred) {
351 for (; first != last; ++first) {
352 if (pred(*first)) {
353 return true;
354 }
355 }
356 return false;
357}
358
361template <typename InputIt, typename Predicate>
362constexpr InputIt find_if(InputIt first, InputIt last, Predicate pred) {
363 for (; first != last; ++first) {
364 if (pred(*first)) {
365 return first;
366 }
367 }
368 return last;
369}
370#endif
371} // namespace pw
std::decay_t< Function > ForEach(C &&c, Function &&f)
Definition: algorithm.h:73
internal_algorithm::ContainerIter< C > FindIfNot(C &c, Pred &&pred)
Definition: algorithm.h:94
internal_algorithm::ContainerIter< Sequence > SearchN(Sequence &sequence, Size count, T &&value)
Definition: algorithm.h:303
internal_algorithm::ContainerIter< C > Find(C &c, T &&value)
Definition: algorithm.h:80
bool Equal(const C1 &c1, const C2 &c2)
Definition: algorithm.h:237
internal_algorithm::ContainerIter< Sequence1 > Search(Sequence1 &sequence, Sequence2 &subsequence)
Definition: algorithm.h:279
internal_algorithm::ContainerIter< Sequence > AdjacentFind(Sequence &sequence)
Definition: algorithm.h:149
internal_algorithm::ContainerIter< Sequence1 > FindEnd(Sequence1 &sequence, Sequence2 &subsequence)
Definition: algorithm.h:101
internal_algorithm::ContainerDifferenceType< const C > CountIf(const C &c, Pred &&pred)
Definition: algorithm.h:174
bool AllOf(const C &c, Pred &&pred)
Definition: algorithm.h:52
bool AnyOf(const C &c, Pred &&pred)
Definition: algorithm.h:59
bool IsPermutation(const C1 &c1, const C2 &c2)
Definition: algorithm.h:256
internal_algorithm::ContainerIter< C > FindIf(C &c, Pred &&pred)
Definition: algorithm.h:87
internal_algorithm::ContainerIterPairType< C1, C2 > Mismatch(C1 &c1, C2 &c2)
Definition: algorithm.h:183
bool NoneOf(const C &c, Pred &&pred)
Definition: algorithm.h:66
internal_algorithm::ContainerIter< C1 > FindFirstOf(C1 &container, C2 &options)
Definition: algorithm.h:126
internal_algorithm::ContainerDifferenceType< const C > Count(const C &c, T &&value)
Definition: algorithm.h:166
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:74
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27
constexpr InputIt find_if(InputIt first, InputIt last, Predicate pred)
Definition: algorithm.h:362
constexpr bool all_of(InputIt first, InputIt last, Predicate pred)
Definition: algorithm.h:338
constexpr bool any_of(InputIt first, InputIt last, Predicate pred)
Definition: algorithm.h:350