This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[libstdc++ patch] TR1 result_of implementation


This patch adds support for result_of (section 3.4 of TR1). This is the 
library-only solution that does not make sure of typeof. If we get a 
reference-preserving typeof (or can fake it), we should consider replacing 
this implementation with one that uses the reference-preserving typeof 
directly.

reference_wrapper's result_type and operator() should be easy to implement 
now.

All function object tests pass on i686-pc-linux-gnu; full test suite is 
running right. Okay to commit if everything passes?

 Doug
Index: include/tr1/functional
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/tr1/functional,v
retrieving revision 1.7
diff -c -3 -p -b -r1.7 functional
*** include/tr1/functional	24 Feb 2005 09:01:52 -0000	1.7
--- include/tr1/functional	27 Feb 2005 20:31:10 -0000
*************** namespace std
*** 45,50 ****
--- 45,135 ----
  {
  namespace tr1
  {
+   /**
+    *  @if maint
+    *  Actual implementation of _Has_result_type, which uses SFINAE to
+    *  determine if the type _Tp has a publicly-accessible member type
+    *  result_type.
+    *  @endif
+   */
+   template<typename _Tp>
+     class _Has_result_type_helper
+     {
+       template<typename _Up>
+       struct _Wrap_type
+       { };
+ 
+       template<typename _Up>
+         static __sfinae_types::__one
+         __test(_Wrap_type<typename _Up::result_type>*);
+ 
+       template<typename _Up>
+         static __sfinae_types::__two __test(...);
+ 
+     public:
+       static const bool __value = sizeof(__test<_Tp>(0)) == 1;
+     };
+ 
+   template<typename _Tp>
+     struct _Has_result_type
+        : integral_constant<
+            bool,
+            _Has_result_type_helper<typename remove_cv<_Tp>::type>::__value>
+     { };
+ 
+   /**
+    *  @if maint
+    *  If we have found a result_type, extract it.
+    *  @endif
+   */
+   template<bool _Has_result_type, typename _Functor>
+     struct _Maybe_get_result_type
+     { };
+ 
+   template<typename _Functor>
+     struct _Maybe_get_result_type<true, _Functor>
+     {
+       typedef typename _Functor::result_type result_type;
+     };
+ 
+   /**
+    *  @if maint
+    *  Base class for any function object that has a weak result type, as
+    *  defined in 3.3/3 of TR1.
+    *  @endif
+   */
+   template<typename _Functor>
+     struct _Weak_result_type_impl
+       : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
+     {
+     };
+ 
+   /**
+    *  @if maint
+    *  Strip top-level cv-qualifiers from the function object and let
+    *  _Weak_result_type_impl perform the real work.
+    *  @endif
+   */
+   template<typename _Functor>
+     struct _Weak_result_type
+     : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
+     {
+     };
+ 
+   template<typename _Signature>
+     class result_of;
+ 
+   /**
+    *  @if maint
+    *  Actual implementation of result_of. When _Has_result_type is
+    *  true, gets its result from _Weak_result_type. Otherwise, uses
+    *  the function object's member template result to extract the
+    *  result type.
+    *  @endif
+   */
+   template<bool _Has_result_type, typename _Signature>
+     struct _Result_of_impl;
+ 
    template<typename _Tp>
      class reference_wrapper
      {
Index: include/tr1/functional_iterate.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/tr1/functional_iterate.h,v
retrieving revision 1.1
diff -c -3 -p -b -r1.1 functional_iterate.h
*** include/tr1/functional_iterate.h	24 Feb 2005 01:16:07 -0000	1.1
--- include/tr1/functional_iterate.h	27 Feb 2005 20:31:10 -0000
***************
*** 33,38 ****
--- 33,109 ----
   *  You should not attempt to use it directly.
   */
  
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)>
+   {
+     typedef _Res result_type;
+   };
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)>
+   {
+     typedef _Res result_type;
+   };
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)>
+   {
+     typedef _Res result_type;
+   };
+ 
+ #if _GLIBCXX_NUM_ARGS > 0
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   struct _Weak_result_type_impl<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
+   {
+     typedef _Res result_type;
+   };
+ 
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   struct _Weak_result_type_impl<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
+   {
+     typedef _Res result_type;
+   };
+ 
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   struct _Weak_result_type_impl<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
+   {
+     typedef _Res result_type;
+   };
+ 
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   struct _Weak_result_type_impl<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
+   {
+     typedef _Res result_type;
+   };
+ #endif
+ 
+ template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   class result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
+     : public _Result_of_impl<
+                _Has_result_type<_Weak_result_type<_Functor> >::value,
+              _Functor(_GLIBCXX_TEMPLATE_ARGS)>
+   { };
+ 
+ template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
+   {
+     typedef typename _Weak_result_type<_Functor>::result_type type;
+   };
+ 
+ template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
+   {
+ #if _GLIBCXX_NUM_ARGS > 0
+     typedef typename _Functor::template result<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type type;
+ #else
+     typedef void type;
+ #endif
+   };
+ 
  #if _GLIBCXX_NUM_ARGS > 0
  template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
           _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
