Skip to content

Commit 1c24729

Browse files
1 parent 17cf9b9 commit 1c24729

6 files changed

Lines changed: 143 additions & 2 deletions

File tree

stl/inc/memory

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4529,6 +4529,63 @@ _NODISCARD auto inout_ptr(_SmartPtr& _Smart_ptr, _ArgsT&&... _Args) {
45294529
return inout_ptr_t<_SmartPtr, _Pointer, _ArgsT&&...>(_Smart_ptr, _STD forward<_ArgsT>(_Args)...);
45304530
}
45314531
}
4532+
4533+
#ifdef __cpp_lib_start_lifetime_as // TRANSITION
4534+
template <class _Ty>
4535+
_Ty* start_lifetime_as(void* const _Ptr) noexcept {
4536+
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
4537+
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
4538+
#endif // ^^^ no workaround ^^^
4539+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
4540+
return __builtin_start_lifetime_as<_Ty>(_Ptr);
4541+
}
4542+
template <class _Ty>
4543+
const _Ty* start_lifetime_as(const void* const _Ptr) noexcept {
4544+
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
4545+
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
4546+
#endif // ^^^ no workaround ^^^
4547+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
4548+
return __builtin_start_lifetime_as<_Ty>(_Ptr);
4549+
}
4550+
template <class _Ty>
4551+
volatile _Ty* start_lifetime_as(volatile void* const _Ptr) noexcept {
4552+
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
4553+
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
4554+
#endif // ^^^ no workaround ^^^
4555+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
4556+
return __builtin_start_lifetime_as<_Ty>(_Ptr);
4557+
}
4558+
template <class _Ty>
4559+
const volatile _Ty* start_lifetime_as(const volatile void* const _Ptr) noexcept {
4560+
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
4561+
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
4562+
#endif // ^^^ no workaround ^^^
4563+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
4564+
return __builtin_start_lifetime_as<_Ty>(_Ptr);
4565+
}
4566+
4567+
template <class _Ty>
4568+
_Ty* start_lifetime_as_array(void* const _Ptr, const size_t _Nx) noexcept {
4569+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
4570+
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
4571+
}
4572+
template <class _Ty>
4573+
const _Ty* start_lifetime_as_array(const void* const _Ptr, const size_t _Nx) noexcept {
4574+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
4575+
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
4576+
}
4577+
template <class _Ty>
4578+
volatile _Ty* start_lifetime_as_array(volatile void* const _Ptr, const size_t _Nx) noexcept {
4579+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
4580+
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
4581+
}
4582+
template <class _Ty>
4583+
const volatile _Ty* start_lifetime_as_array(const volatile void* const _Ptr, const size_t _Nx) noexcept {
4584+
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
4585+
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
4586+
}
4587+
#endif // ^^^ defined(__cpp_lib_start_lifetime_as) ^^^
4588+
45324589
#endif // _HAS_CXX23
45334590
_STD_END
45344591

stl/inc/yvals_core.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,12 +389,14 @@
389389
// P2540R1 Empty Product For Certain Views
390390
// P2549R1 unexpected<E>::error()
391391
// P2585R1 Improve Default Container Formatting
392+
// P2590R2 Explicit Lifetime Management
392393
// P2599R2 mdspan: index_type, size_type
393394
// P2604R0 mdspan: data_handle_type, data_handle(), exhaustive
394395
// P2613R1 mdspan: empty()
395396
// P2614R2 Deprecating float_denorm_style, numeric_limits::has_denorm, numeric_limits::has_denorm_loss
396397
// P2652R2 Disallowing User Specialization Of allocator_traits
397398
// P2674R1 is_implicit_lifetime
399+
// P2679R2 Fixing start_lifetime_as And start_lifetime_as_array
398400
// P2693R1 Formatting thread::id And stacktrace
399401
// P2713R1 Escaping Improvements In std::format
400402
// P2763R1 Fixing layout_stride's Default Constructor For Fully Static Extents
@@ -1788,8 +1790,13 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
17881790
#define __cpp_lib_reference_from_temporary 202202L
17891791
#endif // ^^^ no workaround ^^^
17901792

1791-
#define __cpp_lib_spanstream 202106L
1792-
#define __cpp_lib_stacktrace 202011L
1793+
#define __cpp_lib_spanstream 202106L
1794+
#define __cpp_lib_stacktrace 202011L
1795+
1796+
#if !defined(__clang__) && !defined(__EDG__) && _MSC_VER >= 1951 // TRANSITION, GH-6169, toolset update
1797+
#define __cpp_lib_start_lifetime_as 202207L
1798+
#endif // ^^^ no workaround ^^^
1799+
17931800
#define __cpp_lib_stdatomic_h 202011L
17941801
#define __cpp_lib_string_contains 202011L
17951802
#define __cpp_lib_string_resize_and_overwrite 202110L

tests/std/test.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ tests\P2505R5_monadic_functions_for_std_expected
727727
tests\P2510R3_text_formatting_pointers
728728
tests\P2517R1_apply_conditional_noexcept
729729
tests\P2538R1_adl_proof_std_projected
730+
tests\P2590R2_explicit_lifetime_management
730731
tests\P2609R3_relaxing_ranges_just_a_smidge
731732
tests\P2674R1_is_implicit_lifetime
732733
tests\P2693R1_ostream_and_thread_id
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
RUNALL_INCLUDE ..\usual_latest_matrix.lst
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include <cassert>
5+
#include <concepts>
6+
#include <memory>
7+
using namespace std;
8+
9+
#ifdef __cpp_lib_start_lifetime_as // TRANSITION
10+
struct Point {
11+
int x;
12+
int y;
13+
};
14+
static_assert(alignof(Point) == alignof(int));
15+
static_assert(sizeof(Point) == 2 * sizeof(int));
16+
17+
template <class CvVoidPtr, class CvPointPtr>
18+
void test_scalar() {
19+
int arr[2]{17, 29};
20+
21+
const auto cv_void_ptr = static_cast<CvVoidPtr>(arr);
22+
23+
static_assert(noexcept(start_lifetime_as<Point>(cv_void_ptr)));
24+
const same_as<CvPointPtr> auto cv_point_ptr = start_lifetime_as<Point>(cv_void_ptr);
25+
26+
assert(cv_point_ptr->x == 17);
27+
assert(cv_point_ptr->y == 29);
28+
}
29+
30+
template <class CvVoidPtr, class CvPointPtr>
31+
void test_array() {
32+
{
33+
// N5032 [obj.lifetime]/6: "Preconditions: p is suitably aligned for an array of T or is null."
34+
// N5032 [obj.lifetime]/7: "Effects: If n > 0 is true, [...]. Otherwise, there are no effects."
35+
const same_as<CvPointPtr> auto nil = start_lifetime_as_array<Point>(static_cast<CvVoidPtr>(nullptr), 0);
36+
assert(nil == nullptr); // N5032 [obj.lifetime]/8: "otherwise, a pointer that compares equal to p"
37+
}
38+
39+
int arr[4]{17, 29, 123, 456};
40+
41+
const auto cv_void_ptr = static_cast<CvVoidPtr>(arr);
42+
43+
static_assert(noexcept(start_lifetime_as_array<Point>(cv_void_ptr, 2)));
44+
const same_as<CvPointPtr> auto cv_point_ptr = start_lifetime_as_array<Point>(cv_void_ptr, 2);
45+
46+
assert(cv_point_ptr[0].x == 17);
47+
assert(cv_point_ptr[0].y == 29);
48+
assert(cv_point_ptr[1].x == 123);
49+
assert(cv_point_ptr[1].y == 456);
50+
}
51+
52+
template <class CvVoidPtr, class CvPointPtr>
53+
void test() {
54+
test_scalar<CvVoidPtr, CvPointPtr>();
55+
test_array<CvVoidPtr, CvPointPtr>();
56+
}
57+
58+
int main() {
59+
test<void*, Point*>();
60+
test<const void*, const Point*>();
61+
test<volatile void*, volatile Point*>();
62+
test<const volatile void*, const volatile Point*>();
63+
}
64+
#else // ^^^ no workaround / workaround vvv
65+
int main() {}
66+
#endif // ^^^ workaround ^^^

tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,12 @@ STATIC_ASSERT(__cpp_lib_stacktrace == 202011L);
945945
#error __cpp_lib_stacktrace is defined
946946
#endif
947947

948+
#if _HAS_CXX23 && !defined(__clang__) && !defined(__EDG__) // TRANSITION, GH-6169 tracking LLVM-105234 and VSO-2846756
949+
STATIC_ASSERT(__cpp_lib_start_lifetime_as == 202207L);
950+
#elif defined(__cpp_lib_start_lifetime_as)
951+
#error __cpp_lib_start_lifetime_as is defined
952+
#endif
953+
948954
#if _HAS_CXX20
949955
STATIC_ASSERT(__cpp_lib_starts_ends_with == 201711L);
950956
#elif defined(__cpp_lib_starts_ends_with)

0 commit comments

Comments
 (0)