From be7f782278465ae177c717f3b898906201c2471c Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 19 Apr 2011 13:26:08 +0000 Subject: [PATCH] re PR libstdc++/48521 ([C++0x] std::result_of doesn't work with pointer to member) 2011-04-19 Jonathan Wakely PR libstdc++/48521 * include/std/type_traits (result_of): Handle pointer to member. * include/std/functional (__invoke): Likewise. (_Function_to_function_pointer): Remove. (_Reference_wrapper_base): Provide nested types independent of unary_function and binary_function. (reference_wrapper::operator()): DR 2017. (ref(const A&&), cref(const A&&): Define as deleted. * include/std/future (async): Simplify SFINAE and use result_of to support pointer to member. * testsuite/20_util/reference_wrapper/invoke.cc: Test pointer to member. * testsuite/20_util/reference_wrapper/24803.cc: Likewise. * testsuite/20_util/reference_wrapper/typedefs.cc: Test for types instead of derivation from unary_function and binary_function. * testsuite/20_util/declval/requirements/1_neg.cc: Adjust. * testsuite/20_util/reference_wrapper/invoke-2.cc: New. * testsuite/20_util/reference_wrapper/ref_neg.c: New. * testsuite/20_util/reference_wrapper/typedefs-3.c: New. From-SVN: r172709 --- libstdc++-v3/ChangeLog | 22 +++ libstdc++-v3/include/std/functional | 88 ++++++----- libstdc++-v3/include/std/future | 18 ++- libstdc++-v3/include/std/type_traits | 104 ++++++++++-- .../20_util/declval/requirements/1_neg.cc | 2 +- .../20_util/reference_wrapper/24803.cc | 12 +- .../20_util/reference_wrapper/invoke-2.cc | 47 ++++++ .../20_util/reference_wrapper/invoke.cc | 32 +++- .../20_util/reference_wrapper/ref_neg.cc | 44 ++++++ .../20_util/reference_wrapper/typedefs-3.cc | 148 ++++++++++++++++++ .../20_util/reference_wrapper/typedefs.cc | 48 ++---- 11 files changed, 463 insertions(+), 102 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc create mode 100644 libstdc++-v3/testsuite/20_util/reference_wrapper/ref_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 643e4f2448c..3aa9a3907ca 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2011-04-19 Jonathan Wakely + + PR libstdc++/48521 + * include/std/type_traits (result_of): Handle pointer to member. + * include/std/functional (__invoke): Likewise. + (_Function_to_function_pointer): Remove. + (_Reference_wrapper_base): Provide nested types independent of + unary_function and binary_function. + (reference_wrapper::operator()): DR 2017. + (ref(const A&&), cref(const A&&): Define as deleted. + * include/std/future (async): Simplify SFINAE and use result_of to + support pointer to member. + * testsuite/20_util/reference_wrapper/invoke.cc: Test pointer to + member. + * testsuite/20_util/reference_wrapper/24803.cc: Likewise. + * testsuite/20_util/reference_wrapper/typedefs.cc: Test for types + instead of derivation from unary_function and binary_function. + * testsuite/20_util/declval/requirements/1_neg.cc: Adjust. + * testsuite/20_util/reference_wrapper/invoke-2.cc: New. + * testsuite/20_util/reference_wrapper/ref_neg.c: New. + * testsuite/20_util/reference_wrapper/typedefs-3.c: New. + 2011-04-19 Hans-Peter Nilsson PR testsuite/48675 diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 660e371b599..57ec5062133 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -212,19 +212,6 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) static const bool value = sizeof(__test((_Tp*)0)) == 1; }; - /// Turns a function type into a function pointer type - template::value> - struct _Function_to_function_pointer - { - typedef _Tp type; - }; - - template - struct _Function_to_function_pointer<_Tp, true> - { - typedef _Tp* type; - }; - /** * Invoke a function object, which may be either a member pointer or a * function object. The first parameter will tell which. @@ -235,20 +222,33 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) (!is_member_pointer<_Functor>::value && !is_function<_Functor>::value && !is_function::type>::value), - typename result_of<_Functor(_Args...)>::type + typename result_of<_Functor(_Args&&...)>::type >::type __invoke(_Functor& __f, _Args&&... __args) { return __f(std::forward<_Args>(__args)...); } + template + inline + typename enable_if< + (is_member_pointer<_Functor>::value + && !is_function<_Functor>::value + && !is_function::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 inline typename enable_if< (is_pointer<_Functor>::value && is_function::type>::value), - typename result_of<_Functor(_Args...)>::type + typename result_of<_Functor(_Args&&...)>::type >::type __invoke(_Functor __f, _Args&&... __args) { @@ -263,40 +263,43 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template struct _Reference_wrapper_base_impl; - // Not a unary_function or binary_function, so try a weak result type. + // None of the nested argument types. template struct _Reference_wrapper_base_impl : _Weak_result_type<_Tp> { }; - // unary_function but not binary_function + // Nested argument_type only. template struct _Reference_wrapper_base_impl - : unary_function - { }; + : _Weak_result_type<_Tp> + { + typedef typename _Tp::argument_type argument_type; + }; - // binary_function but not unary_function + // Nested first_argument_type and second_argument_type only. template struct _Reference_wrapper_base_impl - : binary_function - { }; + : _Weak_result_type<_Tp> + { + typedef typename _Tp::first_argument_type first_argument_type; + typedef typename _Tp::second_argument_type second_argument_type; + }; - // Both unary_function and binary_function. Import result_type to - // avoid conflicts. + // All the nested argument types. template struct _Reference_wrapper_base_impl - : unary_function, - binary_function + : _Weak_result_type<_Tp> { - typedef typename _Tp::result_type result_type; + typedef typename _Tp::argument_type argument_type; + typedef typename _Tp::first_argument_type first_argument_type; + typedef typename _Tp::second_argument_type second_argument_type; }; + _GLIBCXX_HAS_NESTED_TYPE(argument_type) + _GLIBCXX_HAS_NESTED_TYPE(first_argument_type) + _GLIBCXX_HAS_NESTED_TYPE(second_argument_type) + /** * Derives from unary_function or binary_function when it * can. Specializations handle all of the easy cases. The primary @@ -306,8 +309,9 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template struct _Reference_wrapper_base : _Reference_wrapper_base_impl< - _Derives_from_unary_function<_Tp>::value, - _Derives_from_binary_function<_Tp>::value, + __has_argument_type<_Tp>::value, + __has_first_argument_type<_Tp>::value + && __has_second_argument_type<_Tp>::value, _Tp> { }; @@ -422,12 +426,8 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) class reference_wrapper : public _Reference_wrapper_base::type> { - // If _Tp is a function type, we can't form result_of<_Tp(...)>, - // so turn it into a function pointer type. - typedef typename _Function_to_function_pointer<_Tp>::type - _M_func_type; - _Tp* _M_data; + public: typedef _Tp type; @@ -456,7 +456,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) { return *_M_data; } template - typename result_of<_M_func_type(_Args...)>::type + typename result_of<_Tp&(_Args&&...)>::type operator()(_Args&&... __args) const { return __invoke(get(), std::forward<_Args>(__args)...); @@ -476,6 +476,12 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) cref(const _Tp& __t) { return reference_wrapper(__t); } + template + void ref(const _Tp&&) = delete; + + template + void cref(const _Tp&&) = delete; + /// Partial specialization. template inline reference_wrapper<_Tp> diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index 7a62d5ecf28..f7035a9109a 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -142,11 +142,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION future::type> async(launch __policy, _Fn&& __fn, _Args&&... __args); + template + struct __async_sfinae_helper + { + typedef future::type> type; + }; + + template + struct __async_sfinae_helper + { }; + template typename - enable_if::type, launch>::value, - future()(std::declval<_Args>()...))> - >::type + __async_sfinae_helper::type, _Fn, _Args...>::type async(_Fn&& __fn, _Args&&... __args); #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ @@ -1373,9 +1381,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// async, potential overload template inline typename - enable_if::type, launch>::value, - future()(std::declval<_Args>()...))> - >::type + __async_sfinae_helper::type, _Fn, _Args...>::type async(_Fn&& __fn, _Args&&... __args) { return async(launch::any, std::forward<_Fn>(__fn), diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index ef622988aa4..11f1b012261 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -1583,18 +1583,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// underlying_type (still unimplemented) - /// result_of - template - class result_of; - - template - struct result_of<_Functor(_ArgTypes...)> - { - typedef - decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) ) - type; - }; - /// declval template struct __declval_protector @@ -1612,6 +1600,98 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __declval_protector<_Tp>::__delegate(); } + /// result_of + template + class result_of; + + template + struct _Result_of_memobj; + + template + struct _Result_of_memobj<_Res _Class::*, _Arg> + { + private: + typedef _Res _Class::* _Func; + + template + static _Tp _S_get(const _Class&); + template + static decltype(*std::declval<_Tp>()) _S_get(...); + + public: + typedef + decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) + __type; + }; + + template + struct _Result_of_memfun; + + template + struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...> + { + private: + typedef _Res _Class::* _Func; + + template + static _Tp _S_get(const _Class&); + template + static decltype(*std::declval<_Tp>()) _S_get(...); + + public: + typedef + decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) + (std::declval<_Args>()...) ) + __type; + }; + + template + struct _Result_of_impl; + + template + struct _Result_of_impl + { + typedef + decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) ) + __type; + }; + + template + struct _Result_of_impl + : _Result_of_memobj::type, _Arg> + { + typedef typename _Result_of_memobj< + typename remove_reference<_MemPtr>::type, _Arg>::__type + __type; + }; + + template + struct _Result_of_impl + : _Result_of_memfun::type, _Arg, + _ArgTypes...> + { + typedef typename _Result_of_memfun< + typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type + __type; + }; + + template + struct result_of<_Functor(_ArgTypes...)> + : _Result_of_impl::type >::value, + is_member_function_pointer< + typename remove_reference<_Functor>::type >::value, + _Functor, _ArgTypes...> + { + typedef typename _Result_of_impl< + is_member_object_pointer< + typename remove_reference<_Functor>::type >::value, + is_member_function_pointer< + typename remove_reference<_Functor>::type >::value, + _Functor, _ArgTypes...>::__type + type; + }; + /** * Use SFINAE to determine if the type _Tp has a publicly-accessible * member type _NTYPE. diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc index 6aee07a3dee..debff581af5 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // . -// { dg-error "static assertion failed" "" { target *-*-* } 1610 } +// { dg-error "static assertion failed" "" { target *-*-* } 1598 } #include diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/24803.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/24803.cc index 598c5c8733b..4bf61485cc8 100644 --- a/libstdc++-v3/testsuite/20_util/reference_wrapper/24803.cc +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/24803.cc @@ -1,7 +1,7 @@ // { dg-options "-std=gnu++0x" } // { dg-do compile } -// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009, 2010, 2011 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 @@ -46,12 +46,18 @@ void verify_return_type(T, T) void test01() { + test_type* null_tt = 0; + const test_type* null_ttc = 0; int zero; std::reference_wrapper* pr1(0); verify_return_type((*pr1)(0), double()); std::reference_wrapper* pr2(0); verify_return_type((*pr2)(0), double()); + std::reference_wrapper* pr3(0); + verify_return_type((*pr3)(null_tt), int()); + std::reference_wrapper* pr4(0); + verify_return_type((*pr4)(null_ttc), int()); std::reference_wrapper* pr5(0); // libstdc++/24803 @@ -62,6 +68,10 @@ void test01() verify_return_type((*pr1b)(0, 0), double()); std::reference_wrapper* pr2b(0); verify_return_type((*pr2b)(0, 0), double()); + std::reference_wrapper* pr3b(0); + verify_return_type((*pr3b)(null_tt,zero), int()); + std::reference_wrapper* pr4b(0); + verify_return_type((*pr4b)(null_ttc), int()); std::reference_wrapper* pr5b(0); // libstdc++/24803 diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc new file mode 100644 index 00000000000..bd9aeb2c40b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc @@ -0,0 +1,47 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile} +// Copyright (C) 2011 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 + +struct X +{ + int f(int) { return 0; } + int i; +}; + +void test01() +{ + typedef int (X::*mfp)(int); + typedef int X::*mp; + mfp m = &X::f; + mp m2 = &X::i; + X x = { }; + std::ref(m)(x, 1); + std::ref(m)(&x, 1); + int& i1 = std::ref(m2)(x); + int& i2 = std::ref(m2)(&x); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc index b371f1ce9e8..7b694c76432 100644 --- a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc @@ -1,6 +1,6 @@ // { dg-options "-std=gnu++0x" } -// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009, 2010, 2011 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 @@ -36,6 +36,7 @@ struct X int foo_c(float x) const { return truncate_float(x); } int foo_v(float x) volatile { return truncate_float(x); } int foo_cv(float x) const volatile { return truncate_float(x); } + int foo_varargs(float x, ...) { return truncate_float(x); } int operator()(float x) { @@ -69,6 +70,13 @@ void test01() ::get_seventeen get_sev; ::X x; + ::X* xp = &x; + int (::X::* p_foo)(float) = &::X::foo; + int (::X::* p_foo_c)(float) const = &::X::foo_c; + int (::X::* p_foo_v)(float) volatile = &::X::foo_v; + int (::X::* p_foo_cv)(float) const volatile = &::X::foo_cv; + int (::X::* p_foo_varargs)(float, ...) = &::X::foo_varargs; + int ::X::* p_bar = &::X::bar; const float pi = 3.14; @@ -77,8 +85,26 @@ void test01() VERIFY(ref(seventeen)() == 17); // Function pointers - VERIFY(cref(&truncate_float)(pi) == 3); - VERIFY(cref(&seventeen)() == 17); + VERIFY(cref(truncate_float)(pi) == 3); + VERIFY(cref(seventeen)() == 17); + + // Member function pointers + VERIFY(ref(p_foo)(x, pi) == 3); + VERIFY(ref(p_foo)(xp, pi) == 3); + VERIFY(ref(p_foo_c)(x, pi) == 3); + VERIFY(ref(p_foo_c)(xp, pi) == 3); + VERIFY(ref(p_foo_v)(x, pi) == 3); + VERIFY(ref(p_foo_v)(xp, pi) == 3); + VERIFY(ref(p_foo_cv)(x, pi) == 3); + VERIFY(ref(p_foo_cv)(xp, pi) == 3); + // VERIFY(ref(p_foo_varargs)(x, pi) == 3); + // VERIFY(ref(p_foo_varargs)(xp, pi, 1, 1) == 3); + // VERIFY(ref(p_foo_varargs)(x, pi, 1, 1) == 3); + // VERIFY(ref(p_foo_varargs)(xp, pi) == 3); + + // Member data pointers + VERIFY(ref(p_bar)(x) == 17); + VERIFY(ref(p_bar)(xp) == 17); // Function objects VERIFY(ref(get_sev)() == 17); diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/ref_neg.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/ref_neg.cc new file mode 100644 index 00000000000..947a9b02f1e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/ref_neg.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2011 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 3, 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 COPYING3. If not see +// . + +// 20.8.3 Class template reference_wrapper + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X { }; +X rval(); +X&& rvalref(); + +void test01() +{ + std::ref(1); // { dg-error "deleted" } + std::cref(1); // { dg-error "deleted" } + std::ref( int() ); // { dg-error "deleted" } + std::cref( int() ); // { dg-error "deleted" } + std::ref(rval()); // { dg-error "deleted" } + std::cref(rvalref()); // { dg-error "deleted" } +} + +int main() +{ + test02(); +} + +// { dg-excess-errors "" } diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc new file mode 100644 index 00000000000..2fea52eed06 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc @@ -0,0 +1,148 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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 3, 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 COPYING3. If not see +// . + +#include +#include + +struct S { }; + +struct S0 +{ + typedef int argument_type; +}; + +struct S1 +{ + typedef float first_argument_type; +}; + +struct S2 +{ + typedef char second_argument_type; +}; + +struct S01 : S0, S1 { }; +struct S02 : S0, S2 { }; +struct S12 : S1, S2 { }; + +struct S012 : S0, S1, S2 { }; + +using std::__sfinae_types; +using std::integral_constant; +using std::remove_cv; + +_GLIBCXX_HAS_NESTED_TYPE(argument_type) +_GLIBCXX_HAS_NESTED_TYPE(first_argument_type) +_GLIBCXX_HAS_NESTED_TYPE(second_argument_type) + +template + struct has_arg_type : __has_argument_type + { }; + +template + struct has_1st_arg_type : __has_first_argument_type + { }; + +template + struct has_2nd_arg_type : __has_second_argument_type + { }; + +template::value> +struct test_arg_type +{ + static_assert( !has_arg_type>::value, + "reference_wrapper has no nested argument_type"); +}; + +template +struct test_arg_type +{ + typedef std::reference_wrapper ref; + + static_assert( has_arg_type::value, + "reference_wrapper has nested argument_type"); + + static_assert( + std::is_same< typename T::argument_type, + typename ref::argument_type >::value, + "reference_wrapper has the correct argument_type"); +}; + +template::value && has_2nd_arg_type::value> +struct test_1st_2nd_arg_types +{ + typedef std::reference_wrapper ref; + + static_assert( !has_1st_arg_type::value, + "reference_wrapper has no nested first_argument_type"); + + static_assert( !has_2nd_arg_type::value, + "reference_wrapper has no nested second_argument_type"); +}; + +template +struct test_1st_2nd_arg_types +{ + typedef std::reference_wrapper ref; + + static_assert( has_1st_arg_type::value, + "reference_wrapper has nested first_argument_type"); + + static_assert( has_2nd_arg_type::value, + "reference_wrapper has nested second_argument_type"); + + static_assert( + std::is_same< typename T::first_argument_type, + typename ref::first_argument_type>::value, + "reference_wrapper has correct first_argument_type"); + + static_assert( + std::is_same< typename T::second_argument_type, + typename ref::second_argument_type>::value, + "reference_wrapper has correct second_argument_type"); +}; + + +template + void test() + { + test_arg_type t; + test_arg_type tc; + test_arg_type tv; + test_arg_type tcv; + test_1st_2nd_arg_types t12; + test_1st_2nd_arg_types t12c; + test_1st_2nd_arg_types t12v; + test_1st_2nd_arg_types t12cv; + } + +int main() +{ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); +} + diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs.cc index 56ee29e1af1..815700f1c64 100644 --- a/libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs.cc +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs.cc @@ -1,6 +1,7 @@ +// { dg-do compile } // { dg-options "-std=gnu++0x" } -// Copyright (C) 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009, 2010, 2011 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 @@ -19,10 +20,6 @@ #include #include -#include -#include - -using namespace __gnu_test; struct X {}; @@ -41,43 +38,18 @@ struct derives_unary_binary void test01() { - bool test __attribute__((unused)) = true; - using std::reference_wrapper; using std::is_same; - using std::is_convertible; - using std::unary_function; - using std::binary_function; // Check result_type typedef - VERIFY((is_same::result_type, int>::value)); - VERIFY((is_same::result_type, int>::value)); - VERIFY((is_same::result_type, int>::value)); - VERIFY((is_same::result_type, int>::value)); - VERIFY((is_same::result_type, int>::value)); - VERIFY((is_same::result_type, int>::value)); - VERIFY((is_same::result_type, int>::value)); - VERIFY((is_same::result_type, int>::value)); - - // Check derivation from unary_function - VERIFY((is_convertible*, unary_function*>::value)); - VERIFY((is_convertible*, unary_function*>::value)); - VERIFY((is_convertible*, unary_function*>::value)); - VERIFY((is_convertible*, unary_function*>::value)); - VERIFY((is_convertible*, unary_function< ::X*, int>*>::value)); - VERIFY((is_convertible*, unary_function*>::value)); - VERIFY((is_convertible*, unary_function*>::value)); - VERIFY((is_convertible*, unary_function*>::value)); - - // Check derivation from binary_function - VERIFY((is_convertible*, binary_function*>::value)); - VERIFY((is_convertible*, binary_function*>::value)); - VERIFY((is_convertible*, binary_function*>::value)); - VERIFY((is_convertible*, binary_function*>::value)); - VERIFY((is_convertible*, binary_function< ::X*, float, int>*>::value)); - VERIFY((is_convertible*, binary_function*>::value)); - VERIFY((is_convertible*, binary_function*>::value)); - VERIFY((is_convertible*, binary_function*>::value)); + static_assert( is_same::result_type, int>::value, "has result_type" ); + static_assert( is_same::result_type, int>::value, "has result_type" ); + static_assert( is_same::result_type, int>::value, "has result_type" ); + static_assert( is_same::result_type, int>::value, "has result_type" ); + static_assert( is_same::result_type, int>::value, "has result_type" ); + static_assert( is_same::result_type, int>::value, "has result_type" ); + static_assert( is_same::result_type, int>::value, "has result_type" ); + static_assert( is_same::result_type, int>::value, "has result_type" ); } int main() -- 2.30.2