P0758R1 Implicit conversion traits

Extend __is_convertible_helper to also detect whether the conversion is
non-throwing, for std::is_nothrow_convertible in C++2a,

	* include/std/type_traits [__cplusplus > 201703]
	(__is_convertible_helper::__is_nothrow_type): Define new member.
	(__is_convertible_helper<_From, _To, false>::__test_aux1): Add
	noexcept.
	(__is_convertible_helper<_From, _To, false>::__test_nothrow)
	(__is_convertible_helper<_From, _To, false>::__is_nothrow_type): Add
	new members.
	(is_nothrow_convertible, is_nothrow_convertible_v): Define for C++2a.
	* testsuite/20_util/is_nothrow_convertible/value.cc: New.
	* testsuite/20_util/is_nothrow_convertible/requirements/
	explicit_instantiation.cc: New.
	* testsuite/20_util/is_nothrow_convertible/requirements/typedefs.cc:
	New.

From-SVN: r262322
This commit is contained in:
Jonathan Wakely 2018-07-02 23:09:25 +01:00 committed by Jonathan Wakely
parent a5eae716f6
commit 8df27fcb91
7 changed files with 291 additions and 5 deletions

View File

@ -1,5 +1,20 @@
2018-07-02 Jonathan Wakely <jwakely@redhat.com>
P0758R1 Implicit conversion traits
* include/std/type_traits [__cplusplus > 201703]
(__is_convertible_helper::__is_nothrow_type): Define new member.
(__is_convertible_helper<_From, _To, false>::__test_aux1): Add
noexcept.
(__is_convertible_helper<_From, _To, false>::__test_nothrow)
(__is_convertible_helper<_From, _To, false>::__is_nothrow_type): Add
new members.
(is_nothrow_convertible, is_nothrow_convertible_v): Define for C++2a.
* testsuite/20_util/is_nothrow_convertible/value.cc: New.
* testsuite/20_util/is_nothrow_convertible/requirements/
explicit_instantiation.cc: New.
* testsuite/20_util/is_nothrow_convertible/requirements/typedefs.cc:
New.
P0887R1 The identity metafunction
* include/std/type_traits (type_identity, type_identity_t): Define
for C++2a.

View File

@ -1341,13 +1341,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool = __or_<is_void<_From>, is_function<_To>,
is_array<_To>>::value>
struct __is_convertible_helper
{ typedef typename is_void<_To>::type type; };
{
typedef typename is_void<_To>::type type;
#if __cplusplus > 201703L
typedef type __is_nothrow_type;
#endif
};
template<typename _From, typename _To>
class __is_convertible_helper<_From, _To, false>
{
template<typename _To1>
static void __test_aux(_To1);
template<typename _To1>
static void __test_aux(_To1) noexcept;
template<typename _From1, typename _To1,
typename = decltype(__test_aux<_To1>(std::declval<_From1>()))>
@ -1358,8 +1363,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static false_type
__test(...);
#if __cplusplus > 201703L
template<typename _From1, typename _To1,
bool _NoEx = noexcept(__test_aux<_To1>(std::declval<_From1>()))>
static __bool_constant<_NoEx>
__test_nothrow(int);
template<typename, typename>
static false_type
__test_nothrow(...);
#endif
public:
typedef decltype(__test<_From, _To>(0)) type;
#if __cplusplus > 201703L
typedef decltype(__test_nothrow<_From, _To>(0)) __is_nothrow_type;
#endif
};
@ -1369,6 +1389,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: public __is_convertible_helper<_From, _To>::type
{ };
#if __cplusplus > 201703L
/// is_nothrow_convertible
template<typename _From, typename _To>
struct is_nothrow_convertible
: public __is_convertible_helper<_From, _To>::__is_nothrow_type
{ };
/// is_nothrow_convertible_v
template<typename _From, typename _To>
inline constexpr bool is_nothrow_convertible_v
= is_nothrow_convertible<_From, _To>::value;
#endif // C++2a
// Const-volatile modifications.

View File

@ -0,0 +1,29 @@
// Copyright (C) 2018 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/>.
// { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } }
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>
namespace std
{
typedef short test_type;
template struct is_nothrow_convertible<test_type, test_type>;
}

View File

@ -0,0 +1,33 @@
// Copyright (C) 2018 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/>.
// { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } }
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>
void test01()
{
// Check for required typedefs
typedef std::is_nothrow_convertible<int, int> test_type;
typedef test_type::value_type value_type;
typedef test_type::type type;
typedef test_type::type::value_type type_value_type;
typedef test_type::type::type type_type;
}

View File

