diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-19 13:26:08 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-19 13:26:08 +0000 |
commit | 409e2405e2f298311e26857cfe610a0865d5d763 (patch) | |
tree | 46bddda6e0625793f71e6f9abbe316c4f086c355 /libstdc++-v3 | |
parent | e400b89a267e84f9753ba212b8ec2ce36a5328de (diff) | |
download | gcc-409e2405e2f298311e26857cfe610a0865d5d763.tar.gz |
2011-04-19 Jonathan Wakely <jwakely.gcc@gmail.com>
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172709 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 22 | ||||
-rw-r--r-- | libstdc++-v3/include/std/functional | 88 | ||||
-rw-r--r-- | libstdc++-v3/include/std/future | 18 | ||||
-rw-r--r-- | libstdc++-v3/include/std/type_traits | 104 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/24803.cc | 12 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc | 47 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc | 32 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/ref_neg.cc | 44 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc | 148 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs.cc | 48 |
11 files changed, 463 insertions, 102 deletions
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 <jwakely.gcc@gmail.com> + + 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 <hp@axis.com> 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<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value> - struct _Function_to_function_pointer - { - typedef _Tp type; - }; - - template<typename _Tp> - 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<typename remove_pointer<_Functor>::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<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 + typename result_of<_Functor(_Args&&...)>::type >::type __invoke(_Functor __f, _Args&&... __args) { @@ -263,40 +263,43 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template<bool _Unary, bool _Binary, typename _Tp> 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<typename _Tp> struct _Reference_wrapper_base_impl<false, false, _Tp> : _Weak_result_type<_Tp> { }; - // unary_function but not binary_function + // Nested argument_type only. template<typename _Tp> struct _Reference_wrapper_base_impl<true, false, _Tp> - : unary_function<typename _Tp::argument_type, - typename _Tp::result_type> - { }; + : _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<typename _Tp> struct _Reference_wrapper_base_impl<false, true, _Tp> - : binary_function<typename _Tp::first_argument_type, - typename _Tp::second_argument_type, - typename _Tp::result_type> - { }; + : _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<typename _Tp> struct _Reference_wrapper_base_impl<true, true, _Tp> - : unary_function<typename _Tp::argument_type, - typename _Tp::result_type>, - binary_function<typename _Tp::first_argument_type, - typename _Tp::second_argument_type, - typename _Tp::result_type> + : _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<typename _Tp> 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<typename remove_cv<_Tp>::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... _Args> - 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<const _Tp>(__t); } + template<typename _Tp> + void ref(const _Tp&&) = delete; + + template<typename _Tp> + void cref(const _Tp&&) = delete; + /// Partial specialization. template<typename _Tp> 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<typename result_of<_Fn(_Args...)>::type> async(launch __policy, _Fn&& __fn, _Args&&... __args); + template<typename _FnCheck, typename _Fn, typename... _Args> + struct __async_sfinae_helper + { + typedef future<typename result_of<_Fn(_Args...)>::type> type; + }; + + template<typename _Fn, typename... _Args> + struct __async_sfinae_helper<launch, _Fn, _Args...> + { }; + template<typename _Fn, typename... _Args> typename - enable_if<!is_same<typename decay<_Fn>::type, launch>::value, - future<decltype(std::declval<_Fn>()(std::declval<_Args>()...))> - >::type + __async_sfinae_helper<typename decay<_Fn>::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<typename _Fn, typename... _Args> inline typename - enable_if<!is_same<typename decay<_Fn>::type, launch>::value, - future<decltype(std::declval<_Fn>()(std::declval<_Args>()...))> - >::type + __async_sfinae_helper<typename decay<_Fn>::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<typename _Signature> - class result_of; - - template<typename _Functor, typename... _ArgTypes> - struct result_of<_Functor(_ArgTypes...)> - { - typedef - decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) ) - type; - }; - /// declval template<typename _Tp> struct __declval_protector @@ -1612,6 +1600,98 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __declval_protector<_Tp>::__delegate(); } + /// result_of + template<typename _Signature> + class result_of; + + template<typename _MemPtr, typename _Arg> + struct _Result_of_memobj; + + template<typename _Res, typename _Class, typename _Arg> + struct _Result_of_memobj<_Res _Class::*, _Arg> + { + private: + typedef _Res _Class::* _Func; + + template<typename _Tp> + static _Tp _S_get(const _Class&); + template<typename _Tp> + static decltype(*std::declval<_Tp>()) _S_get(...); + + public: + typedef + decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) + __type; + }; + + template<typename _MemPtr, typename _Arg, typename... _ArgTypes> + struct _Result_of_memfun; + + template<typename _Res, typename _Class, typename _Arg, typename... _Args> + struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...> + { + private: + typedef _Res _Class::* _Func; + + template<typename _Tp> + static _Tp _S_get(const _Class&); + template<typename _Tp> + static decltype(*std::declval<_Tp>()) _S_get(...); + + public: + typedef + decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) + (std::declval<_Args>()...) ) + __type; + }; + + template<bool, bool, typename _Functor, typename... _ArgTypes> + struct _Result_of_impl; + + template<typename _Functor, typename... _ArgTypes> + struct _Result_of_impl<false, false, _Functor, _ArgTypes...> + { + typedef + decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) ) + __type; + }; + + template<typename _MemPtr, typename _Arg> + struct _Result_of_impl<true, false, _MemPtr, _Arg> + : _Result_of_memobj<typename remove_reference<_MemPtr>::type, _Arg> + { + typedef typename _Result_of_memobj< + typename remove_reference<_MemPtr>::type, _Arg>::__type + __type; + }; + + template<typename _MemPtr, typename _Arg, typename... _ArgTypes> + struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...> + : _Result_of_memfun<typename remove_reference<_MemPtr>::type, _Arg, + _ArgTypes...> + { + typedef typename _Result_of_memfun< + typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type + __type; + }; + + template<typename _Functor, typename... _ArgTypes> + struct result_of<_Functor(_ArgTypes...)> + : _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...> + { + 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 // <http://www.gnu.org/licenses/>. -// { dg-error "static assertion failed" "" { target *-*-* } 1610 } +// { dg-error "static assertion failed" "" { target *-*-* } 1598 } #include <utility> 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<double (int)>* pr1(0); verify_return_type((*pr1)(0), double()); std::reference_wrapper<double (*)(int)>* pr2(0); verify_return_type((*pr2)(0), double()); + std::reference_wrapper<int (test_type::*)()>* pr3(0); + verify_return_type((*pr3)(null_tt), int()); + std::reference_wrapper<int (test_type::*)()const>* pr4(0); + verify_return_type((*pr4)(null_ttc), int()); std::reference_wrapper<functor1>* pr5(0); // libstdc++/24803 @@ -62,6 +68,10 @@ void test01() verify_return_type((*pr1b)(0, 0), double()); std::reference_wrapper<double (*)(int, char)>* pr2b(0); verify_return_type((*pr2b)(0, 0), double()); + std::reference_wrapper<int (test_type::*)(char)>* pr3b(0); + verify_return_type((*pr3b)(null_tt,zero), int()); + std::reference_wrapper<int (test_type::*)()const>* pr4b(0); + verify_return_type((*pr4b)(null_ttc), int()); std::reference_wrapper<functor2>* 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 <functional> + +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 +// <http://www.gnu.org/licenses/>. + +// 20.8.3 Class template reference_wrapper + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include <functional> + +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 +// <http://www.gnu.org/licenses/>. + +#include <functional> +#include <type_traits> + +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<typename T> + struct has_arg_type : __has_argument_type<T> + { }; + +template<typename T> + struct has_1st_arg_type : __has_first_argument_type<T> + { }; + +template<typename T> + struct has_2nd_arg_type : __has_second_argument_type<T> + { }; + +template<typename T, bool = has_arg_type<T>::value> +struct test_arg_type +{ + static_assert( !has_arg_type<std::reference_wrapper<T>>::value, + "reference_wrapper has no nested argument_type"); +}; + +template<typename T> +struct test_arg_type<T, true> +{ + typedef std::reference_wrapper<T> ref; + + static_assert( has_arg_type<ref>::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<typename T, + bool = has_1st_arg_type<T>::value && has_2nd_arg_type<T>::value> +struct test_1st_2nd_arg_types +{ + typedef std::reference_wrapper<T> ref; + + static_assert( !has_1st_arg_type<ref>::value, + "reference_wrapper has no nested first_argument_type"); + + static_assert( !has_2nd_arg_type<ref>::value, + "reference_wrapper has no nested second_argument_type"); +}; + +template<typename T> +struct test_1st_2nd_arg_types<T, true> +{ + typedef std::reference_wrapper<T> ref; + + static_assert( has_1st_arg_type<ref>::value, + "reference_wrapper has nested first_argument_type"); + + static_assert( has_2nd_arg_type<ref>::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<typename T> + void test() + { + test_arg_type<T> t; + test_arg_type<const T> tc; + test_arg_type<volatile T> tv; + test_arg_type<const volatile T> tcv; + test_1st_2nd_arg_types<T> t12; + test_1st_2nd_arg_types<const T> t12c; + test_1st_2nd_arg_types<volatile T> t12v; + test_1st_2nd_arg_types<const volatile T> t12cv; + } + +int main() +{ + test<S>(); + test<S0>(); + test<S1>(); + test<S2>(); + test<S01>(); + test<S02>(); + test<S12>(); + test<S012>(); +} + 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 <functional> #include <type_traits> -#include <testsuite_hooks.h> -#include <testsuite_tr1.h> - -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<reference_wrapper<int_result_type>::result_type, int>::value)); - VERIFY((is_same<reference_wrapper<derives_unary>::result_type, int>::value)); - VERIFY((is_same<reference_wrapper<derives_binary>::result_type, int>::value)); - VERIFY((is_same<reference_wrapper<derives_unary_binary>::result_type, int>::value)); - VERIFY((is_same<reference_wrapper<int(void)>::result_type, int>::value)); - VERIFY((is_same<reference_wrapper<int(*)(void)>::result_type, int>::value)); - VERIFY((is_same<reference_wrapper<int (::X::*)()>::result_type, int>::value)); - VERIFY((is_same<reference_wrapper<int (::X::*)(float)>::result_type, int>::value)); - - // Check derivation from unary_function - VERIFY((is_convertible<reference_wrapper<derives_unary>*, unary_function<int, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<derives_unary_binary>*, unary_function<int, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int(int)>*, unary_function<int, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int(*)(int)>*, unary_function<int, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)()>*, unary_function< ::X*, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)() const>*, unary_function<const ::X*, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)() volatile>*, unary_function<volatile ::X*, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)() const volatile>*, unary_function<const volatile ::X*, int>*>::value)); - - // Check derivation from binary_function - VERIFY((is_convertible<reference_wrapper<derives_binary>*, binary_function<int, float, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<derives_unary_binary>*, binary_function<int, float, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int(int, float)>*, binary_function<int, float, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int(*)(int, float)>*, binary_function<int, float, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)(float)>*, binary_function< ::X*, float, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)(float) const>*, binary_function<const ::X*, float, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)(float) volatile>*, binary_function<volatile ::X*, float, int>*>::value)); - VERIFY((is_convertible<reference_wrapper<int (::X::*)(float) const volatile>*, binary_function<const volatile ::X*, float, int>*>::value)); + static_assert( is_same<reference_wrapper<int_result_type>::result_type, int>::value, "has result_type" ); + static_assert( is_same<reference_wrapper<derives_unary>::result_type, int>::value, "has result_type" ); + static_assert( is_same<reference_wrapper<derives_binary>::result_type, int>::value, "has result_type" ); + static_assert( is_same<reference_wrapper<derives_unary_binary>::result_type, int>::value, "has result_type" ); + static_assert( is_same<reference_wrapper<int(void)>::result_type, int>::value, "has result_type" ); + static_assert( is_same<reference_wrapper<int(*)(void)>::result_type, int>::value, "has result_type" ); + static_assert( is_same<reference_wrapper<int (::X::*)()>::result_type, int>::value, "has result_type" ); + static_assert( is_same<reference_wrapper<int (::X::*)(float)>::result_type, int>::value, "has result_type" ); } int main() |