diff options
Diffstat (limited to 'libstdc++-v3/include/tr1/functional')
-rw-r--r-- | libstdc++-v3/include/tr1/functional | 1233 |
1 files changed, 1198 insertions, 35 deletions
diff --git a/libstdc++-v3/include/tr1/functional b/libstdc++-v3/include/tr1/functional index f3cc78de751..897d48751ff 100644 --- a/libstdc++-v3/include/tr1/functional +++ b/libstdc++-v3/include/tr1/functional @@ -36,16 +36,18 @@ #pragma GCC system_header -#include "../functional" +#include <cstdlib> // for std::abort +#include <cmath> // for std::frexp +#include <string> // for std::tr1::hash +#include <functional> #include <typeinfo> +#include <tr1/tuple> #include <tr1/type_traits> #include <ext/type_traits.h> -#include <cstdlib> // for std::abort -#include <tr1/tuple> namespace std { -_GLIBCXX_BEGIN_NAMESPACE(tr1) +_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1) template<typename _MemberPointer> class _Mem_fn; @@ -109,6 +111,83 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) }; /** + * @if maint + * Retrieve the result type for a function type. + * @endif + */ + template<typename _Res, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /** + * @if maint + * Retrieve the result type for a function reference. + * @endif + */ + template<typename _Res, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /** + * @if maint + * Retrieve the result type for a function pointer. + * @endif + */ + template<typename _Res, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /** + * @if maint + * Retrieve result type for a member function pointer. + * @endif maint + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /** + * @if maint + * Retrieve result type for a const member function pointer. + * @endif maint + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const> + { + typedef _Res result_type; + }; + + /** + * @if maint + * Retrieve result type for a volatile member function pointer. + * @endif maint + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile> + { + typedef _Res result_type; + }; + + /** + * @if maint + * Retrieve result type for a const volatile member function pointer. + * @endif maint + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)const volatile> + { + typedef _Res result_type; + }; + + /** * @if maint * Strip top-level cv-qualifiers from the function object and let * _Weak_result_type_impl perform the real work. @@ -143,6 +222,56 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) }; /** + * @if maint + * Determine whether we can determine a result type from @c Functor + * alone. + * @endif + */ + template<typename _Functor, typename... _ArgTypes> + class result_of<_Functor(_ArgTypes...)> + : public _Result_of_impl< + _Has_result_type<_Weak_result_type<_Functor> >::value, + _Functor(_ArgTypes...)> + { + }; + + /** + * @if maint + * We already know the result type for @c Functor; use it. + * @endif + */ + template<typename _Functor, typename... _ArgTypes> + struct _Result_of_impl<true, _Functor(_ArgTypes...)> + { + typedef typename _Weak_result_type<_Functor>::result_type type; + }; + + /** + * @if maint + * We need to compute the result type for this invocation the hard + * way. + * @endif + */ + template<typename _Functor, typename... _ArgTypes> + struct _Result_of_impl<false, _Functor(_ArgTypes...)> + { + typedef typename _Functor + ::template result<_Functor(_ArgTypes...)>::type type; + }; + + /** + * @if maint + * It is unsafe to access ::result when there are zero arguments, so we + * return @c void instead. + * @endif + */ + template<typename _Functor> + struct _Result_of_impl<false, _Functor()> + { + typedef void type; + }; + + /** * @if maint * Determines if the type _Tp derives from unary_function. * @endif @@ -200,6 +329,51 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) }; /** + * @if maint + * Invoke a function object, which may be either a member pointer or a + * function object. The first parameter will tell which. + * @endif + */ + template<typename _Functor, typename... _Args> + inline + typename __gnu_cxx::__enable_if< + (!is_member_pointer<_Functor>::value + && !is_function<_Functor>::value + && !is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_Args...)>::type + >::__type + __invoke(_Functor& __f, _Args&... __args) + { + return __f(__args...); + } + + template<typename _Functor, typename... _Args> + inline + typename __gnu_cxx::__enable_if< + (is_member_pointer<_Functor>::value + && !is_function<_Functor>::value + && !is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_Args...)>::type + >::__type + __invoke(_Functor& __f, _Args&... __args) + { + return mem_fn(__f)(__args...); + } + + // To pick up function references (that will become function pointers) + template<typename _Functor, typename... _Args> + inline + typename __gnu_cxx::__enable_if< + (is_pointer<_Functor>::value + && is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_Args...)>::type + >::__type + __invoke(_Functor __f, _Args&... __args) + { + return __f(__args...); + } + + /** * @if maint * Knowing which of unary_function and binary_function _Tp derives * from, derives from the same and ensures that reference_wrapper @@ -364,9 +538,12 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) get() const { return *_M_data; } -#define _GLIBCXX_REPEAT_HEADER <tr1/ref_wrap_iterate.h> -#include <tr1/repeat.h> -#undef _GLIBCXX_REPEAT_HEADER + template<typename... _Args> + typename result_of<_M_func_type(_Args...)>::type + operator()(_Args&... __args) const + { + return __invoke(get(), __args...); + } }; @@ -404,6 +581,216 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) typedef _Tp& type; }; + /** + * @if maint + * Derives from @c unary_function or @c binary_function, or perhaps + * nothing, depending on the number of arguments provided. The + * primary template is the basis case, which derives nothing. + * @endif maint + */ + template<typename _Res, typename... _ArgTypes> + struct _Maybe_unary_or_binary_function { }; + + /** + * @if maint + * Derives from @c unary_function, as appropriate. + * @endif + */ + template<typename _Res, typename _T1> + struct _Maybe_unary_or_binary_function<_Res, _T1> + : std::unary_function<_T1, _Res> { }; + + /** + * @if maint + * Derives from @c binary_function, as appropriate. + * @endif + */ + template<typename _Res, typename _T1, typename _T2> + struct _Maybe_unary_or_binary_function<_Res, _T1, _T2> + : std::binary_function<_T1, _T2, _Res> { }; + + /** + * @if maint + * Implementation of @c mem_fn for member function pointers. + * @endif + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...)> + : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...); + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { } + + // Handle objects + _Res operator()(_Class& __object, _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + // Handle pointers + _Res operator()(_Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + /** + * @if maint + * Implementation of @c mem_fn for const member function pointers. + * @endif + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const> + : public _Maybe_unary_or_binary_function<_Res, const _Class*, + _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...) const; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + 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)(__args...); } + + // Handle pointers + _Res operator()(const _Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + /** + * @if maint + * Implementation of @c mem_fn for volatile member function pointers. + * @endif + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile> + : public _Maybe_unary_or_binary_function<_Res, volatile _Class*, + _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + 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)(__args...); } + + // Handle pointers + _Res operator()(volatile _Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + /** + * @if maint + * Implementation of @c mem_fn for const volatile member function pointers. + * @endif + */ + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile> + : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*, + _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + 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)(__args...); } + + // Handle pointers + _Res + operator()(const volatile _Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + template<typename _Res, typename _Class> class _Mem_fn<_Res _Class::*> { @@ -535,6 +922,41 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) */ template<int _Num> struct _Placeholder { }; + // Define a large number of placeholders. There is no way to + // simplify this with variadic templates, because we're introducing + // unique names for each. + namespace placeholders { namespace { + _Placeholder<1> _1; + _Placeholder<2> _2; + _Placeholder<3> _3; + _Placeholder<4> _4; + _Placeholder<5> _5; + _Placeholder<6> _6; + _Placeholder<7> _7; + _Placeholder<8> _8; + _Placeholder<9> _9; + _Placeholder<10> _10; + _Placeholder<11> _11; + _Placeholder<12> _12; + _Placeholder<13> _13; + _Placeholder<14> _14; + _Placeholder<15> _15; + _Placeholder<16> _16; + _Placeholder<17> _17; + _Placeholder<18> _18; + _Placeholder<19> _19; + _Placeholder<20> _20; + _Placeholder<21> _21; + _Placeholder<22> _22; + _Placeholder<23> _23; + _Placeholder<24> _24; + _Placeholder<25> _25; + _Placeholder<26> _26; + _Placeholder<27> _27; + _Placeholder<28> _28; + _Placeholder<29> _29; + } } + /** * @if maint * Partial specialization of is_placeholder that provides the placeholder @@ -549,6 +971,79 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) const int is_placeholder<_Placeholder<_Num> >::value; /** + * @if maint + * Stores a tuple of indices. Used by bind() to extract the elements + * in a tuple. + * @endif + */ + template<int... Indexes> + struct _Index_tuple { }; + + /** + * @if maint + * Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. + * @endif + */ + template<std::size_t _Num, typename _Tuple = _Index_tuple<> > + struct _Build_index_tuple; + + template<std::size_t _Num, int... _Indexes> + struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> > + : _Build_index_tuple<_Num - 1, + _Index_tuple<_Indexes..., sizeof...(_Indexes)> > + { + }; + + template<int... _Indexes> + struct _Build_index_tuple<0, _Index_tuple<_Indexes...> > + { + typedef _Index_tuple<_Indexes...> __type; + }; + + /** + * @if maint + * Used by _Safe_tuple_element to indicate that there is no tuple + * element at this position. + * @endif + */ + struct _No_tuple_element; + + /** + * @if maint + * Implementation helper for _Safe_tuple_element. This primary + * template handles the case where it is safe to use @c + * tuple_element. + * @endif + */ + template<int __i, typename _Tuple, bool _IsSafe> + struct _Safe_tuple_element_impl + : tuple_element<__i, _Tuple> { }; + + /** + * @if maint + * Implementation helper for _Safe_tuple_element. This partial + * specialization handles the case where it is not safe to use @c + * tuple_element. We just return @c _No_tuple_element. + * @endif + */ + template<int __i, typename _Tuple> + struct _Safe_tuple_element_impl<__i, _Tuple, false> + { + typedef _No_tuple_element type; + }; + + /** + * Like tuple_element, but returns @c _No_tuple_element when + * tuple_element would return an error. + */ + template<int __i, typename _Tuple> + struct _Safe_tuple_element + : _Safe_tuple_element_impl<__i, _Tuple, + (__i >= 0 && __i < tuple_size<_Tuple>::value)> + { + }; + + /** * @if maint * Maps an argument to bind() into an actual argument to the bound * function object [TR1 3.6.3/5]. Only the first parameter should @@ -601,9 +1096,33 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) public: template<typename _Signature> class result; -#define _GLIBCXX_REPEAT_HEADER <tr1/mu_iterate.h> -# include <tr1/repeat.h> -#undef _GLIBCXX_REPEAT_HEADER + // Determine the result type when we pass the arguments along. This + // involves passing along the cv-qualifiers placed on _Mu and + // unwrapping the argument bundle. + template<typename _CVMu, typename _CVArg, typename... _Args> + class result<_CVMu(_CVArg, tuple<_Args...>)> + : public result_of<_CVArg(_Args...)> { }; + + template<typename _CVArg, typename... _Args> + typename result_of<_CVArg(_Args...)>::type + operator()(_CVArg& __arg, const tuple<_Args...>& __tuple) + const volatile + { + // Construct an index tuple and forward to __call + typedef typename _Build_index_tuple<sizeof...(_Args)>::__type _Indexes; + return this->__call(__arg, __tuple, _Indexes()); + } + + private: + // Invokes the underlying function object __arg by unpacking all + // of the arguments in the tuple. + template<typename _CVArg, typename... _Args, int... _Indexes> + typename result_of<_CVArg(_Args...)>::type + __call(_CVArg& __arg, const tuple<_Args...>& __tuple, + const _Index_tuple<_Indexes...>&) const volatile + { + return __arg(_GLIBCXX_TR1::get<_Indexes>(__tuple)...); + } }; /** @@ -625,8 +1144,8 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) // Add a reference, if it hasn't already been done for us. // This allows us to be a little bit sloppy in constructing // the tuple that we pass to result_of<...>. - typedef typename tuple_element<(is_placeholder<_Arg>::value - 1), - _Tuple>::type __base_type; + typedef typename _Safe_tuple_element<(is_placeholder<_Arg>::value - 1), + _Tuple>::type __base_type; public: typedef typename add_reference<__base_type>::type type; @@ -636,7 +1155,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) typename result<_Mu(_Arg, _Tuple)>::type operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile { - return ::std::tr1::get<(is_placeholder<_Arg>::value - 1)>(__tuple); + return ::std::_GLIBCXX_TR1::get<(is_placeholder<_Arg>::value - 1)>(__tuple); } }; @@ -698,23 +1217,226 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) * Type of the function object returned from bind(). * @endif */ - template<typename _Signature> - struct _Bind; + template<typename _Signature> + struct _Bind; + + template<typename _Functor, typename... _Bound_args> + class _Bind<_Functor(_Bound_args...)> + : public _Weak_result_type<_Functor> + { + typedef _Bind __self_type; + typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type + _Bound_indexes; + + _Functor _M_f; + tuple<_Bound_args...> _M_bound_args; + + // Call unqualified + template<typename... _Args, int... _Indexes> + typename result_of< + _Functor(typename result_of<_Mu<_Bound_args> + (_Bound_args, tuple<_Args...>)>::type...) + >::type + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const + template<typename... _Args, int... _Indexes> + typename result_of< + const _Functor(typename result_of<_Mu<_Bound_args> + (const _Bound_args, tuple<_Args...>) + >::type...)>::type + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as volatile + template<typename... _Args, int... _Indexes> + typename result_of< + volatile _Functor(typename result_of<_Mu<_Bound_args> + (volatile _Bound_args, tuple<_Args...>) + >::type...)>::type + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) volatile + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const volatile + template<typename... _Args, int... _Indexes> + typename result_of< + const volatile _Functor(typename result_of<_Mu<_Bound_args> + (const volatile _Bound_args, + tuple<_Args...>) + >::type...)>::type + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) const volatile + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + public: + explicit _Bind(_Functor __f, _Bound_args... __bound_args) + : _M_f(__f), _M_bound_args(__bound_args...) { } + + // Call unqualified + template<typename... _Args> + typename result_of< + _Functor(typename result_of<_Mu<_Bound_args> + (_Bound_args, tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + + // Call as const + template<typename... _Args> + typename result_of< + const _Functor(typename result_of<_Mu<_Bound_args> + (const _Bound_args, tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) const + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + + + // Call as volatile + template<typename... _Args> + typename result_of< + volatile _Functor(typename result_of<_Mu<_Bound_args> + (volatile _Bound_args, tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) volatile + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + + + // Call as const volatile + template<typename... _Args> + typename result_of< + const volatile _Functor(typename result_of<_Mu<_Bound_args> + (const volatile _Bound_args, + tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) const volatile + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + }; /** * @if maint * Type of the function object returned from bind<R>(). * @endif */ - template<typename _Result, typename _Signature> - struct _Bind_result; + template<typename _Result, typename _Signature> + struct _Bind_result; + + template<typename _Result, typename _Functor, typename... _Bound_args> + class _Bind_result<_Result, _Functor(_Bound_args...)> + { + typedef _Bind_result __self_type; + typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type + _Bound_indexes; + + _Functor _M_f; + tuple<_Bound_args...> _M_bound_args; + + // Call unqualified + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as volatile + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) volatile + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const volatile + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) const volatile + { + return _M_f(_Mu<_Bound_args>() + (_GLIBCXX_TR1::get<_Indexes>(_M_bound_args), __args)...); + } + + public: + typedef _Result result_type; + + explicit _Bind_result(_Functor __f, _Bound_args... __bound_args) + : _M_f(__f), _M_bound_args(__bound_args...) { } + + // Call unqualified + template<typename... _Args> + result_type + operator()(_Args&... __args) + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + + // Call as const + template<typename... _Args> + result_type + operator()(_Args&... __args) const + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + + + // Call as volatile + template<typename... _Args> + result_type + operator()(_Args&... __args) volatile + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + + + // Call as const volatile + template<typename... _Args> + result_type + operator()(_Args&... __args) const volatile + { + return this->__call(_GLIBCXX_TR1::tie(__args...), _Bound_indexes()); + } + }; /** * @if maint * Class template _Bind is always a bind expression. * @endif */ - template<typename _Signature> + template<typename _Signature> struct is_bind_expression<_Bind<_Signature> > { static const bool value = true; }; @@ -726,9 +1448,36 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) * Class template _Bind_result is always a bind expression. * @endif */ - template<typename _Result, typename _Signature> - struct is_bind_expression<_Bind_result<_Result, _Signature> > - { static const bool value = true; }; + template<typename _Result, typename _Signature> + struct is_bind_expression<_Bind_result<_Result, _Signature> > + { + static const bool value = true; + }; + + template<typename _Functor, typename... _ArgTypes> + inline + _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type(_ArgTypes...)> + bind(_Functor __f, _ArgTypes... __args) + { + typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type; + typedef typename __maybe_type::type __functor_type; + typedef _Bind<__functor_type(_ArgTypes...)> __result_type; + return __result_type(__maybe_type::__do_wrap(__f), __args...); + } + + template<typename _Result, typename _Functor, typename... _ArgTypes> + inline + _Bind_result<_Result, + typename _Maybe_wrap_member_pointer<_Functor>::type + (_ArgTypes...)> + bind(_Functor __f, _ArgTypes... __args) + { + typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type; + typedef typename __maybe_type::type __functor_type; + typedef _Bind_result<_Result, __functor_type(_ArgTypes...)> + __result_type; + return __result_type(__maybe_type::__do_wrap(__f), __args...); + } template<typename _Result, typename _Signature> const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value; @@ -827,13 +1576,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) __callable_functor(_Member _Class::* const &__p) { return mem_fn(__p); } - template<typename _Signature, typename _Functor> - class _Function_handler; - template<typename _Signature> class function; - /** * @if maint * Base class of all polymorphic function object wrappers. @@ -1024,6 +1769,434 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) _Manager_type _M_manager; }; + template<typename _Signature, typename _Functor> + class _Function_handler; + + template<typename _Res, typename _Functor, typename... _ArgTypes> + class _Function_handler<_Res(_ArgTypes...), _Functor> + : public _Function_base::_Base_manager<_Functor> + { + typedef _Function_base::_Base_manager<_Functor> _Base; + + public: + static _Res _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + return (*_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Functor, typename... _ArgTypes> + class _Function_handler<void(_ArgTypes...), _Functor> + : public _Function_base::_Base_manager<_Functor> + { + typedef _Function_base::_Base_manager<_Functor> _Base; + + public: + static void _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + (*_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Res, typename _Functor, typename... _ArgTypes> + class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> > + : public _Function_base::_Ref_manager<_Functor> + { + typedef _Function_base::_Ref_manager<_Functor> _Base; + + public: + static _Res _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + return + __callable_functor(**_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Functor, typename... _ArgTypes> + class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> > + : public _Function_base::_Ref_manager<_Functor> + { + typedef _Function_base::_Ref_manager<_Functor> _Base; + + public: + static void _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + __callable_functor(**_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Class, typename _Member, typename _Res, + typename... _ArgTypes> + class _Function_handler<_Res(_ArgTypes...), _Member _Class::*> + : public _Function_handler<void(_ArgTypes...), _Member _Class::*> + { + typedef _Function_handler<void(_ArgTypes...), _Member _Class::*> + _Base; + + public: + static _Res _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + return _GLIBCXX_TR1::mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...); + } + }; + + template<typename _Class, typename _Member, typename... _ArgTypes> + class _Function_handler<void(_ArgTypes...), _Member _Class::*> + : public _Function_base::_Base_manager< + _Simple_type_wrapper< _Member _Class::* > > + { + typedef _Member _Class::* _Functor; + typedef _Simple_type_wrapper< _Functor > _Wrapper; + typedef _Function_base::_Base_manager<_Wrapper> _Base; + + public: + static bool + _M_manager(_Any_data& __dest, const _Any_data& __source, + _Manager_operation __op) + { + switch (__op) { + case __get_type_info: + __dest._M_access<const type_info*>() = &typeid(_Functor); + break; + + case __get_functor_ptr: + __dest._M_access<_Functor*>() = + &_Base::_M_get_pointer(__source)->__value; + break; + + default: + _Base::_M_manager(__dest, __source, __op); + } + return false; + } + + static void _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + _GLIBCXX_TR1::mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...); + } + }; + + template<typename _Res, typename... _ArgTypes> + class function<_Res(_ArgTypes...)> + : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, + private _Function_base + { + /** + * @if maint + * This class is used to implement the safe_bool idiom. + * @endif + */ + struct _Hidden_type + { + _Hidden_type* _M_bool; + }; + + /** + * @if maint + * This typedef is used to implement the safe_bool idiom. + * @endif + */ + typedef _Hidden_type* _Hidden_type::* _Safe_bool; + + typedef _Res _Signature_type(_ArgTypes...); + + struct _Useless {}; + + public: + typedef _Res result_type; + + // [3.7.2.1] construct/copy/destroy + + /** + * @brief Default construct creates an empty function call wrapper. + * @post @c !(bool)*this + */ + function() : _Function_base() { } + + /** + * @brief Default construct creates an empty function call wrapper. + * @post @c !(bool)*this + */ + function(_M_clear_type*) : _Function_base() { } + + /** + * @brief %Function copy constructor. + * @param x A %function object with identical call signature. + * @pre @c (bool)*this == (bool)x + * + * The newly-created %function contains a copy of the target of @a + * x (if it has one). + */ + function(const function& __x); + + /** + * @brief Builds a %function that targets a copy of the incoming + * function object. + * @param f A %function object that is callable with parameters of + * type @c T1, @c T2, ..., @c TN and returns a value convertible + * to @c Res. + * + * The newly-created %function object will target a copy of @a + * f. If @a f is @c reference_wrapper<F>, then this function + * object will contain a reference to the function object @c + * f.get(). If @a f is a NULL function pointer or NULL + * pointer-to-member, the newly-created object will be empty. + * + * If @a f is a non-NULL function pointer or an object of type @c + * reference_wrapper<F>, this function will not throw. + */ + template<typename _Functor> + function(_Functor __f, + typename __gnu_cxx::__enable_if< + !is_integral<_Functor>::value, _Useless>::__type + = _Useless()); + + /** + * @brief %Function assignment operator. + * @param x A %function with identical call signature. + * @post @c (bool)*this == (bool)x + * @returns @c *this + * + * The target of @a x is copied to @c *this. If @a x has no + * target, then @c *this will be empty. + * + * If @a x targets a function pointer or a reference to a function + * object, then this operation will not throw an exception. + */ + function& operator=(const function& __x) + { + function(__x).swap(*this); + return *this; + } + + /** + * @brief %Function assignment to zero. + * @post @c !(bool)*this + * @returns @c *this + * + * The target of @a *this is deallocated, leaving it empty. + */ + function& operator=(_M_clear_type*) + { + if (_M_manager) { + _M_manager(_M_functor, _M_functor, __destroy_functor); + _M_manager = 0; + _M_invoker = 0; + } + return *this; + } + + /** + * @brief %Function assignment to a new target. + * @param f A %function object that is callable with parameters of + * type @c T1, @c T2, ..., @c TN and returns a value convertible + * to @c Res. + * @return @c *this + * + * This %function object wrapper will target a copy of @a + * f. If @a f is @c reference_wrapper<F>, then this function + * object will contain a reference to the function object @c + * f.get(). If @a f is a NULL function pointer or NULL + * pointer-to-member, @c this object will be empty. + * + * If @a f is a non-NULL function pointer or an object of type @c + * reference_wrapper<F>, this function will not throw. + */ + template<typename _Functor> + typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, + function&>::__type + operator=(_Functor __f) + { + function(__f).swap(*this); + return *this; + } + + // [3.7.2.2] function modifiers + + /** + * @brief Swap the targets of two %function objects. + * @param f A %function with identical call signature. + * + * Swap the targets of @c this function object and @a f. This + * function will not throw an exception. + */ + void swap(function& __x) + { + _Any_data __old_functor = _M_functor; + _M_functor = __x._M_functor; + __x._M_functor = __old_functor; + _Manager_type __old_manager = _M_manager; + _M_manager = __x._M_manager; + __x._M_manager = __old_manager; + _Invoker_type __old_invoker = _M_invoker; + _M_invoker = __x._M_invoker; + __x._M_invoker = __old_invoker; + } + + // [3.7.2.3] function capacity + + /** + * @brief Determine if the %function wrapper has a target. + * + * @return @c true when this %function object contains a target, + * or @c false when it is empty. + * + * This function will not throw an exception. + */ + operator _Safe_bool() const + { + if (_M_empty()) + { + return 0; + } + else + { + return &_Hidden_type::_M_bool; + } + } + + // [3.7.2.4] function invocation + + /** + * @brief Invokes the function targeted by @c *this. + * @returns the result of the target. + * @throws bad_function_call when @c !(bool)*this + * + * The function call operator invokes the target function object + * stored by @c this. + */ + _Res operator()(_ArgTypes... __args) const; + + // [3.7.2.5] function target access + /** + * @brief Determine the type of the target of this function object + * wrapper. + * + * @returns the type identifier of the target function object, or + * @c typeid(void) if @c !(bool)*this. + * + * This function will not throw an exception. + */ + const type_info& target_type() const; + + /** + * @brief Access the stored target function object. + * + * @return Returns a pointer to the stored target function object, + * if @c typeid(Functor).equals(target_type()); otherwise, a NULL + * pointer. + * + * This function will not throw an exception. + */ + template<typename _Functor> _Functor* target(); + + /** + * @overload + */ + template<typename _Functor> const _Functor* target() const; + + private: + // [3.7.2.6] undefined operators + template<typename _Function> + void operator==(const function<_Function>&) const; + template<typename _Function> + void operator!=(const function<_Function>&) const; + + typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...); + _Invoker_type _M_invoker; + }; + + template<typename _Res, typename... _ArgTypes> + function<_Res(_ArgTypes...)>::function(const function& __x) + : _Function_base() + { + if (__x) { + _M_invoker = __x._M_invoker; + _M_manager = __x._M_manager; + __x._M_manager(_M_functor, __x._M_functor, __clone_functor); + } + } + + template<typename _Res, typename... _ArgTypes> + template<typename _Functor> + function<_Res(_ArgTypes...)> + ::function(_Functor __f, + typename __gnu_cxx::__enable_if< + !is_integral<_Functor>::value, _Useless>::__type) + : _Function_base() + { + typedef _Function_handler<_Signature_type, _Functor> _My_handler; + if (_My_handler::_M_not_empty_function(__f)) { + _M_invoker = &_My_handler::_M_invoke; + _M_manager = &_My_handler::_M_manager; + _My_handler::_M_init_functor(_M_functor, __f); + } + } + + template<typename _Res, typename... _ArgTypes> + _Res function<_Res(_ArgTypes...)>::operator()(_ArgTypes... __args) const + { + if (_M_empty()) + { +#if __EXCEPTIONS + throw bad_function_call(); +#else + std::abort(); +#endif + } + return _M_invoker(_M_functor, __args...); + } + + template<typename _Res, typename... _ArgTypes> + const type_info& function<_Res(_ArgTypes...)>::target_type() const + { + if (_M_manager) + { + _Any_data __typeinfo_result; + _M_manager(__typeinfo_result, _M_functor, __get_type_info); + return *__typeinfo_result._M_access<const type_info*>(); + } + else + { + return typeid(void); + } + } + + template<typename _Res, typename... _ArgTypes> + template<typename _Functor> + _Functor* function<_Res(_ArgTypes...)>::target() + { + if (typeid(_Functor) == target_type() && _M_manager) + { + _Any_data __ptr; + if (_M_manager(__ptr, _M_functor, __get_functor_ptr) + && !is_const<_Functor>::value) + return 0; + else + return __ptr._M_access<_Functor*>(); + } + else + { + return 0; + } + } + + template<typename _Res, typename... _ArgTypes> + template<typename _Functor> + const _Functor* function<_Res(_ArgTypes...)>::target() const + { + if (typeid(_Functor) == target_type() && _M_manager) + { + _Any_data __ptr; + _M_manager(__ptr, _M_functor, __get_functor_ptr); + return __ptr._M_access<const _Functor*>(); + } + else + { + return 0; + } + } + // [3.7.2.7] null pointer comparisons /** @@ -1091,16 +2264,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) _GLIBCXX_END_NAMESPACE } -#define _GLIBCXX_JOIN(X,Y) _GLIBCXX_JOIN2( X , Y ) -#define _GLIBCXX_JOIN2(X,Y) _GLIBCXX_JOIN3(X,Y) -#define _GLIBCXX_JOIN3(X,Y) X##Y -#define _GLIBCXX_REPEAT_HEADER <tr1/functional_iterate.h> -#include <tr1/repeat.h> -#undef _GLIBCXX_REPEAT_HEADER -#undef _GLIBCXX_JOIN3 -#undef _GLIBCXX_JOIN2 -#undef _GLIBCXX_JOIN - #include <tr1/functional_hash.h> #endif |