// @} group functors
+ template<typename... _Cond>
+ using _Require = typename enable_if<__and_<_Cond...>::value>::type;
+
+ template<typename... _Types>
+ struct _Pack : integral_constant<size_t, sizeof...(_Types)>
+ { };
+
+ template<typename _From, typename _To, bool = _From::value == _To::value>
+ struct _AllConvertible : false_type
+ { };
+
+ template<typename... _From, typename... _To>
+ struct _AllConvertible<_Pack<_From...>, _Pack<_To...>, true>
+ : __and_<is_convertible<_From, _To>...>
+ { };
+
+ template<typename _Tp1, typename _Tp2>
+ using _NotSame = __not_<is_same<typename std::decay<_Tp1>::type,
+ typename std::decay<_Tp2>::type>>;
+
/**
* Derives from @c unary_function or @c binary_function, or perhaps
* nothing, depending on the number of arguments provided. The
{
typedef _Res (_Class::*_Functor)(_ArgTypes...);
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
_M_call(_Tp&& __object, const volatile _Class *,
- _ArgTypes... __args) const
+ _Args&&... __args) const
{
return (std::forward<_Tp>(__object).*__pmf)
- (std::forward<_ArgTypes>(__args)...);
+ (std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
- _M_call(_Tp&& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
+ { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
+
+ // Require each _Args to be convertible to corresponding _ArgTypes
+ template<typename... _Args>
+ using _RequireValidArgs
+ = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ // Require each _Args to be convertible to corresponding _ArgTypes
+ // and require _Tp is not _Class, _Class& or _Class*
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs2
+ = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ // Require each _Args to be convertible to corresponding _ArgTypes
+ // and require _Tp is _Class or derived from _Class
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs3
+ = _Require<is_base_of<_Class, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
public:
typedef _Res result_type;
explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
// Handle objects
- _Res
- operator()(_Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(_Class& __object, _Args&&... __args) const
+ { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
+
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(_Class&& __object, _Args&&... __args) const
+ {
+ return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
+ }
// Handle pointers
- _Res
- operator()(_Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(_Class* __object, _Args&&... __args) const
+ { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
// Handle smart pointers, references and pointers to derived
- template<typename _Tp>
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs2<_Tp, _Args...>>
_Res
- operator()(_Tp&& __object, _ArgTypes... __args) const
+ operator()(_Tp&& __object, _Args&&... __args) const
{
return _M_call(std::forward<_Tp>(__object), &__object,
- std::forward<_ArgTypes>(__args)...);
+ std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs3<_Tp, _Args...>>
_Res
- operator()(reference_wrapper<_Tp> __ref, _ArgTypes... __args) const
- { return operator()(__ref.get(), std::forward<_ArgTypes>(__args)...); }
+ operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
+ { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
private:
_Functor __pmf;
{
typedef _Res (_Class::*_Functor)(_ArgTypes...) const;
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
_M_call(_Tp&& __object, const volatile _Class *,
- _ArgTypes... __args) const
+ _Args&&... __args) const
{
return (std::forward<_Tp>(__object).*__pmf)
- (std::forward<_ArgTypes>(__args)...);
+ (std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
- _M_call(_Tp&& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
+ { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
+
+ template<typename... _Args>
+ using _RequireValidArgs
+ = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs2
+ = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs3
+ = _Require<is_base_of<_Class, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
public:
typedef _Res result_type;
explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
// Handle objects
- _Res
- operator()(const _Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(const _Class& __object, _Args&&... __args) const
+ { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
+
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(const _Class&& __object, _Args&&... __args) const
+ {
+ return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
+ }
// Handle pointers
- _Res
- operator()(const _Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(const _Class* __object, _Args&&... __args) const
+ { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
// Handle smart pointers, references and pointers to derived
- template<typename _Tp>
- _Res operator()(_Tp&& __object, _ArgTypes... __args) const
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs2<_Tp, _Args...>>
+ _Res operator()(_Tp&& __object, _Args&&... __args) const
{
return _M_call(std::forward<_Tp>(__object), &__object,
- std::forward<_ArgTypes>(__args)...);
+ std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs3<_Tp, _Args...>>
_Res
- operator()(reference_wrapper<_Tp> __ref, _ArgTypes... __args) const
- { return operator()(__ref.get(), std::forward<_ArgTypes>(__args)...); }
+ operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
+ { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
private:
_Functor __pmf;
{
typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile;
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
_M_call(_Tp&& __object, const volatile _Class *,
- _ArgTypes... __args) const
+ _Args&&... __args) const
{
return (std::forward<_Tp>(__object).*__pmf)
- (std::forward<_ArgTypes>(__args)...);
+ (std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
- _M_call(_Tp&& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
+ { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
+
+ template<typename... _Args>
+ using _RequireValidArgs
+ = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs2
+ = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs3
+ = _Require<is_base_of<_Class, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
public:
typedef _Res result_type;
explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
// Handle objects
- _Res
- operator()(volatile _Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(volatile _Class& __object, _Args&&... __args) const
+ { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
+
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(volatile _Class&& __object, _Args&&... __args) const
+ {
+ return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
+ }
// Handle pointers
- _Res
- operator()(volatile _Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(volatile _Class* __object, _Args&&... __args) const
+ { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
// Handle smart pointers, references and pointers to derived
- template<typename _Tp>
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs2<_Tp, _Args...>>
_Res
- operator()(_Tp&& __object, _ArgTypes... __args) const
+ operator()(_Tp&& __object, _Args&&... __args) const
{
return _M_call(std::forward<_Tp>(__object), &__object,
- std::forward<_ArgTypes>(__args)...);
+ std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs3<_Tp, _Args...>>
_Res
- operator()(reference_wrapper<_Tp> __ref, _ArgTypes... __args) const
- { return operator()(__ref.get(), std::forward<_ArgTypes>(__args)...); }
+ operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
+ { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
private:
_Functor __pmf;
{
typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile;
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
_M_call(_Tp&& __object, const volatile _Class *,
- _ArgTypes... __args) const
+ _Args&&... __args) const
{
return (std::forward<_Tp>(__object).*__pmf)
- (std::forward<_ArgTypes>(__args)...);
+ (std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args>
_Res
- _M_call(_Tp&& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
+ { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
+
+ template<typename... _Args>
+ using _RequireValidArgs
+ = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs2
+ = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+
+ template<typename _Tp, typename... _Args>
+ using _RequireValidArgs3
+ = _Require<is_base_of<_Class, _Tp>,
+ _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
public:
typedef _Res result_type;
explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
// Handle objects
- _Res
- operator()(const volatile _Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(const volatile _Class& __object, _Args&&... __args) const
+ { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
+
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(const volatile _Class&& __object, _Args&&... __args) const
+ {
+ return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
+ }
// Handle pointers
- _Res
- operator()(const volatile _Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(std::forward<_ArgTypes>(__args)...); }
+ template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
+ _Res
+ operator()(const volatile _Class* __object, _Args&&... __args) const
+ { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
// Handle smart pointers, references and pointers to derived
- template<typename _Tp>
- _Res operator()(_Tp&& __object, _ArgTypes... __args) const
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs2<_Tp, _Args...>>
+ _Res operator()(_Tp&& __object, _Args&&... __args) const
{
return _M_call(std::forward<_Tp>(__object), &__object,
- std::forward<_ArgTypes>(__args)...);
+ std::forward<_Args>(__args)...);
}
- template<typename _Tp>
+ template<typename _Tp, typename... _Args,
+ typename _Req = _RequireValidArgs3<_Tp, _Args...>>
_Res
- operator()(reference_wrapper<_Tp> __ref, _ArgTypes... __args) const
- { return operator()(__ref.get(), std::forward<_ArgTypes>(__args)...); }
+ operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
+ { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
private:
_Functor __pmf;
// This bit of genius is due to Peter Dimov, improved slightly by
// Douglas Gregor.
- // Made less elegant by Jonathan Wakely to support perfect forwarding.
+ // Made less elegant to support perfect forwarding and noexcept.
template<typename _Tp>
auto
_M_call(_Tp&& __object, const _Class *) const noexcept
{ return __object->*__pm; }
// Handle smart pointers and derived
- template<typename _Tp>
+ template<typename _Tp, typename _Req = _Require<_NotSame<_Class*, _Tp>>>
auto
operator()(_Tp&& __unknown) const
noexcept(noexcept(std::declval<_Mem_fn*>()->_M_call
-> decltype(this->_M_call(std::forward<_Tp>(__unknown), &__unknown))
{ return _M_call(std::forward<_Tp>(__unknown), &__unknown); }
- template<typename _Tp>
+ template<typename _Tp, typename _Req = _Require<is_base_of<_Class, _Tp>>>
auto
operator()(reference_wrapper<_Tp> __ref) const
noexcept(noexcept(std::declval<_Mem_fn&>()(__ref.get())))
-> decltype((*this)(__ref.get()))
- { return operator()(__ref.get()); }
+ { return (*this)(__ref.get()); }
private:
_Res _Class::*__pm;