Verified Commit 11d8be4d authored by Daniel Vrátil's avatar Daniel Vrátil 🤖
Browse files

Replace Akonadi::invoke with std::invoke

Akonadi::invoke was a C++14-compatible implementation of std::invoke.
Now that we have C++17, we can use std::invoke directly.
parent e64ccad8
Pipeline #21313 passed with stage
in 12 minutes and 32 seconds
......@@ -20,100 +20,13 @@
#ifndef AKONADI_AKHELPERS_H_
#define AKONADI_AKHELPERS_H_
#include <type_traits>
#include <utility>
namespace Akonadi
{
namespace detail
{
// C++14-compatible implementation of std::invoke(), based on implementation
// from https://en.cppreference.com/w/cpp/utility/functional/invoke
template<typename T>
struct is_reference_wrapper : std::false_type {};
template<typename T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
template<typename T>
constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
template<typename T>
constexpr bool is_member_function_pointer_v = std::is_member_function_pointer<std::remove_cv_t<std::remove_reference_t<T>>>::value;
template<typename T, typename Type, typename T1, typename ... Args>
auto invoke(Type T::* fun, T1 &&t1, Args && ... args) ->
std::enable_if_t<is_member_function_pointer_v<decltype(fun)>
&& std::is_base_of<T, std::decay_t<T1>>::value,
std::result_of_t<decltype(fun)(T, Args ...)>>
{
return (std::forward<T1>(t1).*fun)(std::forward<Args>(args) ...);
}
template<typename T, typename Type, typename T1, typename ... Args>
auto invoke(Type T::* fun, T1 &&t1, Args && ... args) ->
std::enable_if_t<is_member_function_pointer_v<decltype(fun)>
&& is_reference_wrapper_v<std::decay_t<T1>>,
std::result_of_t<decltype(fun)(T, Args ...)>>
{
return (t1.get().*fun)(std::forward<Args>(args) ...);
}
template<typename T, typename Type, typename T1, typename ... Args>
auto invoke(Type T::* fun, T1 &&t1, Args && ... args) ->
std::enable_if_t<is_member_function_pointer_v<decltype(fun)>
&& !std::is_base_of<T, std::decay_t<T1>>::value
&& !is_reference_wrapper_v<std::decay_t<T1>>,
std::result_of_t<decltype(fun)(T1, Args ...)>>
{
return ((*std::forward<T1>(t1)).*fun)(std::forward<Args>(args) ...);
}
template<typename T, typename Type, typename T1, typename ... Args>
auto invoke(Type T::* fun, T1 &&t1, Args && ...) ->
std::enable_if_t<!is_member_function_pointer_v<decltype(fun)>
&& std::is_base_of<T1, std::decay_t<T1>>::value,
std::result_of_t<decltype(fun)(T1, Args ...)>>
{
return std::forward<T1>(t1).*fun;
}
template<typename T, typename Type, typename T1, typename ... Args>
auto invoke(Type T::* fun, T1 &&t1, Args && ...) ->
std::enable_if_t<!is_member_function_pointer_v<decltype(fun)>
&& is_reference_wrapper_v<std::decay_t<T1>>,
std::result_of_t<decltype(fun)(T1, Args ...)>>
{
return t1.get().*fun;
}
template<typename T, typename Type, typename T1, typename ... Args>
auto invoke(Type T::* fun, T1 &&t1, Args && ...) ->
std::enable_if_t<!is_member_function_pointer_v<decltype(fun)>
&& !std::is_base_of<T1, std::decay_t<T1>>::value
&& !is_reference_wrapper_v<std::decay_t<T1>>,
std::result_of_t<decltype(fun)(T1, Args ...)>>
{
return (*std::forward<T1>(t1)).*fun;
}
template<typename Fun, typename ... Args>
auto invoke(Fun &&fun, Args && ... args)
{
return std::forward<Fun>(fun)(std::forward<Args>(args) ...);
}
} // namespace detail
template<typename Fun, typename ... Args>
auto invoke(Fun &&fun, Args && ... args)
{
return detail::invoke(std::forward<Fun>(fun), std::forward<Args>(args) ...);
}
static const auto IsNull = [](auto ptr) { return !(bool)ptr; };
static const auto IsNotNull = [](auto ptr) { return (bool)ptr; };
} // namespace Akonadi
#endif
......@@ -178,7 +178,7 @@ private:
};
template<typename ... Ts>
using FuncHelper = decltype(Akonadi::invoke(std::declval<Ts>() ...))(Ts ...);
using FuncHelper = decltype(std::invoke(std::declval<Ts>() ...))(Ts ...);
using IteratorValueType = typename ResultOf<FuncHelper<TransformFn, typename IteratorTrait<Iterator>::value_type>>::type;
public:
using value_type = IteratorValueType;
......@@ -193,7 +193,7 @@ public:
auto operator*() const
{
return Akonadi::invoke(mFn, *this->mIter);
return std::invoke(mFn, *this->mIter);
}
private:
......@@ -208,7 +208,7 @@ public:
: IteratorBase<FilterIterator, RangeLike>(iter, range)
, mPredicate(predicate), mEnd(end)
{
while (this->mIter != mEnd && !Akonadi::invoke(mPredicate, *this->mIter)) {
while (this->mIter != mEnd && !std::invoke(mPredicate, *this->mIter)) {
++this->mIter;
}
}
......@@ -218,7 +218,7 @@ public:
if (this->mIter != mEnd) {
do {
++this->mIter;
} while (this->mIter != mEnd && !Akonadi::invoke(mPredicate, *this->mIter));
} while (this->mIter != mEnd && !std::invoke(mPredicate, *this->mIter));
}
return *this;
}
......@@ -416,7 +416,7 @@ auto operator|(const RangeLike &range, AkRanges::detail::ForEachTag_<UnaryOperat
{
std::for_each(std::cbegin(range), std::cend(range),
[op = std::move(op)](const auto &val) mutable {
Akonadi::invoke(op.mFn, val);
std::invoke(op.mFn, val);
});
return range;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment