Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -4529,6 +4529,63 @@ _NODISCARD auto inout_ptr(_SmartPtr& _Smart_ptr, _ArgsT&&... _Args) {
return inout_ptr_t<_SmartPtr, _Pointer, _ArgsT&&...>(_Smart_ptr, _STD forward<_ArgsT>(_Args)...);
}
}

#ifdef __cpp_lib_start_lifetime_as // TRANSITION
template <class _Ty>
_Ty* start_lifetime_as(void* const _Ptr) noexcept {
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
#endif // ^^^ no workaround ^^^
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
return __builtin_start_lifetime_as<_Ty>(_Ptr);
}
template <class _Ty>
const _Ty* start_lifetime_as(const void* const _Ptr) noexcept {
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
#endif // ^^^ no workaround ^^^
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
return __builtin_start_lifetime_as<_Ty>(_Ptr);
}
template <class _Ty>
volatile _Ty* start_lifetime_as(volatile void* const _Ptr) noexcept {
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
#endif // ^^^ no workaround ^^^
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
return __builtin_start_lifetime_as<_Ty>(_Ptr);
}
template <class _Ty>
const volatile _Ty* start_lifetime_as(const volatile void* const _Ptr) noexcept {
#ifdef __cpp_lib_is_implicit_lifetime // TRANSITION
static_assert(is_implicit_lifetime_v<_Ty>, "T must be an implicit-lifetime type. (N5032 [obj.lifetime]/1)");
#endif // ^^^ no workaround ^^^
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/1)");
return __builtin_start_lifetime_as<_Ty>(_Ptr);
}

template <class _Ty>
_Ty* start_lifetime_as_array(void* const _Ptr, const size_t _Nx) noexcept {
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
}
template <class _Ty>
const _Ty* start_lifetime_as_array(const void* const _Ptr, const size_t _Nx) noexcept {
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
}
template <class _Ty>
volatile _Ty* start_lifetime_as_array(volatile void* const _Ptr, const size_t _Nx) noexcept {
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
}
template <class _Ty>
const volatile _Ty* start_lifetime_as_array(const volatile void* const _Ptr, const size_t _Nx) noexcept {
static_assert(sizeof(_Ty) > 0, "T must be a complete type. (N5032 [obj.lifetime]/5)");
return __builtin_start_lifetime_as_array<_Ty>(_Ptr, _Nx);
}
#endif // ^^^ defined(__cpp_lib_start_lifetime_as) ^^^

#endif // _HAS_CXX23
_STD_END

Expand Down
11 changes: 9 additions & 2 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,12 +389,14 @@
// P2540R1 Empty Product For Certain Views
// P2549R1 unexpected<E>::error()
// P2585R1 Improve Default Container Formatting
// P2590R2 Explicit Lifetime Management
// P2599R2 mdspan: index_type, size_type
// P2604R0 mdspan: data_handle_type, data_handle(), exhaustive
// P2613R1 mdspan: empty()
// P2614R2 Deprecating float_denorm_style, numeric_limits::has_denorm, numeric_limits::has_denorm_loss
// P2652R2 Disallowing User Specialization Of allocator_traits
// P2674R1 is_implicit_lifetime
// P2679R2 Fixing start_lifetime_as And start_lifetime_as_array
// P2693R1 Formatting thread::id And stacktrace
// P2713R1 Escaping Improvements In std::format
// P2763R1 Fixing layout_stride's Default Constructor For Fully Static Extents
Expand Down Expand Up @@ -1788,8 +1790,13 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
#define __cpp_lib_reference_from_temporary 202202L
#endif // ^^^ no workaround ^^^

#define __cpp_lib_spanstream 202106L
#define __cpp_lib_stacktrace 202011L
#define __cpp_lib_spanstream 202106L
#define __cpp_lib_stacktrace 202011L

#if !defined(__clang__) && !defined(__EDG__) && _MSC_VER >= 1951 // TRANSITION, GH-6169, toolset update
#define __cpp_lib_start_lifetime_as 202207L
#endif // ^^^ no workaround ^^^

#define __cpp_lib_stdatomic_h 202011L
#define __cpp_lib_string_contains 202011L
#define __cpp_lib_string_resize_and_overwrite 202110L
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ tests\P2505R5_monadic_functions_for_std_expected
tests\P2510R3_text_formatting_pointers
tests\P2517R1_apply_conditional_noexcept
tests\P2538R1_adl_proof_std_projected
tests\P2590R2_explicit_lifetime_management
tests\P2609R3_relaxing_ranges_just_a_smidge
tests\P2674R1_is_implicit_lifetime
tests\P2693R1_ostream_and_thread_id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_latest_matrix.lst
66 changes: 66 additions & 0 deletions tests/std/tests/P2590R2_explicit_lifetime_management/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cassert>
#include <concepts>
#include <memory>
using namespace std;

#ifdef __cpp_lib_start_lifetime_as // TRANSITION
struct Point {
int x;
int y;
};
static_assert(alignof(Point) == alignof(int));
static_assert(sizeof(Point) == 2 * sizeof(int));

template <class CvVoidPtr, class CvPointPtr>
void test_scalar() {
int arr[2]{17, 29};

const auto cv_void_ptr = static_cast<CvVoidPtr>(arr);

static_assert(noexcept(start_lifetime_as<Point>(cv_void_ptr)));
const same_as<CvPointPtr> auto cv_point_ptr = start_lifetime_as<Point>(cv_void_ptr);

assert(cv_point_ptr->x == 17);
assert(cv_point_ptr->y == 29);
}

template <class CvVoidPtr, class CvPointPtr>
void test_array() {
{
// N5032 [obj.lifetime]/6: "Preconditions: p is suitably aligned for an array of T or is null."
// N5032 [obj.lifetime]/7: "Effects: If n > 0 is true, [...]. Otherwise, there are no effects."
const same_as<CvPointPtr> auto nil = start_lifetime_as_array<Point>(static_cast<CvVoidPtr>(nullptr), 0);
assert(nil == nullptr); // N5032 [obj.lifetime]/8: "otherwise, a pointer that compares equal to p"
}

int arr[4]{17, 29, 123, 456};

const auto cv_void_ptr = static_cast<CvVoidPtr>(arr);

static_assert(noexcept(start_lifetime_as_array<Point>(cv_void_ptr, 2)));
const same_as<CvPointPtr> auto cv_point_ptr = start_lifetime_as_array<Point>(cv_void_ptr, 2);

assert(cv_point_ptr[0].x == 17);
assert(cv_point_ptr[0].y == 29);
assert(cv_point_ptr[1].x == 123);
assert(cv_point_ptr[1].y == 456);
}

template <class CvVoidPtr, class CvPointPtr>
void test() {
test_scalar<CvVoidPtr, CvPointPtr>();
test_array<CvVoidPtr, CvPointPtr>();
}

int main() {
test<void*, Point*>();
test<const void*, const Point*>();
test<volatile void*, volatile Point*>();
test<const volatile void*, const volatile Point*>();
}
#else // ^^^ no workaround / workaround vvv
int main() {}
#endif // ^^^ workaround ^^^
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,12 @@ STATIC_ASSERT(__cpp_lib_stacktrace == 202011L);
#error __cpp_lib_stacktrace is defined
#endif

#if _HAS_CXX23 && !defined(__clang__) && !defined(__EDG__) // TRANSITION, GH-6169 tracking LLVM-105234 and VSO-2846756
STATIC_ASSERT(__cpp_lib_start_lifetime_as == 202207L);
#elif defined(__cpp_lib_start_lifetime_as)
#error __cpp_lib_start_lifetime_as is defined
#endif

#if _HAS_CXX20
STATIC_ASSERT(__cpp_lib_starts_ends_with == 201711L);
#elif defined(__cpp_lib_starts_ends_with)
Expand Down