re PR libstdc++/48521 ([C++0x] std::result_of doesn't work with pointer to member)
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. From-SVN: r172709
This commit is contained in:
parent
d39132ea9b
commit
be7f782278
11 changed files with 463 additions and 102 deletions
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
47
libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc
Normal file
47
libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc
Normal file
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
44
libstdc++-v3/testsuite/20_util/reference_wrapper/ref_neg.cc
Normal file
44
libstdc++-v3/testsuite/20_util/reference_wrapper/ref_neg.cc
Normal file
|
@ -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 "" }
|
148
libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc
Normal file
148
libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc
Normal file
|
@ -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>();
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Reference in a new issue