Index: testsuite/tr1/3_function_objects/result_of.cc
===================================================================
RCS file: testsuite/tr1/3_function_objects/result_of.cc
diff -N testsuite/tr1/3_function_objects/result_of.cc
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/tr1/3_function_objects/result_of.cc	27 Feb 2005 20:31:17 -0000
***************
*** 0 ****
--- 1,75 ----
+ // 2005-01-26 Douglas Gregor <dgregor@cs.indiana.edu>
+ //
+ // Copyright (C) 2005 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // 3.4 function return types
+ #include <tr1/functional>
+ #include <tr1/type_traits>
+ #include <testsuite_hooks.h>
+ #include <testsuite_tr1.h>
+ 
+ class X {};
+ 
+ struct int_result_type { typedef int result_type; };
+ 
+ struct int_result_of
+ {
+   template<typename F> struct result { typedef int type; };
+ };
+ 
+ struct int_result_type_and_float_result_of
+ {
+   typedef int result_type;
+   template<typename F> struct result { typedef float type; };
+ };
+ 
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+ 
+   using std::tr1::result_of;
+   using std::tr1::is_same;
+   using namespace __gnu_test;
+ 
+   typedef int (*func_ptr)(float, double);
+   typedef int (&func_ref)(float, double);
+   typedef int (::X::*mem_func_ptr)(float);
+   typedef int (::X::*mem_func_ptr_c)(float) const;
+   typedef int (::X::*mem_func_ptr_v)(float) volatile;
+   typedef int (::X::*mem_func_ptr_cv)(float) const volatile;
+ 
+   VERIFY((is_same<result_of<int_result_type(float)>::type, int>::value));
+   VERIFY((is_same<result_of<int_result_of(double)>::type, int>::value));
+   VERIFY((is_same<result_of<int_result_of(void)>::type, void>::value));
+   VERIFY((is_same<result_of<const int_result_of(double)>::type, int>::value));
+   VERIFY((is_same<result_of<volatile int_result_of(void)>::type, void>::value));
+   VERIFY((is_same<result_of<int_result_type_and_float_result_of(char)>::type, int>::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));
+   VERIFY((is_same<result_of<mem_func_ptr(::X,char)>::type, int>::value));
+   VERIFY((is_same<result_of<mem_func_ptr_c(::X,char)>::type, int>::value));
+   VERIFY((is_same<result_of<mem_func_ptr_v(::X,char)>::type, int>::value));
+   VERIFY((is_same<result_of<mem_func_ptr_cv(::X,char)>::type, int>::value));
+ }
+ 
+ int main()
+ {
+   test01();
+   return 0;
+ }

Attachment: ChangeLog.result_of
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]