Pigweed
 
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::containers {
47
50template <typename C, typename Pred>
51bool AllOf(const C& c, Pred&& pred) {
52 return std::all_of(std::begin(c), std::end(c), std::forward<Pred>(pred));
53}
54
57template <typename C, typename Pred>
58bool AnyOf(const C& c, Pred&& pred) {
59 return std::any_of(std::begin(c), std::end(c), std::forward<Pred>(pred));
60}
61
64template <typename C, typename Pred>
65bool NoneOf(const C& c, Pred&& pred) {
66 return std::none_of(std::begin(c), std::end(c), std::forward<Pred>(pred));
67}
68
71template <typename C, typename Function>
72std::decay_t<Function> ForEach(C&& c, Function&& f) {
73 return std::for_each(std::begin(c), std::end(c), std::forward<Function>(f));
74}
75
78template <typename C, typename T>
79internal_algorithm::ContainerIter<C> Find(C& c, T&& value) {
80 return std::find(std::begin(c), std::end(c), std::forward<T>(value));
81}
82
85template <typename C, typename Pred>
86internal_algorithm::ContainerIter<C> FindIf(C& c, Pred&& pred) {
87 return std::find_if(std::begin(c), std::end(c), std::forward<Pred>(pred));
88}
89
92template <typename C, typename Pred>
93internal_algorithm::ContainerIter<C> FindIfNot(C& c, Pred&& pred) {
94 return std::find_if_not(std::begin(c), std::end(c), std::forward<Pred>(pred));
95}
96
99template <typename Sequence1, typename Sequence2>
100internal_algorithm::ContainerIter<Sequence1> FindEnd(Sequence1& sequence,
101 Sequence2& subsequence) {
102 return std::find_end(std::begin(sequence),
103 std::end(sequence),
104 std::begin(subsequence),
105 std::end(subsequence));
106}
107
110template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
111internal_algorithm::ContainerIter<Sequence1> FindEnd(Sequence1& sequence,
112 Sequence2& subsequence,
113 BinaryPredicate&& pred) {
114 return std::find_end(std::begin(sequence),
115 std::end(sequence),
116 std::begin(subsequence),
117 std::end(subsequence),
118 std::forward<BinaryPredicate>(pred));
119}
120
124template <typename C1, typename C2>
125internal_algorithm::ContainerIter<C1> FindFirstOf(C1& container, C2& options) {
126 return std::find_first_of(std::begin(container),
127 std::end(container),
128 std::begin(options),
129 std::end(options));
130}
131
134template <typename C1, typename C2, typename BinaryPredicate>
135internal_algorithm::ContainerIter<C1> FindFirstOf(C1& container,
136 C2& options,
137 BinaryPredicate&& pred) {
138 return std::find_first_of(std::begin(container),
139 std::end(container),
140 std::begin(options),
141 std::end(options),
142 std::forward<BinaryPredicate>(pred));
143}
144
147template <typename Sequence>
148internal_algorithm::ContainerIter<Sequence> AdjacentFind(Sequence& sequence) {
149 return std::adjacent_find(std::begin(sequence), std::end(sequence));
150}
151
154template <typename Sequence, typename BinaryPredicate>
155internal_algorithm::ContainerIter<Sequence> AdjacentFind(
156 Sequence& sequence, BinaryPredicate&& pred) {
157 return std::adjacent_find(std::begin(sequence),
158 std::end(sequence),
159 std::forward<BinaryPredicate>(pred));
160}
161
164template <typename C, typename T>
165internal_algorithm::ContainerDifferenceType<const C> Count(const C& c,
166 T&& value) {
167 return std::count(std::begin(c), std::end(c), std::forward<T>(value));
168}
169
172template <typename C, typename Pred>
173internal_algorithm::ContainerDifferenceType<const C> CountIf(const C& c,
174 Pred&& pred) {
175 return std::count_if(std::begin(c), std::end(c), std::forward<Pred>(pred));
176}
177
181template <typename C1, typename C2>
182internal_algorithm::ContainerIterPairType<C1, C2> Mismatch(C1& c1, C2& c2) {
183 auto first1 = std::begin(c1);
184 auto last1 = std::end(c1);
185 auto first2 = std::begin(c2);
186 auto last2 = std::end(c2);
187
188 for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
189 // Negates equality because Cpp17EqualityComparable doesn't require clients
190 // to overload both `operator==` and `operator!=`.
191 if (!(*first1 == *first2)) {
192 break;
193 }
194 }
195
196 return std::make_pair(first1, first2);
197}
198
202template <typename C1, typename C2, typename BinaryPredicate>
203internal_algorithm::ContainerIterPairType<C1, C2> Mismatch(
204 C1& c1, C2& c2, BinaryPredicate pred) {
205 auto first1 = std::begin(c1);
206 auto last1 = std::end(c1);
207 auto first2 = std::begin(c2);
208 auto last2 = std::end(c2);
209
210 for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
211 if (!pred(*first1, *first2)) {
212 break;
213 }
214 }
215
216 return std::make_pair(first1, first2);
217}
218
234
235template <typename C1, typename C2>
236bool Equal(const C1& c1, const C2& c2) {
237 return ((std::size(c1) == std::size(c2)) &&
238 std::equal(std::begin(c1), std::end(c1), std::begin(c2)));
239}
240
243template <typename C1, typename C2, typename BinaryPredicate>
244bool Equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
245 return ((std::size(c1) == std::size(c2)) &&
246 std::equal(std::begin(c1),
247 std::end(c1),
248 std::begin(c2),
249 std::forward<BinaryPredicate>(pred)));
250}
251
254template <typename C1, typename C2>
255bool IsPermutation(const C1& c1, const C2& c2) {
256 using std::begin;
257 using std::end;
258 return c1.size() == c2.size() &&
259 std::is_permutation(begin(c1), end(c1), begin(c2));
260}
261
264template <typename C1, typename C2, typename BinaryPredicate>
265bool IsPermutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
266 using std::begin;
267 using std::end;
268 return c1.size() == c2.size() &&
269 std::is_permutation(begin(c1),
270 end(c1),
271 begin(c2),
272 std::forward<BinaryPredicate>(pred));
273}
274
277template <typename Sequence1, typename Sequence2>
278internal_algorithm::ContainerIter<Sequence1> Search(Sequence1& sequence,
279 Sequence2& subsequence) {
280 return std::search(std::begin(sequence),
281 std::end(sequence),
282 std::begin(subsequence),
283 std::end(subsequence));
284}
285
288template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
289internal_algorithm::ContainerIter<Sequence1> Search(Sequence1& sequence,
290 Sequence2& subsequence,
291 BinaryPredicate&& pred) {
292 return std::search(std::begin(sequence),
293 std::end(sequence),
294 std::begin(subsequence),
295 std::end(subsequence),
296 std::forward<BinaryPredicate>(pred));
297}
298
301template <typename Sequence, typename Size, typename T>
302internal_algorithm::ContainerIter<Sequence> SearchN(Sequence& sequence,
303 Size count,
304 T&& value) {
305 return std::search_n(
306 std::begin(sequence), std::end(sequence), count, std::forward<T>(value));
307}
308
311template <typename Sequence,
312 typename Size,
313 typename T,
314 typename BinaryPredicate>
315internal_algorithm::ContainerIter<Sequence> SearchN(Sequence& sequence,
316 Size count,
317 T&& value,
318 BinaryPredicate&& pred) {
319 return std::search_n(std::begin(sequence),
320 std::end(sequence),
321 count,
322 std::forward<T>(value),
323 std::forward<BinaryPredicate>(pred));
324}
325
326} // namespace pw::containers
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:74
Definition: algorithm.h:46
std::decay_t< Function > ForEach(C &&c, Function &&f)
Definition: algorithm.h:72
internal_algorithm::ContainerIter< C > FindIfNot(C &c, Pred &&pred)
Definition: algorithm.h:93
internal_algorithm::ContainerIter< Sequence > SearchN(Sequence &sequence, Size count, T &&value)
Definition: algorithm.h:302
internal_algorithm::ContainerIter< C > Find(C &c, T &&value)
Definition: algorithm.h:79
bool Equal(const C1 &c1, const C2 &c2)
Definition: algorithm.h:236
internal_algorithm::ContainerIter< Sequence1 > Search(Sequence1 &sequence, Sequence2 &subsequence)
Definition: algorithm.h:278
internal_algorithm::ContainerIter< Sequence > AdjacentFind(Sequence &sequence)
Definition: algorithm.h:148
internal_algorithm::ContainerIter< Sequence1 > FindEnd(Sequence1 &sequence, Sequence2 &subsequence)
Definition: algorithm.h:100
internal_algorithm::ContainerDifferenceType< const C > CountIf(const C &c, Pred &&pred)
Definition: algorithm.h:173
bool AllOf(const C &c, Pred &&pred)
Definition: algorithm.h:51
bool AnyOf(const C &c, Pred &&pred)
Definition: algorithm.h:58
bool IsPermutation(const C1 &c1, const C2 &c2)
Definition: algorithm.h:255
internal_algorithm::ContainerIter< C > FindIf(C &c, Pred &&pred)
Definition: algorithm.h:86
internal_algorithm::ContainerIterPairType< C1, C2 > Mismatch(C1 &c1, C2 &c2)
Definition: algorithm.h:182
bool NoneOf(const C &c, Pred &&pred)
Definition: algorithm.h:65
internal_algorithm::ContainerIter< C1 > FindFirstOf(C1 &container, C2 &options)
Definition: algorithm.h:125
internal_algorithm::ContainerDifferenceType< const C > Count(const C &c, T &&value)
Definition: algorithm.h:165