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] | |
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] |