Skip to content

Commit

Permalink
Merge branch 'conditional' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
pfultz2 committed Mar 26, 2016
2 parents 5aa5211 + 4f9fd6b commit 1a9b1ec
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 14 deletions.
66 changes: 59 additions & 7 deletions include/fit/conditional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
/// to how the function is chosen.

#include <fit/reveal.hpp>
#include <fit/detail/compressed_pair.hpp>
#include <fit/detail/callable_base.hpp>
#include <fit/detail/delegate.hpp>
#include <fit/detail/join.hpp>
Expand All @@ -86,22 +87,22 @@ namespace fit {
namespace detail {

template<class F1, class F2>
struct conditional_kernel : F1, F2
struct basic_conditional_adaptor : F1, F2
{
FIT_INHERIT_DEFAULT(conditional_kernel, F1, F2)
FIT_INHERIT_DEFAULT(basic_conditional_adaptor, F1, F2)

template<class A, class B,
FIT_ENABLE_IF_CONVERTIBLE(A, F1),
FIT_ENABLE_IF_CONVERTIBLE(B, F2)>
constexpr conditional_kernel(A&& f1, B&& f2) : F1(FIT_FORWARD(A)(f1)), F2(FIT_FORWARD(B)(f2))
constexpr basic_conditional_adaptor(A&& f1, B&& f2) : F1(FIT_FORWARD(A)(f1)), F2(FIT_FORWARD(B)(f2))
{}

template<class X,
class=typename std::enable_if<
FIT_IS_CONVERTIBLE(X, F1) &&
FIT_IS_DEFAULT_CONSTRUCTIBLE(F2)
>::type>
constexpr conditional_kernel(X&& x) : F1(FIT_FORWARD(X)(x))
constexpr basic_conditional_adaptor(X&& x) : F1(FIT_FORWARD(X)(x))
{}

template<class... Ts>
Expand All @@ -114,14 +115,65 @@ struct conditional_kernel : F1, F2
>
{};

FIT_RETURNS_CLASS(conditional_kernel);
FIT_RETURNS_CLASS(basic_conditional_adaptor);

template<class... Ts, class F=typename select<Ts...>::type>
constexpr FIT_SFINAE_RESULT(typename select<Ts...>::type, id_<Ts>...)
operator()(Ts && ... x) const
operator()(Ts && ... xs) const
FIT_SFINAE_RETURNS
(
FIT_RETURNS_STATIC_CAST(const F&)(*FIT_CONST_THIS)(FIT_FORWARD(Ts)(xs)...)
);
};

struct low_rank {};

struct high_rank : low_rank {};

template <class ...Ts, class F1, class F2, class = typename std::enable_if<(
is_callable<F1, Ts...>::value
)>::type>
constexpr F1&& which(high_rank, holder<Ts...>, F1&& f1, F2&&)
{
return FIT_FORWARD(F1)(f1);
}

template <class ...Ts, class F1, class F2>
constexpr F2&& which(low_rank, holder<Ts...>, F1&&, F2&& f2)
{
return FIT_FORWARD(F2)(f2);
}

template<class F1, class F2>
struct conditional_kernel : compressed_pair<F1, F2>
{
typedef compressed_pair<F1, F2> base;
FIT_INHERIT_CONSTRUCTOR(conditional_kernel, base)

template<class... Ts>
struct select
: std::conditional
<
is_callable<F1, Ts...>::value,
F1,
F2
>
{};

FIT_RETURNS_CLASS(conditional_kernel);

template<class... Ts>
constexpr FIT_SFINAE_RESULT(typename select<Ts...>::type, id_<Ts>...)
operator()(Ts && ... xs) const
FIT_SFINAE_RETURNS
(
FIT_RETURNS_STATIC_CAST(const F&)(*FIT_CONST_THIS)(FIT_FORWARD(Ts)(x)...)
detail::which(
high_rank{},
holder<Ts...>{},
FIT_CONST_THIS->first(xs...),
FIT_CONST_THIS->second(xs...)
)
(FIT_FORWARD(Ts)(xs)...)
);
};
}
Expand Down
6 changes: 3 additions & 3 deletions include/fit/detail/compressed_pair.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,21 @@ struct compressed_pair<First, Second>
FIT_INHERIT_DEFAULT(compressed_pair, first_base, second_base)

template<class Base, class... Xs>
constexpr const Base& get_base(Xs&&... xs) const
constexpr const Base& get_alias_base(Xs&&... xs) const
{
return always_ref(*this)(xs...);
}

template<class... Xs>
constexpr const First& first(Xs&&... xs) const
{
return alias_value(this->get_base<first_base>(xs...), xs...);
return alias_value(this->get_alias_base<first_base>(xs...), xs...);
}

template<class... Xs>
constexpr const Second& second(Xs&&... xs) const
{
return alias_value(this->get_base<second_base>(xs...), xs...);
return alias_value(this->get_alias_base<second_base>(xs...), xs...);
}

};
Expand Down
4 changes: 2 additions & 2 deletions include/fit/partial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ struct partial_adaptor_pack
template<class F, class Pack>
struct partial_adaptor_base
{
typedef conditional_adaptor
typedef basic_conditional_adaptor
<
partial_adaptor_invoke<partial_adaptor<F, Pack>, F, Pack>,
partial_adaptor_join<partial_adaptor<F, Pack>, F, Pack>
Expand All @@ -186,7 +186,7 @@ struct partial_adaptor_base
template<class Derived, class F>
struct partial_adaptor_pack_base
{
typedef conditional_adaptor
typedef basic_conditional_adaptor
<
F,
partial_adaptor_pack<Derived, F>
Expand Down
4 changes: 2 additions & 2 deletions include/fit/pipable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ constexpr auto operator|(A&& a, const pipe_closure<F, Pack>& p) FIT_RETURNS

template<class F>
struct pipable_adaptor
: conditional_adaptor<detail::callable_base<F>, detail::pipe_pack<pipable_adaptor<F>, detail::callable_base<F>> >
: detail::basic_conditional_adaptor<detail::callable_base<F>, detail::pipe_pack<pipable_adaptor<F>, detail::callable_base<F>> >
{
typedef conditional_adaptor<detail::callable_base<F>, detail::pipe_pack<pipable_adaptor<F>, detail::callable_base<F>> > base;
typedef detail::basic_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);
Expand Down
5 changes: 5 additions & 0 deletions test/conditional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,9 @@ FIT_TEST_CASE()
FIT_TEST_CHECK(static_fun(t3()) == 3);
}
#endif

FIT_TEST_CASE()
{
FIT_TEST_CHECK(fit::conditional(fit::identity, fit::identity)(3) == 3);
}
}

0 comments on commit 1a9b1ec

Please sign in to comment.