1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| template <typename F1, typename F2>
struct plus_t {
using F1_info = Callable_traits<F1>;
using F2_info = Callable_traits<F2>;
using value_type = decltype( std::declval<typename F1_info::Return_type>() + std::declval<typename F2_info::Return_type>() );
F1 f1;
F2 f2;
template< class Expr >
plus_t(F1 f1, F2 f2) : f1(f1), f2(f2) {
static_assert(
std::is_same< typename Callable_traits<F1>::Arguments_type, typename Callable_traits<F2>::Arguments_type >::value,
"incompatible functors domains"
);
static_assert(
is_additionable< typename Callable_traits<F1>::Return_type, typename Callable_traits<F2>::Return_type >(),
"incompatible functors values"
);
}
template <typename... Args>
value_type operator()(Args... args) const {
static_assert(
std::is_same<
typename Callable_traits<F1>::Arguments_type,
typename Callable_traits<void(Args...)>::Arguments_type
>::value,
"wrong arguments type or count"
);
return impl(args...);//use a sub function to shut up compiler, we already have an assert
}
private:
template <typename... Args>
value_type impl(Args... args) const {
static_assert(
std::is_same<
typename Callable_traits<F1>::Arguments_type,
typename Callable_traits<void(Args...)>::Arguments_type
>::value,
"invalide operator call"
);
return f1(args...) + f2(args...);
}
};
template <typename F1, typename F2>
auto operator+(F1 f1, F2 f2) {return plus_t<F1, F2>{f1, f2};} |
Partager