GCC Bugzilla – Attachment 16625 Details for
Bug 24803
[c++0x] reference_wrapper and pointers to member functions
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
update result_of and reference_wrapper
result_of-20081105.patch (text/plain), 13.94 KB, created by
Jonathan Wakely
on 2008-11-05 01:09:38 UTC
(
hide
)
Description:
update result_of and reference_wrapper
Filename:
MIME Type:
Creator:
Jonathan Wakely
Created:
2008-11-05 01:09:38 UTC
Size:
13.94 KB
patch
obsolete
>Index: include/tr1_impl/functional >=================================================================== >--- include/tr1_impl/functional (revision 141589) >+++ include/tr1_impl/functional (working copy) >@@ -153,6 +153,7 @@ > template<typename _Signature> > class result_of; > >+#ifdef _GLIBCXX_INCLUDE_AS_TR1 > /** > * Actual implementation of result_of. When _Has_result_type is > * true, gets its result from _Weak_result_type. Otherwise, uses >@@ -210,6 +211,104 @@ > typedef void type; > }; > >+#else >+ /** >+ * Actual implementation of std::result_of. >+ */ >+ template<bool _Is_mem_obj_ptr, bool _Is_mem_fun_ptr, typename _Signature> >+ struct _Result_of_impl; >+ >+ // Helper functions used by _Result_of_impl. >+ template<typename _ArgT> >+ struct _Result_of_arg >+ { >+ // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#904 >+#if 0 >+ static typename conditional<is_reference<_ArgT>::value, >+ typename add_lvalue_reference<_ArgT>::type, >+ typename add_rvalue_reference<_ArgT>::type>::type >+ _S_fwd(); >+#else >+ static typename add_rvalue_reference<_ArgT>::type >+ _S_fwd(); >+#endif >+ }; >+ >+ template<typename _Tp, bool _NoDeref> >+ struct _Result_of_lhs >+ { >+ static _Tp _S_fwd(); >+ }; >+ template<typename _Tp> >+ struct _Result_of_lhs<_Tp, false> >+ { >+ static decltype( *_Result_of_lhs<_Tp,true>::_S_fwd() ) _S_fwd(); >+ }; >+ >+ // Handle member data pointers. >+ template<typename _Res, typename _Class, typename _T1> >+ class _Result_of_impl<true, false, _Res _Class::* (_T1)> >+ { >+ typedef typename remove_reference<_T1>::type _T2; >+ typedef _Result_of_lhs<_T1, is_base_of<_Class, _T2>::value> _Fwd_lhs; >+ typedef _Res _Class::*_MemPtr; >+ >+ public: >+ typedef decltype( (_Fwd_lhs::_S_fwd().*(_MemPtr())) ) type; >+ }; >+ >+ // Handle member function pointers. >+ template<typename _MemFun, typename _T1, typename... _ArgTypes> >+ class _Result_of_impl<false, true, _MemFun (_T1, _ArgTypes...)> >+ { >+ template<typename> >+ struct _Get_class; >+ >+ template<typename _Res, typename _Class, typename... _Args> >+ struct _Get_class<_Res (_Class::*)(_Args...)> >+ { typedef _Class type; }; >+ template<typename _Res, typename _Class, typename... _Args> >+ struct _Get_class<_Res (_Class::*)(_Args...) const> >+ { typedef _Class type; }; >+ template<typename _Res, typename _Class, typename... _Args> >+ struct _Get_class<_Res (_Class::*)(_Args...) volatile> >+ { typedef _Class type; }; >+ template<typename _Res, typename _Class, typename... _Args> >+ struct _Get_class<_Res (_Class::*)(_Args...) const volatile> >+ { typedef _Class type; }; >+ >+ typedef typename _Get_class<_MemFun>::type _Class; >+ typedef typename remove_reference<_T1>::type _T2; >+ typedef _Result_of_lhs<_T1, is_base_of<_Class, _T2>::value> _Fwd_lhs; >+ >+ public: >+ typedef decltype( (_Fwd_lhs::_S_fwd().*(_MemFun())) ( >+ _Result_of_arg<_ArgTypes>::_S_fwd() ... ) ) type; >+ }; >+ >+ // Handle other callable types. >+ template<typename _Functor, typename... _ArgTypes> >+ class _Result_of_impl<false, false, _Functor(_ArgTypes...)> >+ { >+ // get an example of the callable type >+ static typename add_rvalue_reference<_Functor>::type >+ _S_fwd_functor(); >+ >+ public: >+ typedef decltype( _Result_of_impl::_S_fwd_functor() ( >+ _Result_of_arg<_ArgTypes>::_S_fwd() ... ) ) type; >+ }; >+ >+ template<typename _Functor, typename... _ArgTypes> >+ class result_of<_Functor(_ArgTypes...)> >+ : public _Result_of_impl< >+ is_member_object_pointer<_Functor>::value, >+ is_member_function_pointer<_Functor>::value, >+ _Functor(_ArgTypes...)> >+ { >+ }; >+#endif >+ > /// Determines if the type _Tp derives from unary_function. > template<typename _Tp> > struct _Derives_from_unary_function : __sfinae_types >@@ -255,6 +354,7 @@ > typedef _Tp* type; > }; > >+#ifdef _GLIBCXX_INCLUDE_AS_TR1 > /** > * Invoke a function object, which may be either a member pointer or a > * function object. The first parameter will tell which. >@@ -297,7 +397,51 @@ > { > return __f(__args...); > } >+#else >+ /** >+ * Invoke a function object, which may be either a member pointer or a >+ * function object. The first parameter will tell which. >+ */ >+ template<typename _Functor, typename... _Args> >+ inline >+ typename 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(std::forward<_Args>(__args)...); >+ } > >+ template<typename _Functor, typename... _Args> >+ inline >+ typename 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)(std::forward<_Args>(__args)...); >+ } >+ >+ // To pick up function references (that will become function pointers) >+ template<typename _Functor, typename... _Args> >+ inline >+ typename 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(std::forward<_Args>(__args)...); >+ } >+#endif >+ > /** > * Knowing which of unary_function and binary_function _Tp derives > * from, derives from the same and ensures that reference_wrapper >@@ -440,10 +584,18 @@ > public: > typedef _Tp type; > >+#ifdef _GLIBCXX_INCLUDE_AS_TR1 > explicit > reference_wrapper(_Tp& __indata): _M_data(&__indata) > { } >+#else >+ reference_wrapper(_Tp& __indata): _M_data(&__indata) >+ { } > >+ explicit >+ reference_wrapper(_Tp&&) = delete; >+#endif >+ > reference_wrapper(const reference_wrapper<_Tp>& __inref): > _M_data(__inref._M_data) > { } >@@ -462,12 +614,21 @@ > get() const > { return *_M_data; } > >+#ifdef _GLIBCXX_INCLUDE_AS_TR1 > template<typename... _Args> > typename result_of<_M_func_type(_Args...)>::type > operator()(_Args&... __args) const > { > return __invoke(get(), __args...); > } >+#else >+ template<typename... _Args> >+ typename result_of<_M_func_type(_Args...)>::type >+ operator()(_Args&&... __args) const >+ { >+ return __invoke(get(), std::forward<_Args>(__args)...); >+ } >+#endif > }; > > >Index: testsuite/20_util/function_objects/return_types/result_of_neg.cc >=================================================================== >--- testsuite/20_util/function_objects/return_types/result_of_neg.cc (revision 0) >+++ testsuite/20_util/function_objects/return_types/result_of_neg.cc (revision 0) >@@ -0,0 +1,53 @@ >+// { dg-options "-std=gnu++0x" } >+// { dg-do compile } >+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free >+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, >+// USA. >+ >+// 20.6.4 function object return types [func.ret] >+#include <functional> >+#include <testsuite_hooks.h> >+ >+struct X >+{ >+ int i; >+ int f(); >+}; >+ >+void test01() >+{ >+ bool test __attribute__((unused)) = true; >+ >+ using std::result_of; >+ using std::is_same; >+ >+ typedef int X::*pm; >+ typedef int (X::*pmf)(); >+ typedef int (*pf)(); >+ >+ result_of<pmf(X*, int)>::type test2; // { dg-error "here" } >+ // { dg-error "too many arguments to function" "" { target *-*-* } 286 } >+ result_of<pf(int)>::type test3; // { dg-error "here" } >+ // { dg-error "too many arguments to function" "" { target *-*-* } 299 } >+} >+ >+int main() >+{ >+ test01(); >+ return 0; >+} >+// { dg-excess-errors "" } >Index: testsuite/20_util/function_objects/return_types/result_of_ref.cc >=================================================================== >--- testsuite/20_util/function_objects/return_types/result_of_ref.cc (revision 0) >+++ testsuite/20_util/function_objects/return_types/result_of_ref.cc (revision 0) >@@ -0,0 +1,50 @@ >+// { dg-options "-std=gnu++0x" } >+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free >+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, >+// USA. >+ >+// 20.6.4 function object return types [func.ret] >+#include <functional> >+#include <testsuite_hooks.h> >+ >+struct X >+{ >+ int operator()(int&); >+ float operator()(int&&); >+}; >+ >+void test01() >+{ >+ bool test __attribute__((unused)) = true; >+ >+ using std::result_of; >+ using std::is_same; >+ >+ typedef int (*func_ptr)(int&); >+ >+ VERIFY((is_same<result_of<X(int)>::type, float>::value)); >+ VERIFY((is_same<result_of<X(int&)>::type, int>::value)); >+ // VERIFY((is_same<result_of<X(int&&)>::type, int>::value)); >+ VERIFY((is_same<result_of<X(int&&)>::type, float>::value)); >+ VERIFY((is_same<result_of<func_ptr(int&)>::type, int>::value)); >+} >+ >+int main() >+{ >+ test01(); >+ return 0; >+} >Index: testsuite/20_util/function_objects/return_types/result_of.cc >=================================================================== >--- testsuite/20_util/function_objects/return_types/result_of.cc (revision 0) >+++ testsuite/20_util/function_objects/return_types/result_of.cc (revision 0) >@@ -0,0 +1,76 @@ >+// { dg-options "-std=gnu++0x" } >+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free >+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, >+// USA. >+ >+// 20.6.4 function object return types [func.ret] >+#include <functional> >+#include <testsuite_hooks.h> >+ >+struct nested_result_type >+{ >+ typedef float result_type; >+ int operator()(); >+}; >+ >+struct nested_result_template >+{ >+ template<typename F> struct result { typedef float type; }; >+ int operator()(int); >+}; >+ >+struct cv_overload >+{ >+ int operator()(int); >+ char operator()(char) const; >+ float operator()(float) volatile; >+}; >+ >+struct default_args >+{ >+ int operator()(int* = 0, int* = 0); >+ void operator()(void*); >+}; >+ >+class X {}; >+ >+void test01() >+{ >+ bool test __attribute__((unused)) = true; >+ >+ using std::result_of; >+ using std::is_same; >+ >+ typedef int (*func_ptr)(float, double); >+ typedef int (&func_ref)(float, double); >+ >+ VERIFY((is_same<result_of<nested_result_type()>::type, int>::value)); >+ VERIFY((is_same<result_of<nested_result_template(int)>::type, int>::value)); >+ VERIFY((is_same<result_of<cv_overload(int)>::type, int>::value)); >+ VERIFY((is_same<result_of<const cv_overload(int)>::type, char>::value)); >+ VERIFY((is_same<result_of<volatile cv_overload(int)>::type, float>::value)); >+ VERIFY((is_same<result_of<default_args(int*)>::type, int>::value)); >+ VERIFY((is_same<result_of<default_args(char*)>::type, void>::value)); >+ VERIFY((is_same<result_of<func_ptr(char, float)>::type, int>::value)); >+ VERIFY((is_same<result_of<func_ref(char, float)>::type, int>::value)); >+} >+ >+int main() >+{ >+ test01(); >+ return 0; >+} >Index: testsuite/20_util/reference_wrapper/24803.cc >=================================================================== >--- testsuite/20_util/reference_wrapper/24803.cc (revision 141589) >+++ testsuite/20_util/reference_wrapper/24803.cc (working copy) >@@ -70,7 +70,7 @@ > std::reference_wrapper<functor1>* pr5(0); > > // libstdc++/24803 >- // FIXME: verify_return_type((*pr5)(0), double()); >+ verify_return_type((*pr5)(0), double()); > verify_return_type((*pr5)(zero), double()); > > std::reference_wrapper<double (int, char)>* pr1b(0); >@@ -84,6 +84,6 @@ > std::reference_wrapper<functor2>* pr5b(0); > > // libstdc++/24803 >- // FIXME: verify_return_type((*pr5b)(0,0), double()); >+ verify_return_type((*pr5b)(0,0), double()); > verify_return_type((*pr5b)(zero,zero), double()); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 24803
: 16625