Skip to content

Commit ab19068

Browse files
committed
[libc++] Add is_nothrow_convertible from P0758R1
Reviewed as https://reviews.llvm.org/D58019. Thanks to Zoe Carver for the patch. llvm-svn: 355010
1 parent 2dca653 commit ab19068

File tree

3 files changed

+88
-1
lines changed

3 files changed

+88
-1
lines changed

libcxx/include/type_traits

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ namespace std
143143
// Relationships between types:
144144
template <class T, class U> struct is_same;
145145
template <class Base, class Derived> struct is_base_of;
146+
146147
template <class From, class To> struct is_convertible;
148+
template <typename From, typename To> struct is_nothrow_convertible; // C++20
149+
template <typename From, typename To> inline constexpr bool is_nothrow_convertible_v; // C++20
147150
148151
template <class Fn, class... ArgTypes> struct is_invocable;
149152
template <class R, class Fn, class... ArgTypes> struct is_invocable_r;
@@ -1578,6 +1581,32 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_convertible_v
15781581
= is_convertible<_From, _To>::value;
15791582
#endif
15801583

1584+
// is_nothrow_convertible
1585+
1586+
#if _LIBCPP_STD_VER > 17
1587+
1588+
template <typename _Tp>
1589+
static void __test_noexcept(_Tp) noexcept;
1590+
1591+
template<typename _Fm, typename _To>
1592+
static bool_constant<noexcept(__test_noexcept<_To>(declval<_Fm>()))>
1593+
__is_nothrow_convertible_test();
1594+
1595+
template <typename _Fm, typename _To>
1596+
struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>())
1597+
{ };
1598+
1599+
template <typename _Fm, typename _To>
1600+
struct is_nothrow_convertible : __or_<
1601+
__and_<is_void<_To>, is_void<_Fm>>,
1602+
__and_<is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>>
1603+
>::type { };
1604+
1605+
template <typename _Fm, typename _To>
1606+
inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value;
1607+
1608+
#endif // _LIBCPP_STD_VER > 17
1609+
15811610
// is_empty
15821611

15831612
#if __has_feature(is_empty) || (_GNUC_VER >= 407)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
10+
// <type_traits>
11+
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
12+
13+
#include <type_traits>
14+
15+
struct A {};
16+
struct B {
17+
public:
18+
operator A() { return a; } A a;
19+
};
20+
21+
class C { };
22+
class D {
23+
public:
24+
operator C() noexcept { return c; } C c;
25+
};
26+
27+
int main(int, char**) {
28+
static_assert((std::is_nothrow_convertible<int, double>::value), "");
29+
static_assert(!(std::is_nothrow_convertible<int, char*>::value), "");
30+
31+
static_assert(!(std::is_nothrow_convertible<A, B>::value), "");
32+
static_assert((std::is_nothrow_convertible<D, C>::value), "");
33+
34+
static_assert((std::is_nothrow_convertible_v<int, double>), "");
35+
static_assert(!(std::is_nothrow_convertible_v<int, char*>), "");
36+
37+
static_assert(!(std::is_nothrow_convertible_v<A, B>), "");
38+
static_assert((std::is_nothrow_convertible_v<D, C>), "");
39+
40+
static_assert((std::is_nothrow_convertible_v<const void, void>), "");
41+
static_assert((std::is_nothrow_convertible_v<volatile void, void>), "");
42+
static_assert((std::is_nothrow_convertible_v<void, const void>), "");
43+
static_assert((std::is_nothrow_convertible_v<void, volatile void>), "");
44+
45+
static_assert(!(std::is_nothrow_convertible_v<int[], double[]>), "");
46+
static_assert(!(std::is_nothrow_convertible_v<int[], int[]>), "");
47+
static_assert(!(std::is_nothrow_convertible_v<int[10], int[10]>), "");
48+
static_assert(!(std::is_nothrow_convertible_v<int[10], double[10]>), "");
49+
static_assert(!(std::is_nothrow_convertible_v<int[5], double[10]>), "");
50+
static_assert(!(std::is_nothrow_convertible_v<int[10], A[10]>), "");
51+
52+
typedef void V();
53+
typedef int I();
54+
static_assert(!(std::is_nothrow_convertible_v<V, V>), "");
55+
static_assert(!(std::is_nothrow_convertible_v<V, I>), "");
56+
57+
return 0;
58+
}

libcxx/www/cxx2a_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ <h3>Paper Status</h3>
9292
<tr><td><a href="https://wg21.link/P0619R4">P0619R4</a></td><td>LWG</td><td>Reviewing Deprecated Facilities of C++17 for C++20</td><td>Rapperswil</td><td></td><td></td></tr>
9393
<tr><td><a href="https://wg21.link/P0646R1">P0646R1</a></td><td>LWG</td><td>Improving the Return Value of Erase-Like Algorithms</td><td>Rapperswil</td><td></td><td></td></tr>
9494
<tr><td><a href="https://wg21.link/P0722R3">P0722R3</a></td><td>CWG</td><td>Efficient sized delete for variable sized classes</td><td>Rapperswil</td><td></td><td></td></tr>
95-
<tr><td><a href="https://wg21.link/P0758R1">P0758R1</a></td><td>LWG</td><td>Implicit conversion traits and utility functions</td><td>Rapperswil</td><td></td><td></td></tr>
95+
<tr><td><a href="https://wg21.link/P0758R1">P0758R1</a></td><td>LWG</td><td>Implicit conversion traits and utility functions</td><td>Rapperswil</td><td>Complete</td><td></td></tr>
9696
<tr><td><a href="https://wg21.link/P0759R1">P0759R1</a></td><td>LWG</td><td>fpos Requirements</td><td>Rapperswil</td><td></td><td></td></tr>
9797
<tr><td><a href="https://wg21.link/P0769R2">P0769R2</a></td><td>LWG</td><td>Add shift to &lt;algorithm&gt;</td><td>Rapperswil</td><td></td><td></td></tr>
9898
<tr><td><a href="https://wg21.link/P0788R3">P0788R3</a></td><td>LWG</td><td>Standard Library Specification in a Concepts and Contracts World</td><td>Rapperswil</td><td></td><td></td></tr>

0 commit comments

Comments
 (0)