summaryrefslogtreecommitdiff
path: root/boost/functional/forward_adapter.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/functional/forward_adapter.hpp')
-rw-r--r--boost/functional/forward_adapter.hpp33
1 files changed, 31 insertions, 2 deletions
diff --git a/boost/functional/forward_adapter.hpp b/boost/functional/forward_adapter.hpp
index 796abd2bc4..6023fc2ae5 100644
--- a/boost/functional/forward_adapter.hpp
+++ b/boost/functional/forward_adapter.hpp
@@ -144,8 +144,30 @@ namespace boost
: boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
{ };
- template< class MD, class F, class FC >
- struct forward_adapter_impl<MD,F,FC,0,0>
+ // 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_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