Merge pull request #5 from danieljames/feature/forward-fixes

Feature/forward fixes
This commit is contained in:
Daniel James
2016-05-27 09:54:33 +01:00
4 changed files with 78 additions and 6 deletions

View File

@@ -44,6 +44,10 @@ public:
{
return -(l=r+val);
}
char operator()(int& l, int& r)
{
return l=r+val;
}
template <typename Sig>
struct result
@@ -89,8 +93,11 @@ int main()
// lvalue,lvalue
BOOST_TEST(( is_same<
result_of< f(int&, int&) >::type, char >::value ));
// result_of works differently for C++11 here, so compare
// with using it against test_func.
BOOST_TEST(( is_same<
result_of< f const (int&, int&) >::type, char >::value ));
result_of< f const (int&, int&) >::type,
result_of< test_func<> const (int&, int&)>::type >::value ));
}
{

View File

@@ -44,6 +44,10 @@ public:
{
return -(l=r+val);
}
char operator()(int & l, int & r)
{
return l=r+val;
}
template <typename Sig>
struct result
@@ -91,8 +95,11 @@ int main()
// lvalue,lvalue
BOOST_TEST(( is_same<
result_of< f(ref, ref) >::type, char >::value ));
// result_of works differently for C++11 here, so compare
// with using it against test_func.
BOOST_TEST(( is_same<
result_of< f const (ref, ref) >::type, char >::value ));
result_of< f const (ref, ref) >::type,
result_of< test_func<> const (int&, int&) >::type >::value ));
}
{
using boost::noncopyable;

View File

@@ -144,8 +144,30 @@ namespace boost
: boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
{ };
// WHen operator()() doesn't have any parameters, it can't
// be templatized and can't use SFINAE, so intead use class
// template parameter SFINAE to decide whether to instantiate it.
template <typename T, typename R = void>
struct forward_adapter_sfinae
{
typedef T type;
};
// This is the fallback for when there isn't an operator()(),
// need to create an operator() that will never instantiate
// so that using parent::operator() will work okay.
template< class MD, class F, class FC, class Enable = void>
struct forward_adapter_impl_zero
{
template <typename T> struct never_instantiate {};
template <typename T>
typename never_instantiate<T>::type operator()(T) const {}
};
template< class MD, class F, class FC>
struct forward_adapter_impl<MD,F,FC,0,0>
struct forward_adapter_impl_zero<MD, F, FC,
typename forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
{
inline typename boost::result_of< FC() >::type
operator()() const
@@ -158,6 +180,13 @@ namespace boost
{
return static_cast<MD*>(this)->target_function()();
}
};
template< class MD, class F, class FC >
struct forward_adapter_impl<MD,F,FC,0,0>
: forward_adapter_impl_zero<MD,F,FC>
{
using forward_adapter_impl_zero<MD,F,FC>::operator();
// closing brace gets generated by preprocessing code, below

View File

@@ -149,8 +149,31 @@ namespace boost
: boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
{ };
// When operator() doesn't have any parameters, it can't
// be templatized and can't use SFINAE, so intead use class
// template parameter SFINAE to decide whether to instantiate it.
template <typename T, typename R = void>
struct lightweight_forward_adapter_sfinae
{
typedef T type;
};
// This is the fallback for when there isn't an operator()(),
// need to create an operator() that will never instantiate
// so that using parent::operator() will work okay.
template< class MD, class F, class FC, class Enable = void>
struct lightweight_forward_adapter_impl_zero
: lightweight_forward_adapter_result
{
template <typename T> struct never_instantiate {};
template <typename T>
typename never_instantiate<T>::type operator()(T) const {}
};
template< class MD, class F, class FC>
struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
struct lightweight_forward_adapter_impl_zero<MD, F, FC,
typename lightweight_forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
: lightweight_forward_adapter_result
{
inline typename boost::result_of< FC() >::type
@@ -166,6 +189,12 @@ namespace boost
}
};
template< class MD, class F, class FC >
struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
: lightweight_forward_adapter_impl_zero<MD,F,FC>
{
};
# define BOOST_PP_FILENAME_1 \
<boost/functional/lightweight_forward_adapter.hpp>
# define BOOST_PP_ITERATION_LIMITS \