File indexing completed on 2024-06-16 04:58:32
0001 /* 0002 utils/algorithm.h 0003 0004 This file is part of libkleopatra, the KDE keymanagement library 0005 SPDX-FileCopyrightText: 2021 g10 Code GmbH 0006 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #pragma once 0012 0013 #include <algorithm> 0014 #include <iterator> 0015 0016 namespace Kleo 0017 { 0018 0019 template<typename ForwardIterator, typename T> 0020 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value) 0021 { 0022 const ForwardIterator it = std::lower_bound(first, last, value); 0023 return (it == last || value < *it) ? last : it; 0024 } 0025 0026 template<typename ForwardIterator, typename T, typename Compare> 0027 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value, Compare comp) 0028 { 0029 const ForwardIterator it = std::lower_bound(first, last, value, comp); 0030 return (it == last || comp(value, *it)) ? last : it; 0031 } 0032 0033 template<typename Container, typename UnaryOperation> 0034 Container transformInPlace(Container &&c, UnaryOperation op) 0035 { 0036 std::transform(std::begin(c), std::end(c), std::begin(c), op); 0037 return std::move(c); 0038 } 0039 0040 /** Convenience helper for checking if the predicate @p p returns @c true 0041 * for all elements in the range @p range. Returns @c true if the range is empty. 0042 * Use ranges::all_of() instead if you can use C++20. 0043 */ 0044 template<typename InputRange, typename UnaryPredicate> 0045 bool all_of(const InputRange &range, UnaryPredicate p) 0046 { 0047 return std::all_of(std::begin(range), std::end(range), p); 0048 } 0049 0050 /** Convenience helper for checking if a @p range contains at least one element 0051 * for which predicate @p p returns @c true. Returns @c false if @p range is 0052 * empty. 0053 * Use ranges::any_of() instead if you can use C++20. 0054 */ 0055 template<typename InputRange, typename UnaryPredicate> 0056 bool any_of(const InputRange &range, UnaryPredicate p) 0057 { 0058 return std::any_of(std::begin(range), std::end(range), p); 0059 } 0060 0061 /** Convenience helper for counting the number of elements in the range @p range 0062 * for which the predicate @p p returns @c true. 0063 * Use ranges::count_if() instead if you can use C++20. 0064 */ 0065 template<typename InputRange, typename UnaryPredicate> 0066 auto count_if(const InputRange &range, UnaryPredicate p) 0067 { 0068 return std::count_if(std::begin(range), std::end(range), p); 0069 } 0070 0071 /** Convenience helper for finding the first element in the range @p range 0072 * for which predicate @p p returns @c true. 0073 * Use ranges::find_if() instead if you can use C++20. 0074 */ 0075 template<typename InputRange, typename UnaryPredicate> 0076 auto find_if(const InputRange &range, UnaryPredicate p) 0077 { 0078 return std::find_if(std::begin(range), std::end(range), p); 0079 } 0080 0081 /** Convenience helper for applying the function @p f on all elements of the 0082 * range @p range. 0083 * Use ranges::for_each() instead if you can use C++20. 0084 */ 0085 template<typename InputRange, typename UnaryFunction> 0086 UnaryFunction for_each(const InputRange &range, UnaryFunction f) 0087 { 0088 return std::for_each(std::begin(range), std::end(range), f); 0089 } 0090 0091 /** Convenience helper for checking if a @p container contains an element 0092 * with key equivalent to @p key. This is mainly meant to be used for the 0093 * associative standard containers until we can use their corresponding 0094 * member function in C++20. 0095 */ 0096 template<typename Container, typename Key> 0097 bool contains(const Container &container, const Key &key) 0098 { 0099 return std::find(std::begin(container), std::end(container), key) != std::end(container); 0100 } 0101 0102 /** Convenience helper for checking if a range @p range contains an element 0103 * for which predicate @p p returns @c true. 0104 */ 0105 template<typename InputRange, typename UnaryPredicate> 0106 bool contains_if(const InputRange &range, UnaryPredicate p) 0107 { 0108 return Kleo::find_if(range, p) != std::end(range); 0109 } 0110 0111 /** 0112 * Convenience helper for copying elements of @p range. 0113 * Use std::ranges::copy_if() instead if you can use C++20. 0114 */ 0115 template<typename InputRange, typename OutputIterator, typename UnaryPredicate> 0116 OutputIterator copy(InputRange &&range, OutputIterator result) 0117 { 0118 return std::copy(std::begin(range), std::end(range), result); 0119 } 0120 0121 /** 0122 * Convenience helper for copying elements of @p range for which predicate @p p 0123 * returns @c true. 0124 * Use std::ranges::copy_if() instead if you can use C++20. 0125 */ 0126 template<typename InputRange, typename OutputIterator, typename UnaryPredicate> 0127 OutputIterator copy_if(InputRange &&range, OutputIterator result, UnaryPredicate p) 0128 { 0129 return std::copy_if(std::begin(range), std::end(range), result, p); 0130 } 0131 0132 /** 0133 * Convenience helper for transforming the elements of @p range. 0134 * Use std::ranges::transform() instead if you can use C++20. 0135 */ 0136 template<typename InputRange, typename OutputIterator, typename UnaryOperation> 0137 OutputIterator transform(InputRange &&range, OutputIterator result, UnaryOperation op) 0138 { 0139 return std::transform(std::begin(range), std::end(range), result, op); 0140 } 0141 0142 /** 0143 * Convenience helper for removing elements from a vector @p v for which 0144 * predicate @p p returns @c true. 0145 * Use std::erase_if() instead if you can use C++20. 0146 */ 0147 template<typename Vector, typename UnaryPredicate> 0148 void erase_if(Vector &v, UnaryPredicate p) 0149 { 0150 v.erase(std::remove_if(std::begin(v), std::end(v), p), std::end(v)); 0151 } 0152 0153 }