forked from qt-creator/qt-creator
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 <marco.bubke@qt.io>
This commit is contained in:
@@ -48,6 +48,323 @@
|
||||
namespace Utils
|
||||
{
|
||||
|
||||
/////////////////////////
|
||||
// anyOf
|
||||
/////////////////////////
|
||||
template<typename T, typename F>
|
||||
bool anyOf(const T &container, F predicate);
|
||||
template<typename T, typename R, typename S>
|
||||
bool anyOf(const T &container, R (S::*predicate)() const);
|
||||
template<typename T, typename R, typename S>
|
||||
bool anyOf(const T &container, R S::*member);
|
||||
|
||||
/////////////////////////
|
||||
// count
|
||||
/////////////////////////
|
||||
template<typename T, typename F>
|
||||
int count(const T &container, F predicate);
|
||||
|
||||
/////////////////////////
|
||||
// allOf
|
||||
/////////////////////////
|
||||
template<typename T, typename F>
|
||||
bool allOf(const T &container, F predicate);
|
||||
|
||||
/////////////////////////
|
||||
// erase
|
||||
/////////////////////////
|
||||
template<typename T, typename F>
|
||||
void erase(T &container, F predicate);
|
||||
|
||||
/////////////////////////
|
||||
// contains
|
||||
/////////////////////////
|
||||
template<typename T, typename F>
|
||||
bool contains(const T &container, F function);
|
||||
template<typename T, typename R, typename S>
|
||||
bool contains(const T &container, R (S::*function)() const);
|
||||
template<typename C, typename R, typename S>
|
||||
bool contains(const C &container, R S::*member);
|
||||
|
||||
/////////////////////////
|
||||
// findOr
|
||||
/////////////////////////
|
||||
template<typename C, typename F>
|
||||
Q_REQUIRED_RESULT typename C::value_type findOr(const C &container,
|
||||
typename C::value_type other,
|
||||
F function);
|
||||
template<typename T, typename R, typename S>
|
||||
Q_REQUIRED_RESULT typename T::value_type findOr(const T &container,
|
||||
typename T::value_type other,
|
||||
R (S::*function)() const);
|
||||
template<typename T, typename R, typename S>
|
||||
Q_REQUIRED_RESULT typename T::value_type findOr(const T &container,
|
||||
typename T::value_type other,
|
||||
R S::*member);
|
||||
|
||||
/////////////////////////
|
||||
// findOrDefault
|
||||
/////////////////////////
|
||||
template<typename C, typename F>
|
||||
Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
|
||||
typename C::value_type>
|
||||
findOrDefault(const C &container, F function);
|
||||
template<typename C, typename R, typename S>
|
||||
Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
|
||||
typename C::value_type>
|
||||
findOrDefault(const C &container, R (S::*function)() const);
|
||||
template<typename C, typename R, typename S>
|
||||
Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
|
||||
typename C::value_type>
|
||||
findOrDefault(const C &container, R S::*member);
|
||||
|
||||
/////////////////////////
|
||||
// indexOf
|
||||
/////////////////////////
|
||||
template<typename C, typename F>
|
||||
Q_REQUIRED_RESULT int indexOf(const C &container, F function);
|
||||
|
||||
/////////////////////////
|
||||
// maxElementOr
|
||||
/////////////////////////
|
||||
template<typename T>
|
||||
typename T::value_type maxElementOr(const T &container, typename T::value_type other);
|
||||
|
||||
/////////////////////////
|
||||
// filtered
|
||||
/////////////////////////
|
||||
template<typename C, typename F>
|
||||
Q_REQUIRED_RESULT C filtered(const C &container, F predicate);
|
||||
template<typename C, typename R, typename S>
|
||||
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<typename C, typename F>
|
||||
Q_REQUIRED_RESULT std::tuple<C, C> partition(const C &container, F predicate);
|
||||
template<typename C, typename R, typename S>
|
||||
Q_REQUIRED_RESULT std::tuple<C, C> partition(const C &container, R (S::*predicate)() const);
|
||||
|
||||
/////////////////////////
|
||||
// filteredUnique
|
||||
/////////////////////////
|
||||
template<typename C>
|
||||
Q_REQUIRED_RESULT C filteredUnique(const C &container);
|
||||
|
||||
/////////////////////////
|
||||
// qobject_container_cast
|
||||
/////////////////////////
|
||||
template<class T, template<typename> class Container, typename Base>
|
||||
Container<T> qobject_container_cast(const Container<Base> &container);
|
||||
|
||||
/////////////////////////
|
||||
// static_container_cast
|
||||
/////////////////////////
|
||||
template<class T, template<typename> class Container, typename Base>
|
||||
Container<T> static_container_cast(const Container<Base> &container);
|
||||
|
||||
/////////////////////////
|
||||
// sort
|
||||
/////////////////////////
|
||||
template<typename Container>
|
||||
inline void sort(Container &container);
|
||||
template<typename Container, typename Predicate>
|
||||
inline void sort(Container &container, Predicate p);
|
||||
template<typename Container, typename R, typename S>
|
||||
inline void sort(Container &container, R S::*member);
|
||||
template<typename Container, typename R, typename S>
|
||||
inline void sort(Container &container, R (S::*function)() const);
|
||||
|
||||
/////////////////////////
|
||||
// reverseForeach
|
||||
/////////////////////////
|
||||
template<typename Container, typename Op>
|
||||
inline void reverseForeach(const Container &c, const Op &operation);
|
||||
|
||||
/////////////////////////
|
||||
// toReferences
|
||||
/////////////////////////
|
||||
template<template<typename...> class ResultContainer, typename SourceContainer>
|
||||
auto toReferences(SourceContainer &sources);
|
||||
template<typename SourceContainer>
|
||||
auto toReferences(SourceContainer &sources);
|
||||
|
||||
/////////////////////////
|
||||
// toConstReferences
|
||||
/////////////////////////
|
||||
template<template<typename...> class ResultContainer, typename SourceContainer>
|
||||
auto toConstReferences(const SourceContainer &sources);
|
||||
template<typename SourceContainer>
|
||||
auto toConstReferences(const SourceContainer &sources);
|
||||
|
||||
/////////////////////////
|
||||
// take
|
||||
/////////////////////////
|
||||
template<class C, typename P>
|
||||
Q_REQUIRED_RESULT optional<typename C::value_type> take(C &container, P predicate);
|
||||
template<typename C, typename R, typename S>
|
||||
Q_REQUIRED_RESULT decltype(auto) take(C &container, R S::*member);
|
||||
template<typename C, typename R, typename S>
|
||||
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<class InputIt1, class InputIt2, class OutputIt, class Merge, class Compare>
|
||||
OutputIt setUnionMerge(InputIt1 first1,
|
||||
InputIt1 last1,
|
||||
InputIt2 first2,
|
||||
InputIt2 last2,
|
||||
OutputIt d_first,
|
||||
Merge merge,
|
||||
Compare comp);
|
||||
template<class InputIt1, class InputIt2, class OutputIt, class Merge>
|
||||
OutputIt setUnionMerge(
|
||||
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first, Merge merge);
|
||||
template<class OutputContainer, class InputContainer1, class InputContainer2, class Merge, class Compare>
|
||||
OutputContainer setUnionMerge(InputContainer1 &&input1,
|
||||
InputContainer2 &&input2,
|
||||
Merge merge,
|
||||
Compare comp);
|
||||
template<class OutputContainer, class InputContainer1, class InputContainer2, class Merge>
|
||||
OutputContainer setUnionMerge(InputContainer1 &&input1, InputContainer2 &&input2, Merge merge);
|
||||
|
||||
/////////////////////////
|
||||
// usize / ssize
|
||||
/////////////////////////
|
||||
template<typename Container>
|
||||
std::make_unsigned_t<typename Container::size_type> usize(Container container);
|
||||
template<typename Container>
|
||||
std::make_signed_t<typename Container::size_type> ssize(Container container);
|
||||
|
||||
/////////////////////////
|
||||
// setUnion
|
||||
/////////////////////////
|
||||
template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
|
||||
OutputIterator set_union(InputIterator1 first1,
|
||||
InputIterator1 last1,
|
||||
InputIterator2 first2,
|
||||
InputIterator2 last2,
|
||||
OutputIterator result,
|
||||
Compare comp);
|
||||
template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||
OutputIterator set_union(InputIterator1 first1,
|
||||
InputIterator1 last1,
|
||||
InputIterator2 first2,
|
||||
InputIterator2 last2,
|
||||
OutputIterator result);
|
||||
|
||||
/////////////////////////
|
||||
// transform
|
||||
/////////////////////////
|
||||
// function without result type deduction:
|
||||
template<typename ResultContainer, // complete result container type
|
||||
typename SC, // input container type
|
||||
typename F> // function type
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
|
||||
|
||||
// function with result type deduction:
|
||||
template<template<typename> class C, // result container type
|
||||
typename SC, // input container type
|
||||
typename F, // function type
|
||||
typename Value = typename std::decay_t<SC>::value_type,
|
||||
typename Result = std::decay_t<std::result_of_t<F(Value &)>>,
|
||||
typename ResultContainer = C<Result>>
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
|
||||
template<template<typename, typename> class C, // result container type
|
||||
typename SC, // input container type
|
||||
typename F, // function type
|
||||
typename Value = typename std::decay_t<SC>::value_type,
|
||||
typename Result = std::decay_t<std::result_of_t<F(Value &)>>,
|
||||
typename ResultContainer = C<Result, std::allocator<Result>>>
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
|
||||
|
||||
// member function without result type deduction:
|
||||
template<template<typename...> 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<typename ResultContainer, // complete 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 without result type deduction:
|
||||
template<typename ResultContainer, // complete result container type
|
||||
typename SC, // input container
|
||||
typename R,
|
||||
typename S>
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R S::*p);
|
||||
|
||||
// member with result type deduction:
|
||||
template<template<typename...> 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<template<typename...> class C, // container type
|
||||
typename F, // function type
|
||||
typename... CArgs> // Arguments to SC
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, F function);
|
||||
|
||||
// same container types for input and output, const input
|
||||
// member function:
|
||||
template<template<typename...> class C, // container type
|
||||
typename R,
|
||||
typename S,
|
||||
typename... CArgs> // Arguments to SC
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, R (S::*p)() const);
|
||||
|
||||
// same container types for input and output, const input
|
||||
// members:
|
||||
template<template<typename...> class C, // container
|
||||
typename R,
|
||||
typename S,
|
||||
typename... CArgs> // Arguments to SC
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, R S::*p);
|
||||
|
||||
// same container types for input and output, non-const input
|
||||
// function:
|
||||
template<template<typename...> class C, // container type
|
||||
typename F, // function type
|
||||
typename... CArgs> // Arguments to SC
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, F function);
|
||||
|
||||
// same container types for input and output, non-const input
|
||||
// member function:
|
||||
template<template<typename...> class C, // container type
|
||||
typename R,
|
||||
typename S,
|
||||
typename... CArgs> // Arguments to SC
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, R (S::*p)() const);
|
||||
|
||||
// same container types for input and output, non-const input
|
||||
// members:
|
||||
template<template<typename...> class C, // container
|
||||
typename R,
|
||||
typename S,
|
||||
typename... CArgs> // Arguments to SC
|
||||
Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, R S::*p);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//////// Implementations //////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////
|
||||
// anyOf
|
||||
/////////////////
|
||||
@@ -367,25 +684,23 @@ decltype(auto) transform(SC &&container, F function)
|
||||
|
||||
// function with result type deduction:
|
||||
template<template<typename> class C, // result container type
|
||||
typename SC, // input container type
|
||||
typename F, // function type
|
||||
typename Value = typename std::decay_t<SC>::value_type,
|
||||
typename Result = std::decay_t<std::result_of_t<F(Value&)>>,
|
||||
typename ResultContainer = C<Result>>
|
||||
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<ResultContainer>(std::forward<SC>(container), function);
|
||||
}
|
||||
|
||||
template<template<typename, typename> class C, // result container type
|
||||
typename SC, // input container type
|
||||
typename F, // function type
|
||||
typename Value = typename std::decay_t<SC>::value_type,
|
||||
typename Result = std::decay_t<std::result_of_t<F(Value&)>>,
|
||||
typename ResultContainer = C<Result, std::allocator<Result>>>
|
||||
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<ResultContainer>(std::forward<SC>(container), function);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user