@ -0,0 +1,177 @@
// Copyright (C) 2018 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/>.
// { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } }
#include <type_traits>
#include <testsuite_tr1.h>
void test01()
{
using std::is_nothrow_convertible;
using namespace __gnu_test;
// Positive conversion tests.
static_assert(test_relationship<is_nothrow_convertible,
int, int>(true));
static_assert(test_relationship<is_nothrow_convertible,
int, const int>(true));
static_assert(test_relationship<is_nothrow_convertible,
volatile int, const int>(true));
static_assert(test_relationship<is_nothrow_convertible,
int, float>(true));
static_assert(test_relationship<is_nothrow_convertible,
double, float>(true));
static_assert(test_relationship<is_nothrow_convertible,
float, int>(true));
static_assert(test_relationship<is_nothrow_convertible,
int*, const int*>(true));
static_assert(test_relationship<is_nothrow_convertible,
int*, void*>(true));
static_assert(test_relationship<is_nothrow_convertible,
int[4], int*>(true));
static_assert(test_relationship<is_nothrow_convertible,
float&, int>(true));
static_assert(test_relationship<is_nothrow_convertible,
int, const int&>(true));
static_assert(test_relationship<is_nothrow_convertible,
const int&, int>(true));
static_assert(test_relationship<is_nothrow_convertible,
float, const int&>(true));
static_assert(test_relationship<is_nothrow_convertible,
int(int), int(*)(int)>(true));
static_assert(test_relationship<is_nothrow_convertible,
int(&)(int), int(*)(int)>(true));
static_assert(test_relationship<is_nothrow_convertible,
EnumType, int>(true));
static_assert(test_relationship<is_nothrow_convertible,
ClassType, ClassType>(true));
static_assert(test_relationship<is_nothrow_convertible,
DerivedType, ClassType>(true));
static_assert(test_relationship<is_nothrow_convertible,
DerivedType*, ClassType*>(true));
static_assert(test_relationship<is_nothrow_convertible,
DerivedType&, ClassType&>(true));
static_assert(test_relationship<is_nothrow_convertible,
const int, const int&>(true));
static_assert(test_relationship<is_nothrow_convertible,
void, void>(true));
static_assert(test_relationship<is_nothrow_convertible,
const void, void>(true));
static_assert(test_relationship<is_nothrow_convertible,
void, volatile void>(true));
static_assert(test_relationship<is_nothrow_convertible,
double&, NoexceptExplicitClass>(true));
static_assert(test_relationship<is_nothrow_convertible,
NoexceptCopyConsClass,
NoexceptCopyConsClass>(true));
static_assert(test_relationship<is_nothrow_convertible,
const NoexceptCopyConsClass,
NoexceptCopyConsClass>(true));
static_assert(test_relationship<is_nothrow_convertible,
const NoexceptCopyConsClass&,
NoexceptCopyConsClass>(true));
static_assert(test_relationship<is_nothrow_convertible,
NoexceptMoveConsClass,
NoexceptMoveConsClass>(true));
static_assert(test_relationship<is_nothrow_convertible,
int(int), int(&)(int)>(true));
// Negative conversion tests.
static_assert(test_relationship<is_nothrow_convertible,
const int*, int*>(false));
static_assert(test_relationship<is_nothrow_convertible,
int*, float*>(false));
static_assert(test_relationship<is_nothrow_convertible,
const int[4], int*>(false));
static_assert(test_relationship<is_nothrow_convertible,
int[4], int[4]>(false));
static_assert(test_relationship<is_nothrow_convertible,
const int&, int&>(false));
static_assert(test_relationship<is_nothrow_convertible,
float&, int&>(false));
static_assert(test_relationship<is_nothrow_convertible,
float, volatile int&>(false));
static_assert(test_relationship<is_nothrow_convertible,
int(int), int(int)>(false));
static_assert(test_relationship<is_nothrow_convertible,
int(int), int(*)(void)>(false));
static_assert(test_relationship<is_nothrow_convertible,
int(*)(int), int(&)(int)>(false));
static_assert(test_relationship<is_nothrow_convertible,
int, EnumType>(false));
static_assert(test_relationship<is_nothrow_convertible,
int, ClassType>(false));
static_assert(test_relationship<is_nothrow_convertible,
ClassType, DerivedType>(false));
static_assert(test_relationship<is_nothrow_convertible,
ClassType*, DerivedType*>(false));
static_assert(test_relationship<is_nothrow_convertible,
ClassType&, DerivedType&>(false));
static_assert(test_relationship<is_nothrow_convertible,
void, int>(false));
static_assert(test_relationship<is_nothrow_convertible,
void, float>(false));
static_assert(test_relationship<is_nothrow_convertible,
void, int(*)(int)>(false));
// C++0x
static_assert(test_relationship<is_nothrow_convertible,
int, void>(false));
static_assert(test_relationship<is_nothrow_convertible,
int[4], void>(false));
static_assert(test_relationship<is_nothrow_convertible,
int, int&>(false));
static_assert(test_relationship<is_nothrow_convertible,
float, volatile float&>(false));
static_assert(test_relationship<is_nothrow_convertible,
const volatile int,
const volatile int&>(false));
static_assert(test_relationship<is_nothrow_convertible,
volatile int, volatile int&>(false));
static_assert(test_relationship<is_nothrow_convertible,
double&, ExplicitClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
int&, ExplicitClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
void*, ExplicitClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
ExceptCopyConsClass,
ExceptCopyConsClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
const ExceptCopyConsClass,
ExceptCopyConsClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
const ExceptCopyConsClass&,
ExceptCopyConsClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
ExceptMoveConsClass,
ExceptMoveConsClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
ExceptMoveConsClass&,
ExceptMoveConsClass>(false));
static_assert(test_relationship<is_nothrow_convertible,
NoexceptMoveConsClass&,
NoexceptMoveConsClass>(false));
}

View File

@ -47,4 +47,4 @@ void test01()
// { dg-error "required from here" "" { target *-*-* } 39 }
// { dg-error "required from here" "" { target *-*-* } 41 }
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1793 }
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1825 }

View File

@ -47,5 +47,5 @@ void test01()
// { dg-error "required from here" "" { target *-*-* } 39 }
// { dg-error "required from here" "" { target *-*-* } 41 }
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1676 }
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1708 }