{ return type(__pm); }
};
+ // Specialization needed to prevent "forming reference to void" errors when
+ // bind<void>() is called, because argument deduction instantiates
+ // _Maybe_wrap_member_pointer<void> outside the immediate context where
+ // SFINAE applies.
+ template<>
+ struct _Maybe_wrap_member_pointer<void>
+ {
+ typedef void type;
+ };
+
/// Type of the function object returned from bind().
template<typename _Signature>
struct _Bind;
_Functor _M_f;
tuple<_Bound_args...> _M_bound_args;
+ // sfinae types
+ template<typename _Res>
+ struct __enable_if_void : enable_if<is_void<_Res>::value, int> { };
+ template<typename _Res>
+ struct __disable_if_void : enable_if<!is_void<_Res>::value, int> { };
+
// Call unqualified
- template<typename... _Args, int... _Indexes>
+ template<typename _Res, typename... _Args, int... _Indexes>
_Result
- __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>,
+ typename __disable_if_void<_Res>::type = 0)
{
return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...);
}
+ // Call unqualified, return void
+ template<typename _Res, typename... _Args, int... _Indexes>
+ void
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>,
+ typename __enable_if_void<_Res>::type = 0)
+ {
+ _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
// Call as const
- template<typename... _Args, int... _Indexes>
+ template<typename _Res, typename... _Args, int... _Indexes>
_Result
- __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>,
+ typename __disable_if_void<_Res>::type = 0) const
{
return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...);
}
+ // Call as const, return void
+ template<typename _Res, typename... _Args, int... _Indexes>
+ void
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>,
+ typename __enable_if_void<_Res>::type = 0) const
+ {
+ _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
// Call as volatile
- template<typename... _Args, int... _Indexes>
+ template<typename _Res, typename... _Args, int... _Indexes>
_Result
- __call(const tuple<_Args...>& __args,
- _Index_tuple<_Indexes...>) volatile
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>,
+ typename __disable_if_void<_Res>::type = 0) volatile
{
return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...);
}
+ // Call as volatile, return void
+ template<typename _Res, typename... _Args, int... _Indexes>
+ void
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>,
+ typename __enable_if_void<_Res>::type = 0) volatile
+ {
+ _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
// Call as const volatile
- template<typename... _Args, int... _Indexes>
+ template<typename _Res, typename... _Args, int... _Indexes>
_Result
- __call(const tuple<_Args...>& __args,
- _Index_tuple<_Indexes...>) const volatile
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>,
+ typename __disable_if_void<_Res>::type = 0) const volatile
{
return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...);
}
+ // Call as const volatile, return void
+ template<typename _Res, typename... _Args, int... _Indexes>
+ void
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>,
+ typename __enable_if_void<_Res>::type = 0) const volatile
+ {
+ _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
public:
typedef _Result result_type;
result_type
operator()(_Args&... __args)
{
- return this->__call(tie(__args...), _Bound_indexes());
+ return this->__call<_Result>(tie(__args...), _Bound_indexes());
}
// Call as const
result_type
operator()(_Args&... __args) const
{
- return this->__call(tie(__args...), _Bound_indexes());
+ return this->__call<_Result>(tie(__args...), _Bound_indexes());
}
// Call as volatile
result_type
operator()(_Args&... __args) volatile
{
- return this->__call(tie(__args...), _Bound_indexes());
+ return this->__call<_Result>(tie(__args...), _Bound_indexes());
}
// Call as const volatile
result_type
operator()(_Args&... __args) const volatile
{
- return this->__call(tie(__args...), _Bound_indexes());
+ return this->__call<_Result>(tie(__args...), _Bound_indexes());
}
};
--- /dev/null
+// { dg-options "-std=gnu++0x" }
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 20.7.11 Function template bind
+
+#include <functional>
+#include <testsuite_hooks.h>
+
+struct X
+{
+ typedef int result_type;
+ int operator()(int i) const { return i+1; }
+ bool b;
+};
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ using std::bind;
+ using std::ref;
+ ::X x = { true };
+
+ // test bind<R> form
+ bind<void>(ref(x), 1)();
+ VERIFY( bind<long>(ref(x), 1)() == 2 );
+ bind<void>(&::X::b, ref(x))();
+ VERIFY( bind<int>(&::X::b, ref(x))() == 1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}