From 50b12945b72ea0f1f895da903d9ca66288ee3a78 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 13 May 2019 14:26:11 +0200 Subject: [PATCH] Algorithm: Put declarations at top of file It contains so much nowadays, and parts of it require internal functions, so it became hard to actually find out what algorithms we provide. Put declarations of the "public" functions at the top of the file, to make them more discoverable. Change-Id: I99456e1023a6f39223d09a2936995b8fa6dc5cb0 Reviewed-by: Marco Bubke --- src/libs/utils/algorithm.h | 343 +++++++++++++++++++++++++++++++++++-- 1 file changed, 329 insertions(+), 14 deletions(-) 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); }