std::aligned_storage<6 * sizeof(void*)>::type tiny;
};
-template <typename Fun, typename FunT = typename std::decay<Fun>::type>
+template <typename Fun, typename = Fun*>
using IsSmall = Conjunction<
- std::integral_constant<bool, (sizeof(FunT) <= sizeof(Data::tiny))>,
- std::is_nothrow_move_constructible<FunT>>;
+ std::integral_constant<bool, (sizeof(Fun) <= sizeof(Data::tiny))>,
+ std::is_nothrow_move_constructible<Fun>>;
using SmallTag = std::true_type;
using HeapTag = std::false_type;
-template <class T>
+template <typename T>
struct NotFunction : std::true_type {};
-template <class T>
+template <typename T>
struct NotFunction<Function<T>> : std::false_type {};
-template <typename Fun, typename FunT = typename std::decay<Fun>::type>
-using DecayIfConstructible = typename std::enable_if<
- Conjunction<NotFunction<FunT>, std::is_constructible<FunT, Fun>>::value,
- FunT>::type;
+template <typename T>
+using EnableIfNotFunction =
+ typename std::enable_if<NotFunction<T>::value>::type;
struct CoerceTag {};
}
ReturnType operator()(Args... args) {
- auto& fn = *static_cast<Function<ReturnType(Args...)>*>(this);
+ auto& fn = *static_cast<Function<NonConstSignature>*>(this);
return fn.call_(fn.data_, static_cast<Args&&>(args)...);
}
class SharedProxy {
- std::shared_ptr<Function<ReturnType(Args...)>> sp_;
+ std::shared_ptr<Function<NonConstSignature>> sp_;
public:
- explicit SharedProxy(Function<ReturnType(Args...)>&& func)
- : sp_(std::make_shared<Function<ReturnType(Args...)>>(
- std::move(func))) {}
+ explicit SharedProxy(Function<NonConstSignature>&& func)
+ : sp_(std::make_shared<Function<NonConstSignature>>(std::move(func))) {}
ReturnType operator()(Args&&... args) const {
return (*sp_)(static_cast<Args&&>(args)...);
}
}
ReturnType operator()(Args... args) const {
- auto& fn = *static_cast<const Function<ReturnType(Args...) const>*>(this);
+ auto& fn = *static_cast<const Function<ConstSignature>*>(this);
return fn.call_(fn.data_, static_cast<Args&&>(args)...);
}
class SharedProxy {
- std::shared_ptr<Function<ReturnType(Args...) const>> sp_;
+ std::shared_ptr<Function<ConstSignature>> sp_;
public:
- explicit SharedProxy(Function<ReturnType(Args...) const>&& func)
- : sp_(std::make_shared<Function<ReturnType(Args...) const>>(
- std::move(func))) {}
+ explicit SharedProxy(Function<ConstSignature>&& func)
+ : sp_(std::make_shared<Function<ConstSignature>>(std::move(func))) {}
ReturnType operator()(Args&&... args) const {
return (*sp_)(static_cast<Args&&>(args)...);
}
*/
template <
typename Fun,
- typename FunT = detail::function::DecayIfConstructible<Fun>,
+ typename = detail::function::EnableIfNotFunction<Fun>,
typename = typename Traits::template ResultOf<Fun>>
- /* implicit */ Function(Fun&& fun) noexcept(
- IsSmall<Fun>::value && noexcept(FunT(std::declval<Fun>())))
+ /* implicit */ Function(Fun fun) noexcept(
+ IsSmall<Fun>::value && noexcept(Fun(std::declval<Fun>())))
: Function(static_cast<Fun&&>(fun), IsSmall<Fun>{}) {}
/**
* selected by overload resolution when `fun` is not a compatible function.
*/
template <typename Fun, typename = decltype(Function(std::declval<Fun>()))>
- Function& operator=(Fun&& fun) noexcept(
+ Function& operator=(Fun fun) noexcept(
noexcept(/* implicit */ Function(std::declval<Fun>()))) {
// Doing this in place is more efficient when we can do so safely.
if (noexcept(/* implicit */ Function(std::declval<Fun>()))) {
Function<size_t(void)> uf1 = std::move(lambda1);
// Max copies: 0. Max copy+moves: 2.
- EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
+ EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 3);
EXPECT_LE(cmt.copyCount(), 0);
cmt.resetCounters();
Function<size_t(void)> uf2 = lambda2;
// Max copies: 1. Max copy+moves: 2.
- EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
+ EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 3);
EXPECT_LE(cmt.copyCount(), 1);
// Invoking Function must not make copies/moves of the callable