mirror of
https://github.com/boostorg/hof.git
synced 2026-01-31 20:22:11 +00:00
@@ -165,6 +165,79 @@ Given
|
||||
|---------------|--------------------------|
|
||||
| `f(identity)` | performs a function call |
|
||||
|
||||
Callable
|
||||
--------
|
||||
|
||||
Is an object for which the `INVOKE` operation can be applied.
|
||||
|
||||
#### Requirements:
|
||||
|
||||
The type `T` satisfies `Callable` if
|
||||
|
||||
Given
|
||||
|
||||
* `f`, an object of type `const T`
|
||||
* `Args...`, suitable list of argument types
|
||||
|
||||
The following expressions must be valid:
|
||||
|
||||
| Expression | Requirements |
|
||||
|--------------------------------------|-------------------------------------------------------|
|
||||
| `INVOKE(f, std::declval<Args>()...)` | the expression is well-formed in unevaluated context |
|
||||
|
||||
where `INVOKE(f, x, xs...)` is defined as follows:
|
||||
|
||||
* if `f` is a pointer to member function of class `T`:
|
||||
|
||||
- If `std::is_base_of<T, std::decay_t<decltype(x)>>()` is true, then `INVOKE(f, x, xs...)` is equivalent to `(x.*f)(xs...)`
|
||||
- otherwise, if `std::decay_t<decltype(x)>` is a specialization of `std::reference_wrapper`, then `INVOKE(f, x, xs...)` is equivalent to `(x.get().*f)(xs...)`
|
||||
- otherwise, if x does not satisfy the previous items, then `INVOKE(f, x, xs...)` is equivalent to `((*x).*f)(xs...)`.
|
||||
|
||||
* otherwise, if `f` is a pointer to data member of class `T`:
|
||||
|
||||
- If `std::is_base_of<T, std::decay_t<decltype(x)>>()` is true, then `INVOKE(f, x)` is equivalent to `x.*f`
|
||||
- otherwise, if `std::decay_t<decltype(x)>` is a specialization of `std::reference_wrapper`, then `INVOKE(f, x)` is equivalent to `x.get().*f`
|
||||
- otherwise, if `x` does not satisfy the previous items, then `INVOKE(f, x)` is equivalent to `(*x).*f`
|
||||
|
||||
* otherwise, `INVOKE(f, x, xs...)` is equivalent to `f(x, xs...)`
|
||||
|
||||
UnaryCallable
|
||||
-------------
|
||||
|
||||
Is an object for which the `INVOKE` operation can be applied with one parameter.
|
||||
|
||||
#### Requirements:
|
||||
|
||||
* `Callable`
|
||||
|
||||
Given
|
||||
|
||||
* `f`, an object of type `const F`
|
||||
* `arg`, a single argument
|
||||
|
||||
| Expression | Requirements |
|
||||
|------------------|-------------------------------------------------------|
|
||||
| `INVOKE(f, arg)` | the expression is well-formed in unevaluated context |
|
||||
|
||||
BinaryCallable
|
||||
--------------------
|
||||
|
||||
Is an object for which the `INVOKE` operation can be applied with two parameters.
|
||||
|
||||
#### Requirements:
|
||||
|
||||
* `Callable`
|
||||
|
||||
Given
|
||||
|
||||
* `f`, an object of type `const F`
|
||||
* `arg1`, a single argument
|
||||
* `arg2`, a single argument
|
||||
|
||||
| Expression | Requirements |
|
||||
|-------------------------|-------------------------------------------------------|
|
||||
| `INVOKE(f, arg1, arg2)` | the expression is well-formed in unevaluated context |
|
||||
|
||||
Metafunction
|
||||
------------
|
||||
|
||||
|
||||
107
fit/apply.h
107
fit/apply.h
@@ -32,7 +32,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
///
|
||||
/// Example
|
||||
/// -------
|
||||
@@ -52,14 +52,117 @@
|
||||
#include <fit/detail/forward.h>
|
||||
#include <fit/detail/static_const_var.h>
|
||||
|
||||
|
||||
namespace fit {
|
||||
|
||||
namespace detail {
|
||||
#if FIT_HAS_MANUAL_DEDUCTION || FIT_NO_EXPRESSION_SFINAE
|
||||
struct apply_mem_fn
|
||||
{
|
||||
template<class...>
|
||||
struct convertible_args;
|
||||
|
||||
template<class T, class U>
|
||||
struct is_convertible_args;
|
||||
|
||||
template<class... Ts, class... Us>
|
||||
struct is_convertible_args<convertible_args<Ts...>, convertible_args<Us...>>
|
||||
: and_<std::is_convertible<Ts, Us>...>
|
||||
{};
|
||||
|
||||
#define FIT_APPLY_MEM_FN_CALL(cv) \
|
||||
template <class R, class Base, class Derived, class... Ts, class... Us, class=typename std::enable_if<and_< \
|
||||
std::is_base_of<Base, typename std::decay<Derived>::type>, \
|
||||
is_convertible_args<convertible_args<Us...>, convertible_args<Ts...>> \
|
||||
>::value>::type> \
|
||||
constexpr R operator()(R (Base::*mf)(Ts...) cv, Derived&& ref, Us &&... xs) const \
|
||||
{ \
|
||||
return (fit::forward<Derived>(ref).*mf)(fit::forward<Us>(xs)...); \
|
||||
}
|
||||
FIT_APPLY_MEM_FN_CALL()
|
||||
FIT_APPLY_MEM_FN_CALL(const)
|
||||
FIT_APPLY_MEM_FN_CALL(volatile)
|
||||
FIT_APPLY_MEM_FN_CALL(const volatile)
|
||||
};
|
||||
|
||||
struct apply_mem_data
|
||||
{
|
||||
template <class Base, class R, class Derived, class=typename std::enable_if<(
|
||||
std::is_base_of<Base, typename std::decay<Derived>::type>::value
|
||||
)>::type>
|
||||
constexpr R operator()(R Base::*pmd, Derived&& ref) const
|
||||
{
|
||||
return fit::forward<Derived>(ref).*pmd;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class U=decltype(*std::declval<T>())>
|
||||
struct apply_deref
|
||||
{ typedef U type; };
|
||||
|
||||
#endif
|
||||
|
||||
struct apply_f
|
||||
{
|
||||
#if FIT_HAS_MANUAL_DEDUCTION || FIT_NO_EXPRESSION_SFINAE
|
||||
template<class F, class T, class... Ts, class=typename std::enable_if<(
|
||||
std::is_member_function_pointer<typename std::decay<F>::type>::value
|
||||
)>::type>
|
||||
constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<T>, id_<Ts>...)
|
||||
operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_MANUAL_RETURNS
|
||||
(
|
||||
apply_mem_fn()(f, fit::forward<T>(obj), fit::forward<Ts>(xs)...)
|
||||
);
|
||||
|
||||
template<class F, class T, class... Ts, class U=typename apply_deref<T>::type, class=typename std::enable_if<(
|
||||
std::is_member_function_pointer<typename std::decay<F>::type>::value
|
||||
)>::type>
|
||||
constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<U>, id_<Ts>...)
|
||||
operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_MANUAL_RETURNS
|
||||
(
|
||||
apply_mem_fn()(f, *fit::forward<T>(obj), fit::forward<Ts>(xs)...)
|
||||
);
|
||||
|
||||
template<class F, class T, class=typename std::enable_if<(
|
||||
std::is_member_object_pointer<typename std::decay<F>::type>::value
|
||||
)>::type>
|
||||
constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<T>)
|
||||
operator()(F&& f, T&& obj) const FIT_SFINAE_MANUAL_RETURNS
|
||||
(
|
||||
apply_mem_data()(f, fit::forward<T>(obj))
|
||||
);
|
||||
|
||||
template<class F, class T, class U=typename apply_deref<T>::type, class=typename std::enable_if<(
|
||||
std::is_member_object_pointer<typename std::decay<F>::type>::value
|
||||
)>::type>
|
||||
constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<U>)
|
||||
operator()(F&& f, T&& obj) const FIT_SFINAE_MANUAL_RETURNS
|
||||
(
|
||||
apply_mem_data()(f, *fit::forward<T>(obj))
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
template <class Base, class T, class Derived>
|
||||
constexpr auto operator()(T Base::*pmd, Derived&& ref) const
|
||||
FIT_RETURNS(fit::forward<Derived>(ref).*pmd);
|
||||
|
||||
template <class PMD, class Pointer>
|
||||
constexpr auto operator()(PMD&& pmd, Pointer&& ptr) const
|
||||
FIT_RETURNS((*fit::forward<Pointer>(ptr)).*fit::forward<PMD>(pmd));
|
||||
|
||||
template <class Base, class T, class Derived, class... Args>
|
||||
constexpr auto operator()(T Base::*pmf, Derived&& ref, Args&&... args) const
|
||||
FIT_RETURNS((fit::forward<Derived>(ref).*pmf)(fit::forward<Args>(args)...));
|
||||
|
||||
template <class PMF, class Pointer, class... Args>
|
||||
constexpr auto operator()(PMF&& pmf, Pointer&& ptr, Args&&... args) const
|
||||
FIT_RETURNS(((*fit::forward<Pointer>(ptr)).*fit::forward<PMF>(pmf))(fit::forward<Args>(args)...));
|
||||
|
||||
#endif
|
||||
template<class F, class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(F, id_<Ts>...) operator()(F&& f, Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
constexpr FIT_SFINAE_RESULT(F, id_<Ts>...)
|
||||
operator()(F&& f, Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
f(fit::forward<Ts>(xs)...)
|
||||
);
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
///
|
||||
/// Ts must be:
|
||||
///
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <fit/returns.h>
|
||||
#include <fit/detail/forward.h>
|
||||
#include <fit/detail/static_const_var.h>
|
||||
#include <fit/apply.h>
|
||||
#include <fit/eval.h>
|
||||
|
||||
#ifndef FIT_NO_ORDERD_BRACE_INIT
|
||||
@@ -95,7 +96,7 @@ struct eval_helper
|
||||
R result;
|
||||
|
||||
template<class F, class... Ts>
|
||||
constexpr eval_helper(const F& f, Ts&&... xs) : result(f(fit::forward<Ts>(xs)...))
|
||||
constexpr eval_helper(const F& f, Ts&&... xs) : result(apply(f, fit::forward<Ts>(xs)...))
|
||||
{}
|
||||
|
||||
constexpr R get_result()
|
||||
@@ -109,7 +110,7 @@ struct eval_helper<void>
|
||||
{
|
||||
int x;
|
||||
template<class F, class... Ts>
|
||||
constexpr eval_helper(const F& f, Ts&&... xs) : x(f(fit::forward<Ts>(xs)...), 0)
|
||||
constexpr eval_helper(const F& f, Ts&&... xs) : x(apply(f, fit::forward<Ts>(xs)...), 0)
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
@@ -117,7 +118,7 @@ struct eval_helper<void>
|
||||
struct apply_eval_f
|
||||
{
|
||||
template<class F, class... Ts, class R=decltype(
|
||||
std::declval<const F&>()(fit::eval(std::declval<Ts>())...)
|
||||
apply(std::declval<const F&>(), fit::eval(std::declval<Ts>())...)
|
||||
),
|
||||
class=typename std::enable_if<(!std::is_void<R>::value)>::type
|
||||
>
|
||||
@@ -134,7 +135,7 @@ struct apply_eval_f
|
||||
}
|
||||
|
||||
template<class F, class... Ts, class R=decltype(
|
||||
std::declval<const F&>()(fit::eval(std::declval<Ts>())...)
|
||||
apply(std::declval<const F&>(), fit::eval(std::declval<Ts>())...)
|
||||
),
|
||||
class=typename std::enable_if<(std::is_void<R>::value)>::type
|
||||
>
|
||||
|
||||
40
fit/by.h
40
fit/by.h
@@ -43,12 +43,12 @@
|
||||
///
|
||||
/// Projection must be:
|
||||
///
|
||||
/// * [UnaryFunctionObject](concepts.md#unaryfunctionobject)
|
||||
/// * [UnaryCallable](concepts.md#unarycallable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -60,14 +60,14 @@
|
||||
/// {}
|
||||
/// int x;
|
||||
/// };
|
||||
/// assert(fit::by(std::mem_fn(&foo::x), _ + _)(foo(1), foo(2)) == 3);
|
||||
/// assert(fit::by(&foo::x, _ + _)(foo(1), foo(2)) == 3);
|
||||
///
|
||||
|
||||
|
||||
|
||||
#include <utility>
|
||||
#include <fit/always.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/move.h>
|
||||
#include <fit/detail/make.h>
|
||||
@@ -160,17 +160,17 @@ template<class Projection, class F=void>
|
||||
struct by_adaptor;
|
||||
|
||||
template<class Projection, class F>
|
||||
struct by_adaptor : Projection, F
|
||||
struct by_adaptor : detail::callable_base<Projection>, detail::callable_base<F>
|
||||
{
|
||||
typedef by_adaptor fit_rewritable_tag;
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const Projection& base_projection(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<Projection>& base_projection(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -182,51 +182,51 @@ struct by_adaptor : Projection, F
|
||||
{
|
||||
template<class... Ts>
|
||||
struct of
|
||||
: Failure::template of<decltype(std::declval<Projection>()(std::declval<Ts>()))...>
|
||||
: Failure::template of<decltype(std::declval<detail::callable_base<Projection>>()(std::declval<Ts>()))...>
|
||||
{};
|
||||
};
|
||||
};
|
||||
|
||||
struct failure
|
||||
: failure_map<by_failure, F>
|
||||
: failure_map<by_failure, detail::callable_base<F>>
|
||||
{};
|
||||
|
||||
FIT_INHERIT_DEFAULT(by_adaptor, Projection, F)
|
||||
FIT_INHERIT_DEFAULT(by_adaptor, detail::callable_base<Projection>, F)
|
||||
|
||||
template<class P, class G, FIT_ENABLE_IF_CONVERTIBLE(P, Projection), FIT_ENABLE_IF_CONVERTIBLE(G, F)>
|
||||
template<class P, class G, FIT_ENABLE_IF_CONVERTIBLE(P, detail::callable_base<Projection>), FIT_ENABLE_IF_CONVERTIBLE(G, detail::callable_base<F>)>
|
||||
constexpr by_adaptor(P&& p, G&& f)
|
||||
: Projection(fit::forward<P>(p)), F(fit::forward<G>(f))
|
||||
: detail::callable_base<Projection>(fit::forward<P>(p)), detail::callable_base<F>(fit::forward<G>(f))
|
||||
{}
|
||||
|
||||
FIT_RETURNS_CLASS(by_adaptor);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(const F&, result_of<const Projection&, id_<Ts>>...)
|
||||
constexpr FIT_SFINAE_RESULT(const detail::callable_base<F>&, result_of<const detail::callable_base<Projection>&, id_<Ts>>...)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
detail::by_eval(
|
||||
FIT_MANGLE_CAST(const Projection&)(FIT_CONST_THIS->base_projection(xs...)),
|
||||
FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)),
|
||||
FIT_MANGLE_CAST(const detail::callable_base<Projection>&)(FIT_CONST_THIS->base_projection(xs...)),
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(xs...)),
|
||||
fit::forward<Ts>(xs)...
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
template<class Projection>
|
||||
struct by_adaptor<Projection, void> : Projection
|
||||
struct by_adaptor<Projection, void> : detail::callable_base<Projection>
|
||||
{
|
||||
typedef by_adaptor fit_rewritable1_tag;
|
||||
template<class... Ts>
|
||||
constexpr const Projection& base_projection(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<Projection>& base_projection(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
|
||||
FIT_INHERIT_DEFAULT(by_adaptor, Projection)
|
||||
FIT_INHERIT_DEFAULT(by_adaptor, detail::callable_base<Projection>)
|
||||
|
||||
template<class P, FIT_ENABLE_IF_CONVERTIBLE(P, Projection)>
|
||||
template<class P, FIT_ENABLE_IF_CONVERTIBLE(P, detail::callable_base<Projection>)>
|
||||
constexpr by_adaptor(P&& p)
|
||||
: Projection(fit::forward<P>(p))
|
||||
: detail::callable_base<Projection>(fit::forward<P>(p))
|
||||
{}
|
||||
|
||||
FIT_RETURNS_CLASS(by_adaptor);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef FIT_GUARD_CAPTURE_H
|
||||
#define FIT_GUARD_CAPTURE_H
|
||||
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/reveal.h>
|
||||
#include <fit/pack.h>
|
||||
#include <fit/always.h>
|
||||
@@ -67,14 +67,14 @@ namespace fit {
|
||||
namespace detail {
|
||||
|
||||
template<class F, class Pack>
|
||||
struct capture_invoke : F, Pack
|
||||
struct capture_invoke : detail::callable_base<F>, Pack
|
||||
{
|
||||
typedef capture_invoke fit_rewritable1_tag;
|
||||
template<class X, class Y>
|
||||
constexpr capture_invoke(X&& x, Y&& y) : F(fit::forward<X>(x)), Pack(fit::forward<Y>(y))
|
||||
constexpr capture_invoke(X&& x, Y&& y) : detail::callable_base<F>(fit::forward<X>(x)), Pack(fit::forward<Y>(y))
|
||||
{}
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -108,7 +108,7 @@ struct capture_invoke : F, Pack
|
||||
};
|
||||
|
||||
struct failure
|
||||
: failure_map<capture_failure, F>
|
||||
: failure_map<capture_failure, detail::callable_base<F>>
|
||||
{};
|
||||
|
||||
FIT_RETURNS_CLASS(capture_invoke);
|
||||
@@ -120,7 +120,7 @@ struct capture_invoke : F, Pack
|
||||
id_<const Pack&>,
|
||||
result_of<decltype(fit::pack_forward), id_<Ts>...>
|
||||
>::type,
|
||||
id_<F&&>
|
||||
id_<detail::callable_base<F>&&>
|
||||
)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
@@ -129,7 +129,7 @@ struct capture_invoke : F, Pack
|
||||
FIT_MANGLE_CAST(const Pack&)(FIT_CONST_THIS->get_pack(xs...)),
|
||||
fit::pack_forward(fit::forward<Ts>(xs)...)
|
||||
)
|
||||
(FIT_RETURNS_C_CAST(F&&)(FIT_CONST_THIS->base_function(xs...)))
|
||||
(FIT_RETURNS_C_CAST(detail::callable_base<F>&&)(FIT_CONST_THIS->base_function(xs...)))
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
///
|
||||
/// F and Gs must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
#include <fit/pack.h>
|
||||
#include <fit/always.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/make.h>
|
||||
|
||||
namespace fit { namespace detail {
|
||||
@@ -106,9 +106,9 @@ struct combine_adaptor_base<seq<Ns...>, F, Gs...>
|
||||
|
||||
template<class F, class... Gs>
|
||||
struct combine_adaptor
|
||||
: detail::combine_adaptor_base<typename detail::gens<sizeof...(Gs)>::type, F, Gs...>
|
||||
: detail::combine_adaptor_base<typename detail::gens<sizeof...(Gs)>::type, detail::callable_base<F>, detail::callable_base<Gs>...>
|
||||
{
|
||||
typedef detail::combine_adaptor_base<typename detail::gens<sizeof...(Gs)>::type, F, Gs...> base_type;
|
||||
typedef detail::combine_adaptor_base<typename detail::gens<sizeof...(Gs)>::type, detail::callable_base<F>, detail::callable_base<Gs>...> base_type;
|
||||
FIT_INHERIT_CONSTRUCTOR(combine_adaptor, base_type)
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
///
|
||||
/// Fs must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -64,7 +64,7 @@
|
||||
/// assert(r == 4);
|
||||
///
|
||||
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/always.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/compressed_pair.h>
|
||||
@@ -97,30 +97,30 @@ struct compose_kernel : detail::compressed_pair<F1, F2>
|
||||
}
|
||||
|
||||
template<class F, class... Fs>
|
||||
struct compose_adaptor : detail::compose_kernel<F, FIT_JOIN(compose_adaptor, Fs...)>
|
||||
struct compose_adaptor : detail::compose_kernel<detail::callable_base<F>, FIT_JOIN(compose_adaptor, detail::callable_base<Fs>...)>
|
||||
{
|
||||
typedef compose_adaptor fit_rewritable_tag;
|
||||
typedef FIT_JOIN(compose_adaptor, Fs...) tail;
|
||||
typedef detail::compose_kernel<F, tail> base_type;
|
||||
typedef FIT_JOIN(compose_adaptor, detail::callable_base<Fs>...) tail;
|
||||
typedef detail::compose_kernel<detail::callable_base<F>, tail> base_type;
|
||||
|
||||
FIT_INHERIT_DEFAULT(compose_adaptor, base_type)
|
||||
|
||||
template<class X, class... Xs, FIT_ENABLE_IF_CONVERTIBLE(X, F), FIT_ENABLE_IF_CONSTRUCTIBLE(tail, Xs...)>
|
||||
template<class X, class... Xs, FIT_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>), FIT_ENABLE_IF_CONSTRUCTIBLE(tail, Xs...)>
|
||||
constexpr compose_adaptor(X&& f1, Xs&& ... fs)
|
||||
: base_type(fit::forward<X>(f1), tail(fit::forward<Xs>(fs)...))
|
||||
{}
|
||||
};
|
||||
|
||||
template<class F>
|
||||
struct compose_adaptor<F> : F
|
||||
struct compose_adaptor<F> : detail::callable_base<F>
|
||||
{
|
||||
typedef compose_adaptor fit_rewritable_tag;
|
||||
|
||||
FIT_INHERIT_DEFAULT(compose_adaptor, F)
|
||||
FIT_INHERIT_DEFAULT(compose_adaptor, detail::callable_base<F>)
|
||||
|
||||
template<class X, FIT_ENABLE_IF_CONVERTIBLE(X, F)>
|
||||
template<class X, FIT_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>)>
|
||||
constexpr compose_adaptor(X&& f1)
|
||||
: F(fit::forward<X>(f1))
|
||||
: detail::callable_base<F>(fit::forward<X>(f1))
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
///
|
||||
/// State must be:
|
||||
///
|
||||
/// * MoveConstructible
|
||||
/// * CopyConstructible
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject)
|
||||
/// * [BinaryCallable](concepts.md#binarycallable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -65,7 +65,7 @@
|
||||
/// assert(fit::compress(max_f())(2, 3, 4, 5) == 5);
|
||||
///
|
||||
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/compressed_pair.h>
|
||||
#include <fit/detail/move.h>
|
||||
@@ -95,30 +95,30 @@ struct v_fold
|
||||
|
||||
template<class F, class State=void>
|
||||
struct compress_adaptor
|
||||
: detail::compressed_pair<F, State>
|
||||
: detail::compressed_pair<detail::callable_base<F>, State>
|
||||
{
|
||||
typedef detail::compressed_pair<F, State> base_type;
|
||||
typedef detail::compressed_pair<detail::callable_base<F>, State> base_type;
|
||||
FIT_INHERIT_CONSTRUCTOR(compress_adaptor, base_type)
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return this->first(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const State& get_state(Ts&&... xs) const
|
||||
constexpr State get_state(Ts&&... xs) const
|
||||
{
|
||||
return this->second(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_fold, id_<const F&>, id_<const State&>, id_<Ts>...)
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_fold, id_<const detail::callable_base<F>&>, id_<State>, id_<Ts>...)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
detail::v_fold()(
|
||||
FIT_MANGLE_CAST(const F&)(this->base_function(xs...)),
|
||||
FIT_MANGLE_CAST(State&&)(fit::move(this->get_state(xs...))),
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F>&)(this->base_function(xs...)),
|
||||
FIT_MANGLE_CAST(State)(this->get_state(xs...)),
|
||||
fit::forward<Ts>(xs)...
|
||||
)
|
||||
)
|
||||
@@ -127,22 +127,22 @@ struct compress_adaptor
|
||||
|
||||
template<class F>
|
||||
struct compress_adaptor<F, void>
|
||||
: F
|
||||
: detail::callable_base<F>
|
||||
{
|
||||
FIT_INHERIT_CONSTRUCTOR(compress_adaptor, F)
|
||||
FIT_INHERIT_CONSTRUCTOR(compress_adaptor, detail::callable_base<F>)
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_fold, id_<const F&>, id_<Ts>...)
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_fold, id_<const detail::callable_base<F>&>, id_<Ts>...)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
detail::v_fold()(
|
||||
FIT_MANGLE_CAST(const F&)(this->base_function(xs...)),
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F>&)(this->base_function(xs...)),
|
||||
fit::forward<Ts>(xs)...
|
||||
)
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
///
|
||||
/// Fs must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -68,7 +68,7 @@
|
||||
/// to how the function is chosen.
|
||||
|
||||
#include <fit/reveal.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/join.h>
|
||||
#include <fit/detail/make.h>
|
||||
@@ -106,14 +106,14 @@ struct conditional_adaptor_base<N, F, Fs...> : conditional_adaptor_base<N, F>, c
|
||||
};
|
||||
|
||||
template<int N, class F>
|
||||
struct conditional_adaptor_base<N, F> : F
|
||||
struct conditional_adaptor_base<N, F> : detail::callable_base<F>
|
||||
{
|
||||
typedef F base;
|
||||
typedef detail::callable_base<F> base;
|
||||
|
||||
FIT_INHERIT_CONSTRUCTOR(conditional_adaptor_base, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(conditional_adaptor_base, detail::callable_base<F>);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -121,10 +121,10 @@ struct conditional_adaptor_base<N, F> : F
|
||||
FIT_RETURNS_CLASS(conditional_adaptor_base);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(const F&, id_<Ts>...)
|
||||
constexpr FIT_SFINAE_RESULT(const detail::callable_base<F>&, id_<Ts>...)
|
||||
operator()(rank<N>, Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward<Ts>(xs)...)
|
||||
(FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward<Ts>(xs)...)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/move.h>
|
||||
#include <fit/detail/make.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/static_const_var.h>
|
||||
#include <fit/detail/compressed_pair.h>
|
||||
|
||||
@@ -125,22 +125,22 @@ struct decoration
|
||||
}
|
||||
|
||||
template<class F>
|
||||
constexpr decorator_invoke<F, T, D> operator()(F f) const
|
||||
constexpr decorator_invoke<detail::callable_base<F>, T, D> operator()(F f) const
|
||||
{
|
||||
return decorator_invoke<F, T, D>(fit::move(f), this->get_data(f), this->get_decorator(f));
|
||||
return decorator_invoke<detail::callable_base<F>, T, D>(fit::move(f), this->get_data(f), this->get_decorator(f));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<class F>
|
||||
struct decorate_adaptor : F
|
||||
struct decorate_adaptor : detail::callable_base<F>
|
||||
{
|
||||
typedef decorate_adaptor fit_rewritable1_tag;
|
||||
FIT_INHERIT_CONSTRUCTOR(decorate_adaptor, F)
|
||||
FIT_INHERIT_CONSTRUCTOR(decorate_adaptor, detail::callable_base<F>)
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -148,9 +148,9 @@ struct decorate_adaptor : F
|
||||
// TODO: Add predicate for constraints
|
||||
|
||||
template<class T>
|
||||
constexpr detail::decoration<T, F> operator()(T x) const
|
||||
constexpr detail::decoration<T, detail::callable_base<F>> operator()(T x) const
|
||||
{
|
||||
return detail::decoration<T, F>(fit::move(x), this->base_function(x));
|
||||
return detail::decoration<T, detail::callable_base<F>>(fit::move(x), this->base_function(x));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
69
fit/detail/callable_base.h
Normal file
69
fit/detail/callable_base.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2015 Paul Fultz II
|
||||
callable_base.h
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
|
||||
#ifndef FIT_GUARD_CALLABLE_BASE_H
|
||||
#define FIT_GUARD_CALLABLE_BASE_H
|
||||
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/apply.h>
|
||||
|
||||
#ifndef FIT_HAS_TEMPLATE_ALIAS
|
||||
#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
|
||||
#define FIT_HAS_TEMPLATE_ALIAS 0
|
||||
#else
|
||||
#define FIT_HAS_TEMPLATE_ALIAS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace fit { namespace detail {
|
||||
|
||||
template<class F>
|
||||
struct non_class_function
|
||||
{
|
||||
F f;
|
||||
FIT_DELGATE_CONSTRUCTOR(non_class_function, F, f)
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(apply_f, id_<F>, id_<Ts>...)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
fit::apply(f, fit::forward<Ts>(xs)...)
|
||||
);
|
||||
};
|
||||
|
||||
#if FIT_HAS_TEMPLATE_ALIAS
|
||||
template<class F>
|
||||
using callable_base = typename std::conditional<(std::is_class<F>::value), F, non_class_function<F>>::type;
|
||||
#else
|
||||
|
||||
template<class F>
|
||||
struct callable_base_type
|
||||
: std::conditional<(std::is_class<F>::value), F, non_class_function<F>>
|
||||
{};
|
||||
|
||||
template<class F>
|
||||
struct callable_base
|
||||
: callable_base_type<F>::type
|
||||
{
|
||||
typedef typename callable_base_type<F>::type base;
|
||||
FIT_INHERIT_CONSTRUCTOR(callable_base, base)
|
||||
};
|
||||
|
||||
template<class F>
|
||||
struct callable_base<callable_base<F>>
|
||||
: callable_base<F>
|
||||
{
|
||||
typedef callable_base<F> base;
|
||||
FIT_INHERIT_CONSTRUCTOR(callable_base, base)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
111
fit/detail/can_be_called.h
Normal file
111
fit/detail/can_be_called.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2015 Paul Fultz II
|
||||
can_be_called.h
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
|
||||
#ifndef FIT_GUARD_CAN_BE_CALLED_H
|
||||
#define FIT_GUARD_CAN_BE_CALLED_H
|
||||
|
||||
#include <fit/detail/and.h>
|
||||
#include <fit/detail/holder.h>
|
||||
#include <fit/detail/sfinae.h>
|
||||
|
||||
namespace fit { namespace detail {
|
||||
|
||||
#if FIT_NO_EXPRESSION_SFINAE
|
||||
struct dont_care
|
||||
{
|
||||
dont_care(...);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct never_care
|
||||
{
|
||||
typedef dont_care type;
|
||||
};
|
||||
|
||||
struct cant_be_called_type
|
||||
{};
|
||||
|
||||
struct no_type
|
||||
{};
|
||||
|
||||
template<class T, class U=typename std::remove_cv<typename std::remove_reference<T>::type>::type>
|
||||
struct is_callable_wrapper_base
|
||||
: std::conditional<std::is_class<U>::value, U, no_type>
|
||||
{};
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct is_callable_wrapper : is_callable_wrapper_base<F>::type
|
||||
{
|
||||
is_callable_wrapper();
|
||||
typedef cant_be_called_type const &(*pointer_to_function)(typename never_care<Ts>::type...);
|
||||
operator pointer_to_function() const;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct not_
|
||||
: std::integral_constant<bool, !T::value>
|
||||
{};
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct can_be_called
|
||||
: not_<std::is_same<cant_be_called_type, typename std::decay<decltype(
|
||||
is_callable_wrapper<F, Ts...>()(std::declval<Ts>()...)
|
||||
)>::type>>
|
||||
{};
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct check_args;
|
||||
|
||||
template<class Res, class... Ts, class... Us>
|
||||
struct check_args<Res(Us...), Ts...>
|
||||
: and_<std::is_convertible<Ts, Us>...>
|
||||
{};
|
||||
|
||||
template<class Res, class... Ts, class... Us>
|
||||
struct can_be_called<Res(*)(Us...), Ts...>
|
||||
: std::conditional<sizeof...(Ts) == sizeof...(Us),
|
||||
check_args<Res(Us...), Ts...>,
|
||||
std::false_type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<class Res, class... Ts, class... Us>
|
||||
struct can_be_called<Res(Us...), Ts...>
|
||||
: std::conditional<sizeof...(Ts) == sizeof...(Us),
|
||||
check_args<Res(Us...), Ts...>,
|
||||
std::false_type
|
||||
>::type
|
||||
{};
|
||||
|
||||
#else
|
||||
|
||||
template<class... Ts>
|
||||
struct callable_args
|
||||
{};
|
||||
|
||||
template<class F, class Args, class=void>
|
||||
struct can_be_called_impl
|
||||
: std::false_type
|
||||
{};
|
||||
|
||||
template<class F, class... Args>
|
||||
struct can_be_called_impl<F, callable_args<Args...>, typename detail::holder<
|
||||
decltype( std::declval<F>()(std::declval<Args>()...) )
|
||||
>::type>
|
||||
: std::true_type
|
||||
{};
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct can_be_called
|
||||
: can_be_called_impl<F, detail::callable_args<Ts...>>
|
||||
{};
|
||||
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
#if FIT_HAS_MANUAL_DEDUCTION || FIT_NO_EXPRESSION_SFINAE
|
||||
|
||||
#include <type_traits>
|
||||
#include <fit/is_callable.h>
|
||||
#include <fit/detail/and.h>
|
||||
#include <fit/detail/holder.h>
|
||||
#include <fit/detail/can_be_called.h>
|
||||
|
||||
namespace fit { namespace detail {
|
||||
|
||||
@@ -34,7 +34,7 @@ template<class F, class... Ts>
|
||||
struct result_of_impl<
|
||||
F,
|
||||
holder<Ts...>,
|
||||
typename std::enable_if<is_callable<F, typename Ts::type...>::value>::type
|
||||
typename std::enable_if<can_be_called<F, typename Ts::type...>::value>::type
|
||||
>
|
||||
{
|
||||
typedef decltype(std::declval<F>()(std::declval<typename Ts::type>()...)) type;
|
||||
|
||||
16
fit/fix.h
16
fit/fix.h
@@ -37,7 +37,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -48,7 +48,7 @@
|
||||
///
|
||||
|
||||
#include <fit/always.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/reveal.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/move.h>
|
||||
@@ -71,12 +71,12 @@ namespace fit {
|
||||
namespace detail{
|
||||
|
||||
template<class Derived, class F>
|
||||
struct fix_adaptor_base : F
|
||||
struct fix_adaptor_base : detail::callable_base<F>
|
||||
{
|
||||
FIT_INHERIT_CONSTRUCTOR(fix_adaptor_base, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(fix_adaptor_base, detail::callable_base<F>);
|
||||
|
||||
template<class... Ts>
|
||||
FIT_FIX_CONSTEXPR const F& base_function(Ts&&... xs) const
|
||||
FIT_FIX_CONSTEXPR const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -100,17 +100,17 @@ struct fix_adaptor_base : F
|
||||
};
|
||||
|
||||
struct failure
|
||||
: failure_map<fix_failure, F>
|
||||
: failure_map<fix_failure, detail::callable_base<F>>
|
||||
{};
|
||||
|
||||
|
||||
FIT_RETURNS_CLASS(fix_adaptor_base);
|
||||
|
||||
template<class... Ts>
|
||||
FIT_FIX_CONSTEXPR FIT_SFINAE_RESULT(const F&, id_<const Derived&>, id_<Ts>...)
|
||||
FIT_FIX_CONSTEXPR FIT_SFINAE_RESULT(const detail::callable_base<F>&, id_<const Derived&>, id_<Ts>...)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...))
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(xs...))
|
||||
(FIT_MANGLE_CAST(const Derived&)(FIT_CONST_THIS->derived_function(xs...)), fit::forward<Ts>(xs)...)
|
||||
);
|
||||
};
|
||||
|
||||
14
fit/flip.h
14
fit/flip.h
@@ -32,7 +32,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject)
|
||||
/// * [BinaryCallable](concepts.md#binarycallable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -42,7 +42,7 @@
|
||||
/// assert(r == 3);
|
||||
///
|
||||
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/reveal.h>
|
||||
#include <fit/detail/make.h>
|
||||
#include <fit/detail/static_const_var.h>
|
||||
@@ -50,10 +50,10 @@
|
||||
namespace fit {
|
||||
|
||||
template<class F>
|
||||
struct flip_adaptor : F
|
||||
struct flip_adaptor : detail::callable_base<F>
|
||||
{
|
||||
typedef flip_adaptor fit_rewritable1_tag;
|
||||
FIT_INHERIT_CONSTRUCTOR(flip_adaptor, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(flip_adaptor, detail::callable_base<F>);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
@@ -74,16 +74,16 @@ struct flip_adaptor : F
|
||||
};
|
||||
|
||||
struct failure
|
||||
: failure_map<flip_failure, F>
|
||||
: failure_map<flip_failure, detail::callable_base<F>>
|
||||
{};
|
||||
|
||||
FIT_RETURNS_CLASS(flip_adaptor);
|
||||
|
||||
template<class T, class U, class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(const F&, id_<U>, id_<T>, id_<Ts>...)
|
||||
constexpr FIT_SFINAE_RESULT(const detail::callable_base<F>&, id_<U>, id_<T>, id_<Ts>...)
|
||||
operator()(T&& x, U&& y, Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)))
|
||||
(FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(xs...)))
|
||||
(fit::forward<U>(y), fit::forward<T>(x), fit::forward<Ts>(xs)...)
|
||||
);
|
||||
};
|
||||
|
||||
22
fit/flow.h
22
fit/flow.h
@@ -36,7 +36,7 @@
|
||||
///
|
||||
/// Fs must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -64,7 +64,7 @@
|
||||
/// assert(r == 4);
|
||||
///
|
||||
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/always.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/compressed_pair.h>
|
||||
@@ -77,20 +77,20 @@
|
||||
namespace fit { namespace detail {
|
||||
|
||||
template<class F1, class F2>
|
||||
struct flow_kernel : detail::compressed_pair<F1, F2>
|
||||
struct flow_kernel : detail::compressed_pair<detail::callable_base<F1>, detail::callable_base<F2>>
|
||||
{
|
||||
typedef detail::compressed_pair<F1, F2> base_type;
|
||||
typedef detail::compressed_pair<detail::callable_base<F1>, detail::callable_base<F2>> base_type;
|
||||
|
||||
FIT_INHERIT_CONSTRUCTOR(flow_kernel, base_type)
|
||||
|
||||
FIT_RETURNS_CLASS(flow_kernel);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(const F2&, result_of<const F1&, id_<Ts>...>)
|
||||
constexpr FIT_SFINAE_RESULT(const detail::callable_base<F2>&, result_of<const detail::callable_base<F1>&, id_<Ts>...>)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
FIT_MANGLE_CAST(const F2&)(FIT_CONST_THIS->second(xs...))(
|
||||
FIT_MANGLE_CAST(const F1&)(FIT_CONST_THIS->first(xs...))(fit::forward<Ts>(xs)...)
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F2>&)(FIT_CONST_THIS->second(xs...))(
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F1>&)(FIT_CONST_THIS->first(xs...))(fit::forward<Ts>(xs)...)
|
||||
)
|
||||
);
|
||||
};
|
||||
@@ -112,14 +112,14 @@ struct flow_adaptor : detail::flow_kernel<F, FIT_JOIN(flow_adaptor, Fs...)>
|
||||
};
|
||||
|
||||
template<class F>
|
||||
struct flow_adaptor<F> : F
|
||||
struct flow_adaptor<F> : detail::callable_base<F>
|
||||
{
|
||||
typedef flow_adaptor fit_rewritable_tag;
|
||||
FIT_INHERIT_DEFAULT(flow_adaptor, F)
|
||||
FIT_INHERIT_DEFAULT(flow_adaptor, detail::callable_base<F>)
|
||||
|
||||
template<class X, FIT_ENABLE_IF_CONVERTIBLE(X, F)>
|
||||
template<class X, FIT_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>)>
|
||||
constexpr flow_adaptor(X&& f1)
|
||||
: F(fit::forward<X>(f1))
|
||||
: detail::callable_base<F>(fit::forward<X>(f1))
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
8
fit/if.h
8
fit/if.h
@@ -36,7 +36,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -58,7 +58,7 @@
|
||||
///
|
||||
|
||||
#include <fit/always.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/forward.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/move.h>
|
||||
@@ -74,9 +74,9 @@ struct if_depend
|
||||
{};
|
||||
|
||||
template<bool Cond, class F>
|
||||
struct if_adaptor : F
|
||||
struct if_adaptor : detail::callable_base<F>
|
||||
{
|
||||
FIT_INHERIT_CONSTRUCTOR(if_adaptor, F)
|
||||
FIT_INHERIT_CONSTRUCTOR(if_adaptor, detail::callable_base<F>)
|
||||
};
|
||||
|
||||
template<class F>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#include <fit/detail/static_const_var.h>
|
||||
|
||||
namespace fit {
|
||||
|
||||
// TODO: Support non-classes as well
|
||||
template<class F>
|
||||
struct indirect_adaptor : F
|
||||
{
|
||||
|
||||
14
fit/infix.h
14
fit/infix.h
@@ -34,7 +34,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject)
|
||||
/// * [BinaryCallable](concepts.md#binarycallable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -55,7 +55,7 @@
|
||||
///
|
||||
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/always.h>
|
||||
#include <fit/detail/move.h>
|
||||
#include <fit/detail/make.h>
|
||||
@@ -105,19 +105,19 @@ constexpr postfix_adaptor<T, F> make_postfix_adaptor(T&& x, F f)
|
||||
}
|
||||
|
||||
template<class F>
|
||||
struct infix_adaptor : F
|
||||
struct infix_adaptor : detail::callable_base<F>
|
||||
{
|
||||
typedef infix_adaptor fit_rewritable1_tag;
|
||||
FIT_INHERIT_CONSTRUCTOR(infix_adaptor, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(infix_adaptor, detail::callable_base<F>);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& infix_base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& infix_base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -127,7 +127,7 @@ struct infix_adaptor : F
|
||||
template<class... Ts>
|
||||
constexpr auto operator()(Ts&&... xs) const FIT_RETURNS
|
||||
(
|
||||
(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward<Ts>(xs)...)
|
||||
(FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward<Ts>(xs)...)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -14,9 +14,15 @@
|
||||
/// Description
|
||||
/// -----------
|
||||
///
|
||||
/// The `is_callable` metafunction checks if the function object is callable with
|
||||
/// The `is_callable` metafunction checks if the function is callable with
|
||||
/// certain parameters.
|
||||
///
|
||||
/// Requirements
|
||||
/// ------------
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [Callable](concepts.md#callable)
|
||||
///
|
||||
/// Synopsis
|
||||
/// --------
|
||||
@@ -36,108 +42,17 @@
|
||||
/// static_assert(is_callable<is_callable_class, int>(), "Not callable");
|
||||
///
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <fit/detail/holder.h>
|
||||
#include <fit/detail/and.h>
|
||||
#include <fit/detail/sfinae.h>
|
||||
|
||||
#include <fit/detail/can_be_called.h>
|
||||
#include <fit/apply.h>
|
||||
|
||||
namespace fit {
|
||||
|
||||
#if FIT_NO_EXPRESSION_SFINAE
|
||||
namespace detail {
|
||||
|
||||
struct dont_care
|
||||
{
|
||||
dont_care(...);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct never_care
|
||||
{
|
||||
typedef dont_care type;
|
||||
};
|
||||
|
||||
struct cant_be_called_type
|
||||
{};
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct is_callable_wrapper : std::remove_cv<typename std::remove_reference<F>::type>::type
|
||||
{
|
||||
is_callable_wrapper();
|
||||
typedef cant_be_called_type const &(*pointer_to_function)(typename never_care<Ts>::type...);
|
||||
operator pointer_to_function() const;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct not_
|
||||
: std::integral_constant<bool, !T::value>
|
||||
{};
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct can_be_called
|
||||
: not_<std::is_same<cant_be_called_type, typename std::decay<decltype(
|
||||
is_callable_wrapper<F, Ts...>()(std::declval<Ts>()...)
|
||||
)>::type>>
|
||||
{};
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct check_args;
|
||||
|
||||
template<class Res, class... Ts, class... Us>
|
||||
struct check_args<Res(Us...), Ts...>
|
||||
: and_<std::is_convertible<Ts, Us>...>
|
||||
{};
|
||||
|
||||
template<class Res, class... Ts, class... Us>
|
||||
struct can_be_called<Res(*)(Us...), Ts...>
|
||||
: std::conditional<sizeof...(Ts) == sizeof...(Us),
|
||||
check_args<Res(Us...), Ts...>,
|
||||
std::false_type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<class Res, class... Ts, class... Us>
|
||||
struct can_be_called<Res(Us...), Ts...>
|
||||
: std::conditional<sizeof...(Ts) == sizeof...(Us),
|
||||
check_args<Res(Us...), Ts...>,
|
||||
std::false_type
|
||||
>::type
|
||||
{};
|
||||
}
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct is_callable
|
||||
: detail::can_be_called<F, Ts...>
|
||||
: detail::can_be_called<detail::apply_f, F, Ts...>
|
||||
{};
|
||||
|
||||
#else
|
||||
namespace detail {
|
||||
template<class... Ts>
|
||||
struct callable_args
|
||||
{};
|
||||
|
||||
template<class F, class Args, class=void>
|
||||
struct is_callable_impl
|
||||
: std::false_type
|
||||
{};
|
||||
|
||||
template<class F, class... Args>
|
||||
struct is_callable_impl<F, callable_args<Args...>, typename detail::holder<
|
||||
decltype( std::declval<F>()(std::declval<Args>()...) )
|
||||
>::type>
|
||||
: std::true_type
|
||||
{};
|
||||
}
|
||||
|
||||
|
||||
template<class F, class... Ts>
|
||||
struct is_callable
|
||||
: detail::is_callable_impl<F, detail::callable_args<Ts...>>
|
||||
{};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
12
fit/lazy.h
12
fit/lazy.h
@@ -36,7 +36,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -225,12 +225,12 @@ constexpr lazy_nullary_invoker<F> make_lazy_nullary_invoker(F f)
|
||||
|
||||
|
||||
template<class F>
|
||||
struct lazy_adaptor : F
|
||||
struct lazy_adaptor : detail::callable_base<F>
|
||||
{
|
||||
FIT_INHERIT_CONSTRUCTOR(lazy_adaptor, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(lazy_adaptor, detail::callable_base<F>);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -240,7 +240,7 @@ struct lazy_adaptor : F
|
||||
template<class T, class... Ts>
|
||||
constexpr auto operator()(T x, Ts... xs) const FIT_RETURNS
|
||||
(
|
||||
fit::detail::make_lazy_invoker(FIT_RETURNS_C_CAST(F&&)(FIT_CONST_THIS->base_function(x, xs...)),
|
||||
fit::detail::make_lazy_invoker(FIT_RETURNS_C_CAST(detail::callable_base<F>&&)(FIT_CONST_THIS->base_function(x, xs...)),
|
||||
pack(fit::move(x), fit::move(xs)...))
|
||||
);
|
||||
|
||||
@@ -248,7 +248,7 @@ struct lazy_adaptor : F
|
||||
template<class Unused=int>
|
||||
constexpr detail::lazy_nullary_invoker<F> operator()() const
|
||||
{
|
||||
return fit::detail::make_lazy_nullary_invoker((F&&)(
|
||||
return fit::detail::make_lazy_nullary_invoker((detail::callable_base<F>&&)(
|
||||
this->base_function(Unused())
|
||||
));
|
||||
}
|
||||
|
||||
19
fit/match.h
19
fit/match.h
@@ -30,7 +30,7 @@
|
||||
///
|
||||
/// Fs must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -62,6 +62,7 @@
|
||||
///
|
||||
|
||||
#include <fit/reveal.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/move.h>
|
||||
#include <fit/detail/make.h>
|
||||
@@ -72,20 +73,20 @@ namespace fit {
|
||||
template<class...Fs> struct match_adaptor;
|
||||
|
||||
template<class F, class...Fs>
|
||||
struct match_adaptor<F, Fs...> : F, match_adaptor<Fs...>
|
||||
struct match_adaptor<F, Fs...> : detail::callable_base<F>, match_adaptor<Fs...>
|
||||
{
|
||||
typedef match_adaptor<Fs...> base;
|
||||
typedef match_adaptor fit_rewritable_tag;
|
||||
|
||||
struct failure
|
||||
: failure_for<F, Fs...>
|
||||
: failure_for<detail::callable_base<F>, Fs...>
|
||||
{};
|
||||
|
||||
FIT_INHERIT_DEFAULT(match_adaptor, F, base);
|
||||
FIT_INHERIT_DEFAULT(match_adaptor, detail::callable_base<F>, base);
|
||||
|
||||
template<class X, class... Xs, FIT_ENABLE_IF_CONVERTIBLE(X, F), FIT_ENABLE_IF_CONSTRUCTIBLE(base, Xs...)>
|
||||
template<class X, class... Xs, FIT_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>), FIT_ENABLE_IF_CONSTRUCTIBLE(base, Xs...)>
|
||||
constexpr match_adaptor(X&& f1, Xs&& ... fs)
|
||||
: F(fit::forward<X>(f1)), base(fit::forward<Xs>(fs)...)
|
||||
: detail::callable_base<F>(fit::forward<X>(f1)), base(fit::forward<Xs>(fs)...)
|
||||
{}
|
||||
|
||||
using F::operator();
|
||||
@@ -93,13 +94,13 @@ struct match_adaptor<F, Fs...> : F, match_adaptor<Fs...>
|
||||
};
|
||||
|
||||
template<class F>
|
||||
struct match_adaptor<F> : F
|
||||
struct match_adaptor<F> : detail::callable_base<F>
|
||||
{
|
||||
typedef F base;
|
||||
typedef detail::callable_base<F> base;
|
||||
typedef match_adaptor fit_rewritable_tag;
|
||||
using F::operator();
|
||||
|
||||
FIT_INHERIT_CONSTRUCTOR(match_adaptor, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(match_adaptor, detail::callable_base<F>);
|
||||
};
|
||||
|
||||
FIT_DECLARE_STATIC_VAR(match, detail::make<match_adaptor>);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -173,13 +173,13 @@ struct partial_adaptor_base
|
||||
> type;
|
||||
};
|
||||
|
||||
template<class F>
|
||||
struct partial_adaptor_base<F, void>
|
||||
template<class Derived, class F>
|
||||
struct partial_adaptor_pack_base
|
||||
{
|
||||
typedef conditional_adaptor
|
||||
<
|
||||
F,
|
||||
partial_adaptor_pack<partial_adaptor<F, void>, F>
|
||||
partial_adaptor_pack<Derived, F>
|
||||
> type;
|
||||
};
|
||||
|
||||
@@ -214,14 +214,14 @@ struct partial_adaptor : detail::partial_adaptor_base<F, Pack>::type, F, Pack
|
||||
};
|
||||
|
||||
template<class F>
|
||||
struct partial_adaptor<F, void> : detail::partial_adaptor_base<F, void>::type
|
||||
struct partial_adaptor<F, void> : detail::partial_adaptor_pack_base<partial_adaptor<F, void>, detail::callable_base<F>>::type
|
||||
{
|
||||
typedef typename detail::partial_adaptor_base<F, void>::type base;
|
||||
typedef typename detail::partial_adaptor_pack_base<partial_adaptor<F, void>, detail::callable_base<F>>::type base;
|
||||
|
||||
typedef partial_adaptor fit_rewritable1_tag;
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&...) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&...) const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
@@ -231,6 +231,7 @@ struct partial_adaptor<F, void> : detail::partial_adaptor_base<F, void>::type
|
||||
FIT_INHERIT_CONSTRUCTOR(partial_adaptor, base);
|
||||
|
||||
};
|
||||
|
||||
// Make partial_adaptor work with pipable_adaptor by removing its pipableness
|
||||
template<class F>
|
||||
struct partial_adaptor<pipable_adaptor<F>, void>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -145,14 +145,14 @@ constexpr auto operator|(A&& a, const pipe_closure<F, Pack>& p) FIT_RETURNS
|
||||
|
||||
template<class F>
|
||||
struct pipable_adaptor
|
||||
: conditional_adaptor<F, detail::pipe_pack<pipable_adaptor<F>, F> >
|
||||
: conditional_adaptor<detail::callable_base<F>, detail::pipe_pack<pipable_adaptor<F>, detail::callable_base<F>> >
|
||||
{
|
||||
typedef conditional_adaptor<F, detail::pipe_pack<pipable_adaptor<F>, F> > base;
|
||||
typedef conditional_adaptor<detail::callable_base<F>, detail::pipe_pack<pipable_adaptor<F>, detail::callable_base<F>> > base;
|
||||
typedef pipable_adaptor fit_rewritable_tag;
|
||||
|
||||
FIT_INHERIT_CONSTRUCTOR(pipable_adaptor, base);
|
||||
|
||||
constexpr const F& base_function() const
|
||||
constexpr const detail::callable_base<F>& base_function() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
namespace fit {
|
||||
|
||||
template<class F>
|
||||
struct protect_adaptor : F
|
||||
struct protect_adaptor : detail::callable_base<F>
|
||||
{
|
||||
typedef protect_adaptor fit_rewritable1_tag;
|
||||
template<class... Ts>
|
||||
constexpr protect_adaptor(Ts&&... xs) : F(fit::forward<Ts>(xs)...)
|
||||
constexpr protect_adaptor(Ts&&... xs) : detail::callable_base<F>(fit::forward<Ts>(xs)...)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
18
fit/result.h
18
fit/result.h
@@ -31,7 +31,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -50,7 +50,7 @@
|
||||
/// static_assert(std::is_same<decltype(int_result(true)), int>::value, "Not the same type");
|
||||
///
|
||||
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/is_callable.h>
|
||||
#include <fit/always.h>
|
||||
#include <fit/reveal.h>
|
||||
@@ -58,18 +58,18 @@
|
||||
namespace fit {
|
||||
|
||||
template<class Result, class F>
|
||||
struct result_adaptor : F
|
||||
struct result_adaptor : detail::callable_base<F>
|
||||
{
|
||||
FIT_INHERIT_CONSTRUCTOR(result_adaptor, F)
|
||||
FIT_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
|
||||
|
||||
typedef Result result_type;
|
||||
|
||||
struct failure
|
||||
: failure_for<F>
|
||||
: failure_for<detail::callable_base<F>>
|
||||
{};
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -82,14 +82,14 @@ struct result_adaptor : F
|
||||
};
|
||||
|
||||
template<class F>
|
||||
struct result_adaptor<void, F> : F
|
||||
struct result_adaptor<void, F> : detail::callable_base<F>
|
||||
{
|
||||
FIT_INHERIT_CONSTRUCTOR(result_adaptor, F)
|
||||
FIT_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
|
||||
|
||||
typedef void result_type;
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
|
||||
11
fit/reveal.h
11
fit/reveal.h
@@ -32,7 +32,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <fit/is_callable.h>
|
||||
#include <fit/identity.h>
|
||||
#include <fit/detail/move.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/holder.h>
|
||||
#include <fit/detail/join.h>
|
||||
@@ -211,13 +212,13 @@ struct failure_for
|
||||
|
||||
template<class F>
|
||||
struct reveal_adaptor
|
||||
: detail::traverse_failure<F>, F
|
||||
: detail::traverse_failure<detail::callable_base<F>>, detail::callable_base<F>
|
||||
{
|
||||
typedef reveal_adaptor fit_rewritable1_tag;
|
||||
using detail::traverse_failure<F>::operator();
|
||||
using F::operator();
|
||||
using detail::traverse_failure<detail::callable_base<F>>::operator();
|
||||
using detail::callable_base<F>::operator();
|
||||
|
||||
FIT_INHERIT_CONSTRUCTOR(reveal_adaptor, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(reveal_adaptor, detail::callable_base<F>);
|
||||
};
|
||||
// Avoid double reveals, it causes problem on gcc 4.6
|
||||
template<class F>
|
||||
|
||||
@@ -45,11 +45,11 @@
|
||||
///
|
||||
/// State must be:
|
||||
///
|
||||
/// * MoveConstructible
|
||||
/// * CopyConstructible
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject)
|
||||
/// * [BinaryCallable](concepts.md#binarycallable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -66,7 +66,7 @@
|
||||
/// assert(fit::reverse_compress(max_f())(2, 3, 4, 5) == 5);
|
||||
///
|
||||
|
||||
#include <fit/detail/result_of.h>
|
||||
#include <fit/detail/callable_base.h>
|
||||
#include <fit/detail/delegate.h>
|
||||
#include <fit/detail/compressed_pair.h>
|
||||
#include <fit/detail/move.h>
|
||||
@@ -96,30 +96,30 @@ struct v_reverse_fold
|
||||
|
||||
template<class F, class State=void>
|
||||
struct reverse_compress_adaptor
|
||||
: detail::compressed_pair<F, State>
|
||||
: detail::compressed_pair<detail::callable_base<F>, State>
|
||||
{
|
||||
typedef detail::compressed_pair<F, State> base_type;
|
||||
typedef detail::compressed_pair<detail::callable_base<F>, State> base_type;
|
||||
FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, base_type)
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return this->first(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const State& get_state(Ts&&... xs) const
|
||||
constexpr State get_state(Ts&&... xs) const
|
||||
{
|
||||
return this->second(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_<const F&>, id_<const State&>, id_<Ts>...)
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_<const detail::callable_base<F>&>, id_<State>, id_<Ts>...)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
detail::v_reverse_fold()(
|
||||
FIT_MANGLE_CAST(const F&)(this->base_function(xs...)),
|
||||
FIT_MANGLE_CAST(State&&)(fit::move(this->get_state(xs...))),
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F>&)(this->base_function(xs...)),
|
||||
FIT_MANGLE_CAST(State)(this->get_state(xs...)),
|
||||
fit::forward<Ts>(xs)...
|
||||
)
|
||||
)
|
||||
@@ -128,22 +128,22 @@ struct reverse_compress_adaptor
|
||||
|
||||
template<class F>
|
||||
struct reverse_compress_adaptor<F, void>
|
||||
: F
|
||||
: detail::callable_base<F>
|
||||
{
|
||||
FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, F)
|
||||
FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, detail::callable_base<F>)
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_<const F&>, id_<Ts>...)
|
||||
constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_<const detail::callable_base<F>&>, id_<Ts>...)
|
||||
operator()(Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
detail::v_reverse_fold()(
|
||||
FIT_MANGLE_CAST(const F&)(this->base_function(xs...)),
|
||||
FIT_MANGLE_CAST(const detail::callable_base<F>&)(this->base_function(xs...)),
|
||||
fit::forward<Ts>(xs)...
|
||||
)
|
||||
)
|
||||
|
||||
14
fit/rotate.h
14
fit/rotate.h
@@ -33,7 +33,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -51,13 +51,13 @@
|
||||
namespace fit {
|
||||
|
||||
template<class F>
|
||||
struct rotate_adaptor : F
|
||||
struct rotate_adaptor : detail::callable_base<F>
|
||||
{
|
||||
typedef rotate_adaptor fit_rewritable1_tag;
|
||||
FIT_INHERIT_CONSTRUCTOR(rotate_adaptor, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(rotate_adaptor, detail::callable_base<F>);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -75,16 +75,16 @@ struct rotate_adaptor : F
|
||||
};
|
||||
|
||||
struct failure
|
||||
: failure_map<rotate_failure, F>
|
||||
: failure_map<rotate_failure, detail::callable_base<F>>
|
||||
{};
|
||||
|
||||
FIT_RETURNS_CLASS(rotate_adaptor);
|
||||
|
||||
template<class T, class... Ts>
|
||||
constexpr FIT_SFINAE_RESULT(const F&, id_<Ts>..., id_<T>)
|
||||
constexpr FIT_SFINAE_RESULT(const detail::callable_base<F>&, id_<Ts>..., id_<T>)
|
||||
operator()(T&& x, Ts&&... xs) const FIT_SFINAE_RETURNS
|
||||
(
|
||||
(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)))
|
||||
(FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(xs...)))
|
||||
(fit::forward<Ts>(xs)..., fit::forward<T>(x))
|
||||
);
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [UnaryCallable](concepts.md#unarycallable)
|
||||
///
|
||||
/// Example
|
||||
/// -------
|
||||
@@ -51,6 +51,7 @@
|
||||
///
|
||||
|
||||
#include <fit/pipable.h>
|
||||
#include <fit/apply.h>
|
||||
#include <fit/detail/static_const_var.h>
|
||||
|
||||
namespace fit { namespace detail {
|
||||
@@ -60,7 +61,7 @@ struct tap_f
|
||||
template<class T, class F>
|
||||
constexpr T operator()(T&& x, const F& f) const
|
||||
{
|
||||
return f(x), fit::forward<T>(x);
|
||||
return fit::apply(f, x), fit::forward<T>(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
14
fit/unpack.h
14
fit/unpack.h
@@ -31,7 +31,7 @@
|
||||
///
|
||||
/// F must be:
|
||||
///
|
||||
/// * [FunctionObject](concepts.md#functionobject)
|
||||
/// * [Callable](concepts.md#callable)
|
||||
/// * MoveConstructible
|
||||
///
|
||||
/// Example
|
||||
@@ -172,13 +172,13 @@ struct is_unpackable
|
||||
{};
|
||||
|
||||
template<class F>
|
||||
struct unpack_adaptor : F
|
||||
struct unpack_adaptor : detail::callable_base<F>
|
||||
{
|
||||
typedef unpack_adaptor fit_rewritable1_tag;
|
||||
FIT_INHERIT_CONSTRUCTOR(unpack_adaptor, F);
|
||||
FIT_INHERIT_CONSTRUCTOR(unpack_adaptor, detail::callable_base<F>);
|
||||
|
||||
template<class... Ts>
|
||||
constexpr const F& base_function(Ts&&... xs) const
|
||||
constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
|
||||
{
|
||||
return always_ref(*this)(xs...);
|
||||
}
|
||||
@@ -223,7 +223,7 @@ struct unpack_adaptor : F
|
||||
};
|
||||
|
||||
struct failure
|
||||
: failure_map<unpack_failure, F>
|
||||
: failure_map<unpack_failure, detail::callable_base<F>>
|
||||
{};
|
||||
|
||||
FIT_RETURNS_CLASS(unpack_adaptor);
|
||||
@@ -233,7 +233,7 @@ struct unpack_adaptor : F
|
||||
constexpr auto operator()(T&& x) const
|
||||
FIT_RETURNS
|
||||
(
|
||||
detail::unpack_simple(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(x)), fit::forward<T>(x))
|
||||
detail::unpack_simple(FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(x)), fit::forward<T>(x))
|
||||
);
|
||||
|
||||
template<class T, class... Ts, class=typename std::enable_if<(detail::and_<
|
||||
@@ -241,7 +241,7 @@ struct unpack_adaptor : F
|
||||
>::value)>::type>
|
||||
constexpr auto operator()(T&& x, Ts&&... xs) const FIT_RETURNS
|
||||
(
|
||||
detail::unpack_join(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(x)), fit::forward<T>(x), fit::forward<Ts>(xs)...)
|
||||
detail::unpack_join(FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(x)), fit::forward<T>(x), fit::forward<Ts>(xs)...)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -6,3 +6,57 @@ FIT_TEST_CASE()
|
||||
FIT_STATIC_TEST_CHECK(fit::apply(binary_class(), 1, 2) == 3);
|
||||
FIT_TEST_CHECK(fit::apply(binary_class(), 1, 2) == 3);
|
||||
}
|
||||
|
||||
struct member_sum_f
|
||||
{
|
||||
int i;
|
||||
constexpr member_sum_f(int x) : i(x)
|
||||
{}
|
||||
|
||||
constexpr int add(int x) const
|
||||
{
|
||||
return i+x;
|
||||
}
|
||||
};
|
||||
|
||||
struct member_sum_f_derived
|
||||
: member_sum_f
|
||||
{
|
||||
constexpr member_sum_f_derived(int x) : member_sum_f(x)
|
||||
{}
|
||||
};
|
||||
|
||||
FIT_TEST_CASE()
|
||||
{
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
|
||||
|
||||
#ifdef __clang__
|
||||
FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
|
||||
FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
|
||||
#endif
|
||||
|
||||
static_assert(std::is_base_of<member_sum_f, member_sum_f>::value, "Base of failed");
|
||||
std::unique_ptr<member_sum_f> msp(new member_sum_f(1));
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::add, msp, 2) == 3);
|
||||
|
||||
std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(1));
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::add, mspd, 2) == 3);
|
||||
}
|
||||
|
||||
FIT_TEST_CASE()
|
||||
{
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f(3)) == 3);
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
|
||||
|
||||
#ifdef __clang__
|
||||
FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f(3)) == 3);
|
||||
FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
|
||||
#endif
|
||||
|
||||
std::unique_ptr<member_sum_f> msp(new member_sum_f(3));
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::i, msp) == 3);
|
||||
|
||||
std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(3));
|
||||
FIT_TEST_CHECK(fit::apply(&member_sum_f::i, mspd) == 3);
|
||||
}
|
||||
|
||||
11
test/by.cpp
11
test/by.cpp
@@ -31,6 +31,17 @@ FIT_TEST_CASE()
|
||||
static_assert(fit::detail::is_default_constructible<decltype(fit::by(select_x(), add))>::value, "Not default constructible");
|
||||
}
|
||||
|
||||
FIT_TEST_CASE()
|
||||
{
|
||||
#ifndef _MSC_VER
|
||||
constexpr
|
||||
#endif
|
||||
auto add = fit::_ + fit::_;
|
||||
FIT_STATIC_TEST_CHECK(fit::by(select_x(), add)(foo(1), foo(2)) == 3);
|
||||
FIT_TEST_CHECK(fit::by(&foo::x, add)(foo(1), foo(2)) == 3);
|
||||
static_assert(fit::detail::is_default_constructible<decltype(fit::by(select_x(), add))>::value, "Not default constructible");
|
||||
}
|
||||
|
||||
FIT_TEST_CASE()
|
||||
{
|
||||
auto indirect_add = fit::by(*fit::_, fit::_ + fit::_);
|
||||
|
||||
@@ -25,4 +25,24 @@ FIT_TEST_CASE()
|
||||
|
||||
FIT_STATIC_TEST_CHECK(fit::capture_decay(1)(binary_class())(2) == 3);
|
||||
FIT_TEST_CHECK(fit::capture_decay(1)(binary_class())(2) == 3);
|
||||
}
|
||||
}
|
||||
|
||||
struct add_member
|
||||
{
|
||||
int i;
|
||||
|
||||
add_member(int i) : i(i)
|
||||
{}
|
||||
|
||||
int add(int j) const
|
||||
{
|
||||
return i + j;
|
||||
}
|
||||
};
|
||||
|
||||
FIT_TEST_CASE()
|
||||
{
|
||||
FIT_TEST_CHECK(fit::capture(add_member(1), 2)(&add_member::add)() == 3);
|
||||
FIT_TEST_CHECK(fit::capture(add_member(1))(&add_member::add)(2) == 3);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user