Skip to content

Commit

Permalink
Add support for using reference_wrapper with member pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
pfultz2 committed Jun 25, 2016
1 parent cae0591 commit bbdd63b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
26 changes: 26 additions & 0 deletions include/fit/apply.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,15 @@ struct apply_f
apply_mem_fn()(f, *FIT_FORWARD(T)(obj), FIT_FORWARD(Ts)(xs)...)
);

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, const std::reference_wrapper<T>& ref, Ts&&... xs) const FIT_SFINAE_MANUAL_RETURNS
(
apply_mem_fn()(f, ref.get(), 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>
Expand All @@ -184,6 +193,15 @@ struct apply_f
(
apply_mem_data()(f, *FIT_FORWARD(T)(obj))
);

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, const std::reference_wrapper<T>& ref) const FIT_SFINAE_MANUAL_RETURNS
(
apply_mem_data()(f, ref.get())
);

#else

Expand All @@ -194,6 +212,10 @@ struct apply_f
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>
constexpr auto operator()(T Base::*pmd, const std::reference_wrapper<Derived>& ref) const
FIT_RETURNS(ref.get().*pmd);

template <class Base, class T, class Derived, class... Args>
constexpr auto operator()(T Base::*pmf, Derived&& ref, Args&&... args) const
Expand All @@ -203,6 +225,10 @@ struct apply_f
constexpr auto operator()(PMF&& pmf, Pointer&& ptr, Args&&... args) const
FIT_RETURNS(((*FIT_FORWARD(Pointer)(ptr)).*FIT_FORWARD(PMF)(pmf))(FIT_FORWARD(Args)(args)...));

template <class Base, class T, class Derived, class... Args>
constexpr auto operator()(T Base::*pmf, const std::reference_wrapper<Derived>& ref, Args&&... args) const
FIT_RETURNS((ref.get().*pmf)(FIT_FORWARD(Args)(args)...));

#endif
template<class F, class... Ts>
constexpr FIT_SFINAE_RESULT(F, id_<Ts>...)
Expand Down
22 changes: 22 additions & 0 deletions test/apply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,25 @@ FIT_TEST_CASE()
FIT_TEST_CHECK( fit::apply( &dm_t::m, pcx ) == 603 );

}


struct X_ref
{
int f()
{
return 1;
}

int g() const
{
return 2;
}
};

FIT_TEST_CASE()
{
X_ref x;

FIT_TEST_CHECK( fit::apply( &X_ref::f, std::ref( x ) ) == 1 );
FIT_TEST_CHECK( fit::apply( &X_ref::g, std::cref( x ) ) == 2 );
}

0 comments on commit bbdd63b

Please sign in to comment.