Skip to content

Commit 6d9dfd7

Browse files
H-G-HristovZingam
andauthored
[libc++][type_traits] Implements "A type trait to detect reference binding to temporary" (#128649)
Implements partially: [P2255R2: A type trait to detect reference binding to temporary](https://wg21.link/P2255R2) Issue: #105180 https://eel.is/c++draft/meta.type.synop https://eel.is/c++draft/meta.unary.prop Implented type traits: - [x] `reference_constructs_from_temporary` - [x] `reference_converts_from_temporary` Closes #129049 Minor drive-by tweak to `std::is_implicit_lifetime` tests. --------- Co-authored-by: Hristo Hristov <[email protected]>
1 parent 3b8f9a2 commit 6d9dfd7

File tree

13 files changed

+337
-10
lines changed

13 files changed

+337
-10
lines changed

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Implemented Papers
4141
- N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
4242
- P0767R1: Deprecate POD (`Github <https://github.com/llvm/llvm-project/issues/104013>`__)
4343
- P1361R2: Integration of chrono with text formatting (`Github <https://github.com/llvm/llvm-project/issues/100014>`__)
44+
- P2255R2: A type trait to detect reference binding to temporary (implemented the type traits only) (`Github <https://github.com/llvm/llvm-project/issues/105180>`)
4445

4546
Improvements and New Features
4647
-----------------------------

libcxx/docs/Status/Cxx23Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"`P0627R6 <https://wg21.link/P0627R6>`__","Function to mark unreachable code","2022-02 (Virtual)","|Complete|","15",""
4444
"`P1206R7 <https://wg21.link/P1206R7>`__","``ranges::to``: A function to convert any range to a container","2022-02 (Virtual)","|Complete|","17",""
4545
"`P1413R3 <https://wg21.link/P1413R3>`__","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","2022-02 (Virtual)","|Complete|","","``std::aligned_storage_t`` and ``std::aligned_union_t`` are marked deprecated, but clang doesn't issue a diagnostic for deprecated using template declarations."
46-
"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","","",""
46+
"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","|Partial|","","Implemented the type traits only."
4747
"`P2273R3 <https://wg21.link/P2273R3>`__","Making ``std::unique_ptr`` constexpr","2022-02 (Virtual)","|Complete|","16",""
4848
"`P2387R3 <https://wg21.link/P2387R3>`__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19",""
4949
"`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","","",""

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,8 @@ set(files
867867
__type_traits/negation.h
868868
__type_traits/promote.h
869869
__type_traits/rank.h
870+
__type_traits/reference_constructs_from_temporary.h
871+
__type_traits/reference_converts_from_temporary.h
870872
__type_traits/remove_all_extents.h
871873
__type_traits/remove_const.h
872874
__type_traits/remove_const_ref.h
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
10+
#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
11+
12+
#include <__config>
13+
#include <__type_traits/integral_constant.h>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
_LIBCPP_BEGIN_NAMESPACE_STD
20+
21+
#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
22+
23+
template <class _Tp, class _Up>
24+
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_constructs_from_temporary
25+
: public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> {};
26+
27+
template <class _Tp, class _Up>
28+
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_constructs_from_temporary_v =
29+
__reference_constructs_from_temporary(_Tp, _Up);
30+
31+
#endif
32+
33+
_LIBCPP_END_NAMESPACE_STD
34+
35+
#endif // _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
10+
#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
11+
12+
#include <__config>
13+
#include <__type_traits/integral_constant.h>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
_LIBCPP_BEGIN_NAMESPACE_STD
20+
21+
#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_converts_from_temporary)
22+
23+
template <class _Tp, class _Up>
24+
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_converts_from_temporary
25+
: public bool_constant<__reference_converts_from_temporary(_Tp, _Up)> {};
26+
27+
template <class _Tp, class _Up>
28+
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_converts_from_temporary_v =
29+
__reference_converts_from_temporary(_Tp, _Up);
30+
31+
#endif
32+
33+
_LIBCPP_END_NAMESPACE_STD
34+
35+
#endif // _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H

libcxx/include/module.modulemap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,14 @@ module std_core [system] {
369369
module negation { header "__type_traits/negation.h" }
370370
module promote { header "__type_traits/promote.h" }
371371
module rank { header "__type_traits/rank.h" }
372+
module reference_constructs_from_temporary {
373+
header "__type_traits/reference_constructs_from_temporary.h"
374+
export std_core.type_traits.integral_constant
375+
}
376+
module reference_converts_from_temporary {
377+
header "__type_traits/reference_converts_from_temporary.h"
378+
export std_core.type_traits.integral_constant
379+
}
372380
module remove_all_extents { header "__type_traits/remove_all_extents.h" }
373381
module remove_const_ref { header "__type_traits/remove_const_ref.h" }
374382
module remove_const { header "__type_traits/remove_const.h" }

libcxx/include/type_traits

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ namespace std
143143
144144
template<class T> struct has_unique_object_representations; // C++17
145145
146+
template<class T, class U> struct reference_constructs_from_temporary; // Since C++23
147+
template<class T, class U> struct reference_converts_from_temporary; // Since C++23
148+
146149
// Relationships between types:
147150
template <class T, class U> struct is_same;
148151
template <class Base, class Derived> struct is_base_of;
@@ -382,6 +385,12 @@ namespace std
382385
= has_virtual_destructor<T>::value; // C++17
383386
template<class T> inline constexpr bool has_unique_object_representations_v // C++17
384387
= has_unique_object_representations<T>::value;
388+
template<class T, class U>
389+
constexpr bool reference_constructs_from_temporary_v
390+
= reference_constructs_from_temporary<T, U>::value; // Since C++23
391+
template<class T, class U>
392+
constexpr bool reference_converts_from_temporary_v
393+
= reference_converts_from_temporary<T, U>::value; // Since C++23
385394
386395
// See C++14 20.10.5, type property queries
387396
template <class T> inline constexpr size_t alignment_of_v
@@ -523,6 +532,8 @@ namespace std
523532

524533
# if _LIBCPP_STD_VER >= 23
525534
# include <__type_traits/is_implicit_lifetime.h>
535+
# include <__type_traits/reference_constructs_from_temporary.h>
536+
# include <__type_traits/reference_converts_from_temporary.h>
526537
# endif
527538

528539
# include <version>

libcxx/modules/std/type_traits.inc

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,14 @@ export namespace std {
106106

107107
using std::has_unique_object_representations;
108108

109-
// using std::reference_constructs_from_temporary;
110-
// using std::reference_converts_from_temporary;
109+
#if _LIBCPP_STD_VER >= 23
110+
# if __has_builtin(__reference_constructs_from_temporary)
111+
using std::reference_constructs_from_temporary;
112+
# endif
113+
# if __has_builtin(__reference_converts_from_temporary)
114+
using std::reference_converts_from_temporary;
115+
# endif
116+
#endif
111117

112118
// [meta.unary.prop.query], type property queries
113119
using std::alignment_of;
@@ -284,8 +290,14 @@ export namespace std {
284290
using std::is_unbounded_array_v;
285291
using std::is_unsigned_v;
286292
using std::is_volatile_v;
287-
// using std::reference_constructs_from_temporary_v;
288-
// using std::reference_converts_from_temporary_v;
293+
#if _LIBCPP_STD_VER >= 23
294+
# if __has_builtin(__reference_constructs_from_temporary)
295+
using std::reference_constructs_from_temporary_v;
296+
# endif
297+
# if __has_builtin(__reference_converts_from_temporary)
298+
using std::reference_converts_from_temporary_v;
299+
# endif
300+
#endif
289301

290302
// [meta.unary.prop.query], type property queries
291303
using std::alignment_of_v;

libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,52 @@ struct A {
3939
A& operator=(const A&);
4040
};
4141

42-
class Abstract
43-
{
44-
virtual ~Abstract() = 0;
42+
class Abstract {
43+
virtual ~Abstract() = 0;
4544
};
4645

46+
// Types for reference_{constructs/converts}_from_temporary
47+
48+
#if TEST_STD_VER >= 23
49+
50+
class NonPODClass {
51+
public:
52+
NonPODClass(int);
53+
};
54+
enum Enum { EV };
55+
struct Base {
56+
Enum e;
57+
int i;
58+
float f;
59+
NonPODClass* p;
60+
};
61+
// Not PODs
62+
struct Derived : Base {};
63+
64+
template <class T, class RefType = T&>
65+
class ConvertsToRef {
66+
public:
67+
operator RefType() const { return static_cast<RefType>(obj); }
68+
mutable T obj = 42;
69+
};
70+
template <class T, class RefType = T&>
71+
class ConvertsToRefPrivate {
72+
operator RefType() const { return static_cast<RefType>(obj); }
73+
mutable T obj = 42;
74+
};
75+
76+
class ExplicitConversionRvalueRef {
77+
public:
78+
operator int();
79+
explicit operator int&&();
80+
};
81+
82+
class ExplicitConversionRef {
83+
public:
84+
operator int();
85+
explicit operator int&();
86+
};
87+
88+
#endif
89+
4790
#endif // TEST_META_UNARY_COMP_COMMON_H

libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
1010

1111
// These compilers don't support __builtin_is_implicit_lifetime yet.
12-
// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16, apple-clang-17
12+
// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16
1313

1414
// <type_traits>
1515

0 commit comments

Comments
 (0)