Libkleo

algorithm.h
1/*
2 utils/algorithm.h
3
4 This file is part of libkleopatra, the KDE keymanagement library
5 SPDX-FileCopyrightText: 2021 g10 Code GmbH
6 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10
11#pragma once
12
13#include <algorithm>
14#include <functional>
15#include <iterator>
16
17namespace Kleo
18{
19
20template<typename ForwardIterator, typename T>
21ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value)
22{
23 const ForwardIterator it = std::lower_bound(first, last, value);
24 return (it == last || value < *it) ? last : it;
25}
26
27template<typename ForwardIterator, typename T, typename Compare>
28ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value, Compare comp)
29{
30 const ForwardIterator it = std::lower_bound(first, last, value, comp);
31 return (it == last || comp(value, *it)) ? last : it;
32}
33
34template<typename Container, typename UnaryOperation>
35Container transformInPlace(Container &&c, UnaryOperation op)
36{
37 std::transform(std::begin(c), std::end(c), std::begin(c), op);
38 return std::move(c);
39}
40
41/** Convenience helper for checking if the predicate @p p returns @c true
42 * for all elements in the range @p range. Returns @c true if the range is empty.
43 * Use ranges::all_of() instead if you can use C++20.
44 */
45template<typename InputRange, typename UnaryPredicate>
46bool all_of(const InputRange &range, UnaryPredicate p)
47{
48 return std::all_of(std::begin(range), std::end(range), p);
49}
50
51/** Convenience helper for checking if a @p range contains at least one element
52 * for which predicate @p p returns @c true. Returns @c false if @p range is
53 * empty.
54 * Use ranges::any_of() instead if you can use C++20.
55 */
56template<typename InputRange, typename UnaryPredicate>
57bool any_of(const InputRange &range, UnaryPredicate p)
58{
59 return std::any_of(std::begin(range), std::end(range), p);
60}
61
62/** Convenience helper for counting the number of elements in the range @p range
63 * for which the predicate @p p returns @c true.
64 * Use ranges::count_if() instead if you can use C++20.
65 */
66template<typename InputRange, typename UnaryPredicate>
67auto count_if(const InputRange &range, UnaryPredicate p)
68{
69 return std::count_if(std::begin(range), std::end(range), p);
70}
71
72/** Convenience helper for finding the first element in the range @p range
73 * for which predicate @p p returns @c true.
74 * Use ranges::find_if() instead if you can use C++20.
75 */
76template<typename InputRange, typename UnaryPredicate>
77auto find_if(const InputRange &range, UnaryPredicate p)
78{
79 return std::find_if(std::begin(range), std::end(range), p);
80}
81
82/** Convenience helper for applying the function @p f on all elements of the
83 * range @p range.
84 * Use ranges::for_each() instead if you can use C++20.
85 */
86template<typename InputRange, typename UnaryFunction>
87UnaryFunction for_each(const InputRange &range, UnaryFunction f)
88{
89 return std::for_each(std::begin(range), std::end(range), f);
90}
91
92/** Convenience helper for checking if a @p container contains an element
93 * with key equivalent to @p key. This is mainly meant to be used for the
94 * associative standard containers until we can use their corresponding
95 * member function in C++20.
96 */
97template<typename Container, typename Key>
98bool contains(const Container &container, const Key &key)
99{
100 return std::find(std::begin(container), std::end(container), key) != std::end(container);
101}
102
103/** Convenience helper for checking if a range @p range contains an element
104 * for which predicate @p p returns @c true.
105 */
106template<typename InputRange, typename UnaryPredicate>
107bool contains_if(const InputRange &range, UnaryPredicate p)
108{
109 return Kleo::find_if(range, p) != std::end(range);
110}
111
112/**
113 * Convenience helper for copying elements of @p range.
114 * Use std::ranges::copy_if() instead if you can use C++20.
115 */
116template<typename InputRange, typename OutputIterator, typename UnaryPredicate>
117OutputIterator copy(InputRange &&range, OutputIterator result)
118{
119 return std::copy(std::begin(range), std::end(range), result);
120}
121
122/**
123 * Convenience helper for copying elements of @p range for which predicate @p p
124 * returns @c true.
125 * Use std::ranges::copy_if() instead if you can use C++20.
126 */
127template<typename InputRange, typename OutputIterator, typename UnaryPredicate>
128OutputIterator copy_if(InputRange &&range, OutputIterator result, UnaryPredicate p)
129{
130 return std::copy_if(std::begin(range), std::end(range), result, p);
131}
132
133/**
134 * Convenience helper for transforming the elements of @p range.
135 * Use std::ranges::transform() instead if you can use C++20.
136 */
137template<typename InputRange, typename OutputIterator, typename UnaryOperation>
138OutputIterator transform(InputRange &&range, OutputIterator result, UnaryOperation op)
139{
140 return std::transform(std::begin(range), std::end(range), result, op);
141}
142
143/**
144 * Convenience helper for transforming the elements of @p range for which
145 * predicate @p p return @c true.
146 */
147template<typename InputRange, typename OutputIterator, typename UnaryOperation, typename UnaryPredicate>
148OutputIterator transform_if(InputRange &&range, OutputIterator result, UnaryOperation op, UnaryPredicate p)
149{
150 auto first = std::begin(range);
151 auto last = std::end(range);
152 for (auto first = std::begin(range), last = std::end(range); first != last; ++first, (void)++result) {
153 if (std::invoke(p, *first)) {
154 *result = std::invoke(op, *first);
155 }
156 }
157 return std::move(result);
158}
159
160/**
161 * Convenience helper for removing elements from a vector @p v for which
162 * predicate @p p returns @c true.
163 * Use std::erase_if() instead if you can use C++20.
164 */
165template<typename Vector, typename UnaryPredicate>
166void erase_if(Vector &v, UnaryPredicate p)
167{
168 v.erase(std::remove_if(std::begin(v), std::end(v), p), std::end(v));
169}
170
171}
KDOCTOOLS_EXPORT QString transform(const QString &file, const QString &stylesheet, const QList< const char * > &params=QList< const char * >())
const QList< QKeySequence > & copy()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:56:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.