diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 766f9419b84..9e80755a3a0 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -48,6 +48,323 @@ namespace Utils { +///////////////////////// +// anyOf +///////////////////////// +template +bool anyOf(const T &container, F predicate); +template +bool anyOf(const T &container, R (S::*predicate)() const); +template +bool anyOf(const T &container, R S::*member); + +///////////////////////// +// count +///////////////////////// +template +int count(const T &container, F predicate); + +///////////////////////// +// allOf +///////////////////////// +template +bool allOf(const T &container, F predicate); + +///////////////////////// +// erase +///////////////////////// +template +void erase(T &container, F predicate); + +///////////////////////// +// contains +///////////////////////// +template +bool contains(const T &container, F function); +template +bool contains(const T &container, R (S::*function)() const); +template +bool contains(const C &container, R S::*member); + +///////////////////////// +// findOr +///////////////////////// +template +Q_REQUIRED_RESULT typename C::value_type findOr(const C &container, + typename C::value_type other, + F function); +template +Q_REQUIRED_RESULT typename T::value_type findOr(const T &container, + typename T::value_type other, + R (S::*function)() const); +template +Q_REQUIRED_RESULT typename T::value_type findOr(const T &container, + typename T::value_type other, + R S::*member); + +///////////////////////// +// findOrDefault +///////////////////////// +template +Q_REQUIRED_RESULT typename std::enable_if_t::value, + typename C::value_type> +findOrDefault(const C &container, F function); +template +Q_REQUIRED_RESULT typename std::enable_if_t::value, + typename C::value_type> +findOrDefault(const C &container, R (S::*function)() const); +template +Q_REQUIRED_RESULT typename std::enable_if_t::value, + typename C::value_type> +findOrDefault(const C &container, R S::*member); + +///////////////////////// +// indexOf +///////////////////////// +template +Q_REQUIRED_RESULT int indexOf(const C &container, F function); + +///////////////////////// +// maxElementOr +///////////////////////// +template +typename T::value_type maxElementOr(const T &container, typename T::value_type other); + +///////////////////////// +// filtered +///////////////////////// +template +Q_REQUIRED_RESULT C filtered(const C &container, F predicate); +template +Q_REQUIRED_RESULT C filtered(const C &container, R (S::*predicate)() const); + +///////////////////////// +// partition +///////////////////////// +// Recommended usage: +// C hit; +// C miss; +// std::tie(hit, miss) = Utils::partition(container, predicate); +template +Q_REQUIRED_RESULT std::tuple partition(const C &container, F predicate); +template +Q_REQUIRED_RESULT std::tuple partition(const C &container, R (S::*predicate)() const); + +///////////////////////// +// filteredUnique +///////////////////////// +template +Q_REQUIRED_RESULT C filteredUnique(const C &container); + +///////////////////////// +// qobject_container_cast +///////////////////////// +template class Container, typename Base> +Container qobject_container_cast(const Container &container); + +///////////////////////// +// static_container_cast +///////////////////////// +template class Container, typename Base> +Container static_container_cast(const Container &container); + +///////////////////////// +// sort +///////////////////////// +template +inline void sort(Container &container); +template +inline void sort(Container &container, Predicate p); +template +inline void sort(Container &container, R S::*member); +template +inline void sort(Container &container, R (S::*function)() const); + +///////////////////////// +// reverseForeach +///////////////////////// +template +inline void reverseForeach(const Container &c, const Op &operation); + +///////////////////////// +// toReferences +///////////////////////// +template class ResultContainer, typename SourceContainer> +auto toReferences(SourceContainer &sources); +template +auto toReferences(SourceContainer &sources); + +///////////////////////// +// toConstReferences +///////////////////////// +template class ResultContainer, typename SourceContainer> +auto toConstReferences(const SourceContainer &sources); +template +auto toConstReferences(const SourceContainer &sources); + +///////////////////////// +// take +///////////////////////// +template +Q_REQUIRED_RESULT optional take(C &container, P predicate); +template +Q_REQUIRED_RESULT decltype(auto) take(C &container, R S::*member); +template +Q_REQUIRED_RESULT decltype(auto) take(C &container, R (S::*function)() const); + +///////////////////////// +// setUnionMerge +///////////////////////// +// Works like std::set_union but provides a merge function for items that match +// !(a > b) && !(b > a) which normally means that there is an "equal" match. +// It uses iterators to support move_iterators. +template +OutputIt setUnionMerge(InputIt1 first1, + InputIt1 last1, + InputIt2 first2, + InputIt2 last2, + OutputIt d_first, + Merge merge, + Compare comp); +template +OutputIt setUnionMerge( + InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first, Merge merge); +template +OutputContainer setUnionMerge(InputContainer1 &&input1, + InputContainer2 &&input2, + Merge merge, + Compare comp); +template +OutputContainer setUnionMerge(InputContainer1 &&input1, InputContainer2 &&input2, Merge merge); + +///////////////////////// +// usize / ssize +///////////////////////// +template +std::make_unsigned_t usize(Container container); +template +std::make_signed_t ssize(Container container); + +///////////////////////// +// setUnion +///////////////////////// +template +OutputIterator set_union(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2, + InputIterator2 last2, + OutputIterator result, + Compare comp); +template +OutputIterator set_union(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2, + InputIterator2 last2, + OutputIterator result); + +///////////////////////// +// transform +///////////////////////// +// function without result type deduction: +template // function type +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function); + +// function with result type deduction: +template class C, // result container type + typename SC, // input container type + typename F, // function type + typename Value = typename std::decay_t::value_type, + typename Result = std::decay_t>, + typename ResultContainer = C> +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function); +template class C, // result container type + typename SC, // input container type + typename F, // function type + typename Value = typename std::decay_t::value_type, + typename Result = std::decay_t>, + typename ResultContainer = C>> +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function); + +// member function without result type deduction: +template class C, // result container type + typename SC, // input container type + typename R, + typename S> +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R (S::*p)() const); + +// member function with result type deduction: +template +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R (S::*p)() const); + +// member without result type deduction: +template +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R S::*p); + +// member with result type deduction: +template class C, // result container + typename SC, // input container + typename R, + typename S> +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R S::*p); + +// same container types for input and output, const input +// function: +template class C, // container type + typename F, // function type + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT decltype(auto) transform(const C &container, F function); + +// same container types for input and output, const input +// member function: +template class C, // container type + typename R, + typename S, + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT decltype(auto) transform(const C &container, R (S::*p)() const); + +// same container types for input and output, const input +// members: +template class C, // container + typename R, + typename S, + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT decltype(auto) transform(const C &container, R S::*p); + +// same container types for input and output, non-const input +// function: +template class C, // container type + typename F, // function type + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT decltype(auto) transform(C &container, F function); + +// same container types for input and output, non-const input +// member function: +template class C, // container type + typename R, + typename S, + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT decltype(auto) transform(C &container, R (S::*p)() const); + +// same container types for input and output, non-const input +// members: +template class C, // container + typename R, + typename S, + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT decltype(auto) transform(C &container, R S::*p); + +///////////////////////////////////////////////////////////////////////////// +//////// Implementations ////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + ////////////////// // anyOf ///////////////// @@ -367,25 +684,23 @@ decltype(auto) transform(SC &&container, F function) // function with result type deduction: template class C, // result container type - typename SC, // input container type - typename F, // function type - typename Value = typename std::decay_t::value_type, - typename Result = std::decay_t>, - typename ResultContainer = C> -Q_REQUIRED_RESULT -decltype(auto) transform(SC &&container, F function) + typename SC, // input container type + typename F, // function type + typename Value, + typename Result, + typename ResultContainer> +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function) { return transform(std::forward(container), function); } template class C, // result container type - typename SC, // input container type - typename F, // function type - typename Value = typename std::decay_t::value_type, - typename Result = std::decay_t>, - typename ResultContainer = C>> -Q_REQUIRED_RESULT -decltype(auto) transform(SC &&container, F function) + typename SC, // input container type + typename F, // function type + typename Value, + typename Result, + typename ResultContainer> +Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function) { return transform(std::forward(container), function); }