mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-30 15:24:07 +08:00
[multiple changes]
2011-04-30 Daniel Krugler <daniel.kruegler@googlemail.com> * include/std/type_traits (__is_default_constructible_atom, __is_default_constructible_safe<, true>, __is_direct_constructible_new_safe, __is_base_to_derived_ref<,, true>, __is_lvalue_to_rvalue_ref<,, true>, __is_direct_constructible_ref_cast, __is_direct_constructible, __is_nary_constructible): Simplify; add comments throughout. 2011-04-30 Paolo Carlini <paolo.carlini@oracle.com> * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust dg-error line numbers. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. From-SVN: r173222
This commit is contained in:
parent
2ad7ae18f4
commit
2c7a09d774
@ -1,3 +1,20 @@
|
|||||||
|
2011-04-30 Daniel Krugler <daniel.kruegler@googlemail.com>
|
||||||
|
|
||||||
|
* include/std/type_traits (__is_default_constructible_atom,
|
||||||
|
__is_default_constructible_safe<, true>,
|
||||||
|
__is_direct_constructible_new_safe,
|
||||||
|
__is_base_to_derived_ref<,, true>, __is_lvalue_to_rvalue_ref<,, true>,
|
||||||
|
__is_direct_constructible_ref_cast, __is_direct_constructible,
|
||||||
|
__is_nary_constructible): Simplify; add comments throughout.
|
||||||
|
|
||||||
|
2011-04-30 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
|
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
|
||||||
|
Adjust dg-error line numbers.
|
||||||
|
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
|
||||||
|
Likewise.
|
||||||
|
* testsuite/20_util/declval/requirements/1_neg.cc: Likewise.
|
||||||
|
|
||||||
2011-04-30 Doug Kwan <dougkwan@google.com>
|
2011-04-30 Doug Kwan <dougkwan@google.com>
|
||||||
|
|
||||||
* include/Makefile.am (install-freestanding-headers): Also install
|
* include/Makefile.am (install-freestanding-headers): Also install
|
||||||
|
@ -550,7 +550,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
struct __is_array_unknown_bounds
|
struct __is_array_unknown_bounds
|
||||||
: public __and_<is_array<_Tp>, __not_<extent<_Tp>>>::type
|
: public __and_<is_array<_Tp>, __not_<extent<_Tp>>>::type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
|
// In N3290 is_destructible does not say anything about function
|
||||||
|
// types and abstract types, see LWG 2049. This implementation
|
||||||
|
// describes function types as trivially nothrow destructible and
|
||||||
|
// abstract types as destructible, iff the explicit destructor
|
||||||
|
// call expression is wellformed.
|
||||||
struct __do_is_destructible_impl_1
|
struct __do_is_destructible_impl_1
|
||||||
{
|
{
|
||||||
template<typename _Up>
|
template<typename _Up>
|
||||||
@ -571,6 +576,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
typedef decltype(__test<_Tp>(0)) type;
|
typedef decltype(__test<_Tp>(0)) type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Special implementation for abstract types
|
||||||
struct __do_is_destructible_impl_2
|
struct __do_is_destructible_impl_2
|
||||||
{
|
{
|
||||||
template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())>
|
template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())>
|
||||||
@ -632,23 +638,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __is_default_constructible_atom
|
struct __is_default_constructible_atom
|
||||||
: public __and_<is_destructible<_Tp>,
|
: public __and_<__not_<is_void<_Tp>>,
|
||||||
__is_default_constructible_impl<_Tp>>::type::type
|
__is_default_constructible_impl<_Tp>>::type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template<typename _Tp, bool = is_array<_Tp>::value>
|
template<typename _Tp, bool = is_array<_Tp>::value>
|
||||||
struct __is_default_constructible_safe;
|
struct __is_default_constructible_safe;
|
||||||
|
|
||||||
// The following technique is a workaround for a gcc defect, which does
|
// The following technique is a workaround for a current core language
|
||||||
// not sfinae away attempts to default-construct arrays of unknown bounds.
|
// restriction, which does not allow for array types to occur in
|
||||||
// Complete arrays can be default-constructed, if the element type is
|
// functional casts of the form T(). Complete arrays can be default-
|
||||||
// default-constructible, but arrays with unknown bounds are not:
|
// constructed, if the element type is default-constructible, but
|
||||||
|
// arrays with unknown bounds are not.
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __is_default_constructible_safe<_Tp, true>
|
struct __is_default_constructible_safe<_Tp, true>
|
||||||
: public __and_<__is_array_known_bounds<_Tp>,
|
: public __and_<__is_array_known_bounds<_Tp>,
|
||||||
__is_default_constructible_atom<typename
|
__is_default_constructible_atom<typename
|
||||||
remove_all_extents<_Tp>::type>>::type::type
|
remove_all_extents<_Tp>::type>>::type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
@ -663,6 +669,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_Tp>::value)>
|
_Tp>::value)>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
|
|
||||||
|
// Implementation of is_constructible.
|
||||||
|
|
||||||
|
// The hardest part of this trait is the binary direct-initialization
|
||||||
|
// case, because we hit into a functional cast of the form T(arg).
|
||||||
|
// This implementation uses different strategies depending on the
|
||||||
|
// target type to reduce the test overhead as much as possible:
|
||||||
|
//
|
||||||
|
// a) For a reference target type, we use a static_cast expression
|
||||||
|
// modulo its extra cases.
|
||||||
|
//
|
||||||
|
// b) For a non-reference target type we use a ::new expression.
|
||||||
struct __do_is_static_castable_impl
|
struct __do_is_static_castable_impl
|
||||||
{
|
{
|
||||||
template<typename _From, typename _To, typename
|
template<typename _From, typename _To, typename
|
||||||
@ -682,8 +700,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
template<typename _From, typename _To>
|
template<typename _From, typename _To>
|
||||||
struct __is_static_castable_safe
|
struct __is_static_castable_safe
|
||||||
: public __and_<__or_<is_void<_To>, is_destructible<_To>>,
|
: public __is_static_castable_impl<_From, _To>::type
|
||||||
__is_static_castable_impl<_From, _To>>::type::type
|
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// __is_static_castable
|
// __is_static_castable
|
||||||
@ -693,6 +710,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_From, _To>::value)>
|
_From, _To>::value)>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
|
// Implementation for non-reference types. To meet the proper
|
||||||
|
// variable definition semantics, we also need to test for
|
||||||
|
// is_destructible in this case.
|
||||||
struct __do_is_direct_constructible_impl
|
struct __do_is_direct_constructible_impl
|
||||||
{
|
{
|
||||||
template<typename _Tp, typename _Arg, typename
|
template<typename _Tp, typename _Arg, typename
|
||||||
@ -713,7 +733,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
template<typename _Tp, typename _Arg>
|
template<typename _Tp, typename _Arg>
|
||||||
struct __is_direct_constructible_new_safe
|
struct __is_direct_constructible_new_safe
|
||||||
: public __and_<is_destructible<_Tp>,
|
: public __and_<is_destructible<_Tp>,
|
||||||
__is_direct_constructible_impl<_Tp, _Arg>>::type::type
|
__is_direct_constructible_impl<_Tp, _Arg>>::type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template<typename, typename>
|
template<typename, typename>
|
||||||
@ -736,10 +756,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
>::type>::type __src_t;
|
>::type>::type __src_t;
|
||||||
typedef typename remove_cv<typename remove_reference<_To
|
typedef typename remove_cv<typename remove_reference<_To
|
||||||
>::type>::type __dst_t;
|
>::type>::type __dst_t;
|
||||||
typedef typename __and_<
|
typedef __and_<__not_<is_same<__src_t, __dst_t>>,
|
||||||
__not_<is_same<__src_t, __dst_t>>,
|
is_base_of<__src_t, __dst_t>> type;
|
||||||
is_base_of<__src_t, __dst_t>
|
|
||||||
>::type type;
|
|
||||||
static constexpr bool value = type::value;
|
static constexpr bool value = type::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -760,10 +778,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_From>::type>::type __src_t;
|
_From>::type>::type __src_t;
|
||||||
typedef typename remove_cv<typename remove_reference<
|
typedef typename remove_cv<typename remove_reference<
|
||||||
_To>::type>::type __dst_t;
|
_To>::type>::type __dst_t;
|
||||||
typedef typename __or_<
|
typedef __or_<is_same<__src_t, __dst_t>,
|
||||||
is_same<__src_t, __dst_t>,
|
is_base_of<__dst_t, __src_t>> type;
|
||||||
is_base_of<__dst_t, __src_t>
|
|
||||||
>::type type;
|
|
||||||
static constexpr bool value = type::value;
|
static constexpr bool value = type::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -772,25 +788,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
: public false_type
|
: public false_type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Here we handle direct-initialization to a reference type
|
// Here we handle direct-initialization to a reference type as
|
||||||
// as equivalent to a static_cast modulo overshooting conversions.
|
// equivalent to a static_cast modulo overshooting conversions.
|
||||||
// These are restricted to the following conversion:
|
// These are restricted to the following conversions:
|
||||||
// a) A base class to a derived class reference
|
// a) A glvalue of a base class to a derived class reference
|
||||||
// b) An lvalue-reference to an rvalue-reference
|
// b) An lvalue to an rvalue-reference of reference-compatible
|
||||||
|
// types
|
||||||
template<typename _Tp, typename _Arg>
|
template<typename _Tp, typename _Arg>
|
||||||
struct __is_direct_constructible_ref_cast
|
struct __is_direct_constructible_ref_cast
|
||||||
: public __and_<__is_static_castable<_Arg, _Tp>,
|
: public __and_<__is_static_castable<_Arg, _Tp>,
|
||||||
__not_<__or_<__is_base_to_derived_ref<_Arg, _Tp>,
|
__not_<__or_<__is_base_to_derived_ref<_Arg, _Tp>,
|
||||||
__is_lvalue_to_rvalue_ref<_Arg, _Tp>
|
__is_lvalue_to_rvalue_ref<_Arg, _Tp>
|
||||||
>>>::type::type
|
>>>::type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Direct-initialization is tricky, because of functional
|
|
||||||
// casts: For a conversion to reference we fall back to a
|
|
||||||
// static_cast modulo extra cases, otherwise we use a
|
|
||||||
// new expression:
|
|
||||||
|
|
||||||
template<typename _Tp, typename _Arg>
|
template<typename _Tp, typename _Arg>
|
||||||
struct __is_direct_constructible_new
|
struct __is_direct_constructible_new
|
||||||
: public conditional<is_reference<_Tp>::value,
|
: public conditional<is_reference<_Tp>::value,
|
||||||
@ -802,9 +813,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
template<typename _Tp, typename _Arg>
|
template<typename _Tp, typename _Arg>
|
||||||
struct __is_direct_constructible
|
struct __is_direct_constructible
|
||||||
: public integral_constant<bool, (__is_direct_constructible_new<
|
: public integral_constant<bool, (__is_direct_constructible_new<
|
||||||
_Tp, _Arg>::type::value)>
|
_Tp, _Arg>::value)>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
|
// Since default-construction and binary direct-initialization have
|
||||||
|
// been handled separately, the implementation of the remaining
|
||||||
|
// n-ary construction cases is rather straightforward.
|
||||||
struct __do_is_nary_constructible_impl
|
struct __do_is_nary_constructible_impl
|
||||||
{
|
{
|
||||||
template<typename _Tp, typename... _Args, typename
|
template<typename _Tp, typename... _Args, typename
|
||||||
@ -824,9 +838,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
template<typename _Tp, typename... _Args>
|
template<typename _Tp, typename... _Args>
|
||||||
struct __is_nary_constructible
|
struct __is_nary_constructible
|
||||||
: public __and_<is_destructible<_Tp>,
|
: public __is_nary_constructible_impl<_Tp, _Args...>::type
|
||||||
__is_nary_constructible_impl<_Tp, _Args...>
|
|
||||||
>::type::type
|
|
||||||
{
|
{
|
||||||
static_assert(sizeof...(_Args) > 1,
|
static_assert(sizeof...(_Args) > 1,
|
||||||
"Only useful for > 1 arguments");
|
"Only useful for > 1 arguments");
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
// with this library; see the file COPYING3. If not see
|
// with this library; see the file COPYING3. If not see
|
||||||
// <http://www.gnu.org/licenses/>.
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// { dg-error "static assertion failed" "" { target *-*-* } 1603 }
|
// { dg-error "static assertion failed" "" { target *-*-* } 1615 }
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -48,5 +48,5 @@ void test01()
|
|||||||
// { dg-error "instantiated from here" "" { target *-*-* } 40 }
|
// { dg-error "instantiated from here" "" { target *-*-* } 40 }
|
||||||
// { dg-error "instantiated from here" "" { target *-*-* } 42 }
|
// { dg-error "instantiated from here" "" { target *-*-* } 42 }
|
||||||
|
|
||||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1389 }
|
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1401 }
|
||||||
// { dg-error "declaration of" "" { target *-*-* } 1353 }
|
// { dg-error "declaration of" "" { target *-*-* } 1365 }
|
||||||
|
@ -48,5 +48,5 @@ void test01()
|
|||||||
// { dg-error "instantiated from here" "" { target *-*-* } 40 }
|
// { dg-error "instantiated from here" "" { target *-*-* } 40 }
|
||||||
// { dg-error "instantiated from here" "" { target *-*-* } 42 }
|
// { dg-error "instantiated from here" "" { target *-*-* } 42 }
|
||||||
|
|
||||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1313 }
|
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1325 }
|
||||||
// { dg-error "declaration of" "" { target *-*-* } 1277 }
|
// { dg-error "declaration of" "" { target *-*-* } 1289 }
|
||||||
|
Loading…
Reference in New Issue
Block a user