From f612feec0b62b4ed2c2f239776c4c8d43ee97364 Mon Sep 17 00:00:00 2001 From: Shivam Kunwar Date: Wed, 4 Sep 2024 15:02:30 +0530 Subject: [PATCH 1/3] [libc++] P2590R2: Explicit lifetime management --- libcxx/include/CMakeLists.txt | 2 + libcxx/include/__memory/start_lifetime_as.h | 50 +++++++ .../__memory/start_lifetime_as_array.h | 47 +++++++ libcxx/include/memory | 2 + .../start_lifetime_as.pass.cpp | 127 ++++++++++++++++++ 5 files changed, 228 insertions(+) create mode 100644 libcxx/include/__memory/start_lifetime_as.h create mode 100644 libcxx/include/__memory/start_lifetime_as_array.h create mode 100644 libcxx/test/std/utilities/memory/default.allocator/start_lifetime_as.pass.cpp diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 32579272858a8..629742cbaee76 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -542,6 +542,8 @@ set(files __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h __memory/shared_ptr.h + __memory/start_lifetime_as_array.h + __memory/start_lifetime_as.h __memory/swap_allocator.h __memory/temp_value.h __memory/temporary_buffer.h diff --git a/libcxx/include/__memory/start_lifetime_as.h b/libcxx/include/__memory/start_lifetime_as.h new file mode 100644 index 0000000000000..f661a709c06c4 --- /dev/null +++ b/libcxx/include/__memory/start_lifetime_as.h @@ -0,0 +1,50 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MEMORY_START_LIFETIME_AS_H +#define _LIBCPP___MEMORY_START_LIFETIME_AS_H + +#include <__config> +#include <__type_traits/is_array.h> +#include <__type_traits/remove_all_extents.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS __start_lifetime_as_impl { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Tp* __call(void* __p) _NOEXCEPT { return static_cast<_Tp*>(__p); } +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* start_lifetime_as(void* __p) _NOEXCEPT { + return __start_lifetime_as_impl<_Tp>::__call(__p); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const _Tp* start_lifetime_as(const void* __p) _NOEXCEPT { + return start_lifetime_as<_Tp>(const_cast(__p)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR volatile _Tp* start_lifetime_as(volatile void* __p) _NOEXCEPT { + return start_lifetime_as<_Tp>(const_cast(__p)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const volatile _Tp* start_lifetime_as(const volatile void* __p) _NOEXCEPT { + return start_lifetime_as<_Tp>(const_cast(__p)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_START_LIFETIME_AS_H diff --git a/libcxx/include/__memory/start_lifetime_as_array.h b/libcxx/include/__memory/start_lifetime_as_array.h new file mode 100644 index 0000000000000..5b227870f7ed6 --- /dev/null +++ b/libcxx/include/__memory/start_lifetime_as_array.h @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MEMORY_START_LIFETIME_AS_ARRAY_H +#define _LIBCPP___MEMORY_START_LIFETIME_AS_ARRAY_H + +#include <__config> +#include <__memory/start_lifetime_as.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* start_lifetime_as_array(void* __p, [[maybe_unused]] size_t __n) _NOEXCEPT { + return static_cast<_Tp*>(__p); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const _Tp* start_lifetime_as_array(const void* __p, size_t __n) _NOEXCEPT { + return start_lifetime_as_array<_Tp>(const_cast(__p), __n); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR volatile _Tp* +start_lifetime_as_array(volatile void* __p, size_t __n) _NOEXCEPT { + return start_lifetime_as_array<_Tp>(const_cast(__p), __n); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const volatile _Tp* +start_lifetime_as_array(const volatile void* __p, size_t __n) _NOEXCEPT { + return start_lifetime_as_array<_Tp>(const_cast(__p), __n); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_START_LIFETIME_AS_ARRAY_H diff --git a/libcxx/include/memory b/libcxx/include/memory index b940a32c3ebe6..3162bbb2b906a 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -946,6 +946,8 @@ template #include <__memory/pointer_traits.h> #include <__memory/raw_storage_iterator.h> #include <__memory/shared_ptr.h> +#include <__memory/start_lifetime_as.h> +#include <__memory/start_lifetime_as_array.h> #include <__memory/temporary_buffer.h> #include <__memory/uninitialized_algorithms.h> #include <__memory/unique_ptr.h> diff --git a/libcxx/test/std/utilities/memory/default.allocator/start_lifetime_as.pass.cpp b/libcxx/test/std/utilities/memory/default.allocator/start_lifetime_as.pass.cpp new file mode 100644 index 0000000000000..e483516e77b46 --- /dev/null +++ b/libcxx/test/std/utilities/memory/default.allocator/start_lifetime_as.pass.cpp @@ -0,0 +1,127 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template +// T* start_lifetime_as(void* p) noexcept; +// +// template +// const T* start_lifetime_as(const void* p) noexcept; +// +// template +// volatile T* start_lifetime_as(volatile void* p) noexcept; +// +// template +// const volatile T* start_lifetime_as(const volatile void* p) noexcept; +// +// template +// T* start_lifetime_as_array(void* p, size_t n) noexcept; +// +// template +// const T* start_lifetime_as_array(const void* p, size_t n) noexcept; +// +// template +// volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; +// +// template +// const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) noexcept; + +#include +#include +#include + +#include "test_macros.h" + +struct S { + int x; + double y; +}; + +template +void test_start_lifetime_as() { + alignas(T) char buffer[sizeof(T)]; + + { + T* ptr = std::start_lifetime_as(buffer); + ASSERT_SAME_TYPE(decltype(ptr), T*); + ASSERT_NOEXCEPT(std::start_lifetime_as(buffer)); + assert(ptr == reinterpret_cast(buffer)); + } + + { + const T* cptr = std::start_lifetime_as(static_cast(buffer)); + ASSERT_SAME_TYPE(decltype(cptr), const T*); + ASSERT_NOEXCEPT(std::start_lifetime_as(static_cast(buffer))); + assert(cptr == reinterpret_cast(buffer)); + } + + { + volatile T* vptr = std::start_lifetime_as(static_cast(buffer)); + ASSERT_SAME_TYPE(decltype(vptr), volatile T*); + ASSERT_NOEXCEPT(std::start_lifetime_as(static_cast(buffer))); + assert(vptr == reinterpret_cast(buffer)); + } + + { + const volatile T* cvptr = std::start_lifetime_as(static_cast(buffer)); + ASSERT_SAME_TYPE(decltype(cvptr), const volatile T*); + ASSERT_NOEXCEPT(std::start_lifetime_as(static_cast(buffer))); + assert(cvptr == reinterpret_cast(buffer)); + } +} + +template +void test_start_lifetime_as_array() { + constexpr size_t count = 5; + alignas(T) char buffer[sizeof(T) * count]; + + { + T* ptr = std::start_lifetime_as_array(buffer, count); + ASSERT_SAME_TYPE(decltype(ptr), T*); + ASSERT_NOEXCEPT(std::start_lifetime_as_array(buffer, count)); + assert(ptr == reinterpret_cast(buffer)); + } + + { + const T* cptr = std::start_lifetime_as_array(static_cast(buffer), count); + ASSERT_SAME_TYPE(decltype(cptr), const T*); + ASSERT_NOEXCEPT(std::start_lifetime_as_array(static_cast(buffer), count)); + assert(cptr == reinterpret_cast(buffer)); + } + + { + volatile T* vptr = std::start_lifetime_as_array(static_cast(buffer), count); + ASSERT_SAME_TYPE(decltype(vptr), volatile T*); + ASSERT_NOEXCEPT(std::start_lifetime_as_array(static_cast(buffer), count)); + assert(vptr == reinterpret_cast(buffer)); + } + + { + const volatile T* cvptr = std::start_lifetime_as_array(static_cast(buffer), count); + ASSERT_SAME_TYPE(decltype(cvptr), const volatile T*); + ASSERT_NOEXCEPT(std::start_lifetime_as_array(static_cast(buffer), count)); + assert(cvptr == reinterpret_cast(buffer)); + } +} + +int main(int, char**) { + test_start_lifetime_as(); + test_start_lifetime_as(); + test_start_lifetime_as(); + test_start_lifetime_as(); + + test_start_lifetime_as_array(); + test_start_lifetime_as_array(); + test_start_lifetime_as_array(); + test_start_lifetime_as_array(); + + return 0; +} \ No newline at end of file From 73eeb1324eea8b9e5725bc15b41419c1d2874be9 Mon Sep 17 00:00:00 2001 From: Shivam Kunwar Date: Wed, 4 Sep 2024 15:02:30 +0530 Subject: [PATCH 2/3] [libc++] P2590R2: Explicit lifetime management --- libcxx/include/__memory/start_lifetime_as.h | 6 +++--- libcxx/include/__memory/start_lifetime_as_array.h | 9 +++++---- libcxx/include/module.modulemap | 2 ++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libcxx/include/__memory/start_lifetime_as.h b/libcxx/include/__memory/start_lifetime_as.h index f661a709c06c4..2e3292657472c 100644 --- a/libcxx/include/__memory/start_lifetime_as.h +++ b/libcxx/include/__memory/start_lifetime_as.h @@ -32,17 +32,17 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* start_lifetime_as(void* __p) _NOEXC template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const _Tp* start_lifetime_as(const void* __p) _NOEXCEPT { - return start_lifetime_as<_Tp>(const_cast(__p)); + return std::start_lifetime_as<_Tp>(const_cast(__p)); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR volatile _Tp* start_lifetime_as(volatile void* __p) _NOEXCEPT { - return start_lifetime_as<_Tp>(const_cast(__p)); + return std::start_lifetime_as<_Tp>(const_cast(__p)); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const volatile _Tp* start_lifetime_as(const volatile void* __p) _NOEXCEPT { - return start_lifetime_as<_Tp>(const_cast(__p)); + return std::start_lifetime_as<_Tp>(const_cast(__p)); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__memory/start_lifetime_as_array.h b/libcxx/include/__memory/start_lifetime_as_array.h index 5b227870f7ed6..17272c318c2ab 100644 --- a/libcxx/include/__memory/start_lifetime_as_array.h +++ b/libcxx/include/__memory/start_lifetime_as_array.h @@ -21,25 +21,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* start_lifetime_as_array(void* __p, [[maybe_unused]] size_t __n) _NOEXCEPT { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* +start_lifetime_as_array(void* __p, [[__maybe_unused__]] size_t __n) _NOEXCEPT { return static_cast<_Tp*>(__p); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const _Tp* start_lifetime_as_array(const void* __p, size_t __n) _NOEXCEPT { - return start_lifetime_as_array<_Tp>(const_cast(__p), __n); + return std::start_lifetime_as_array<_Tp>(const_cast(__p), __n); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR volatile _Tp* start_lifetime_as_array(volatile void* __p, size_t __n) _NOEXCEPT { - return start_lifetime_as_array<_Tp>(const_cast(__p), __n); + return std::start_lifetime_as_array<_Tp>(const_cast(__p), __n); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const volatile _Tp* start_lifetime_as_array(const volatile void* __p, size_t __n) _NOEXCEPT { - return start_lifetime_as_array<_Tp>(const_cast(__p), __n); + return std::start_lifetime_as_array<_Tp>(const_cast(__p), __n); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index f193b5d95f49f..d340d6b33ddae 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1543,6 +1543,8 @@ module std_private_memory_shared_ptr [system] { header "__memory/shared_ptr.h" export std_private_memory_uninitialized_algorithms } +module std_private_memory_start_lifetime_as_array [system] { header "__memory/start_lifetime_as_array.h" } +module std_private_memory_start_lifetime_as [system] { header "__memory/start_lifetime_as.h" } module std_private_memory_swap_allocator [system] { header "__memory/swap_allocator.h" } module std_private_memory_temp_value [system] { header "__memory/temp_value.h" } module std_private_memory_temporary_buffer [system] { From 8ba8c649f9871bf4cd632b6bbcdb3f7681932c57 Mon Sep 17 00:00:00 2001 From: Shivam Kunwar Date: Wed, 4 Sep 2024 15:02:30 +0530 Subject: [PATCH 3/3] [libc++] P2590R2: Explicit lifetime management --- libcxx/include/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 629742cbaee76..a9c6e2e499953 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -542,8 +542,8 @@ set(files __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h __memory/shared_ptr.h - __memory/start_lifetime_as_array.h __memory/start_lifetime_as.h + __memory/start_lifetime_as_array.h __memory/swap_allocator.h __memory/temp_value.h __memory/temporary_buffer.h