https://gcc.gnu.org/g:f8681ec8d0a778c62cf6d921e00a8714529ecca8
commit r16-4023-gf8681ec8d0a778c62cf6d921e00a8714529ecca8 Author: Tomasz Kamiński <[email protected]> Date: Mon Sep 22 13:31:17 2025 +0200 libstdc++: Move start_lifetime_as functions to bits/stl_construct.h [PR106658] This allows inplace_vector to use these functions without including the entire <memory> header. Preprocessor checks are changed to use __glibcxx macros, so new functions are available outside memory header, that exports __cpp_lib macros. PR libstdc++/106658 libstdc++-v3/ChangeLog: * include/bits/stl_construct.h (std::start_lifetime_as_array) (std::start_lifetime_as): Moved from std/memory, with update to guard macros. * include/std/memory (std::start_lifetime_as_array) (std::start_lifetime_as): Moved to bits/stl_construct.h. Reviewed-by: Jonathan Wakely <[email protected]> Signed-off-by: Tomasz Kamiński <[email protected]> Diff: --- libstdc++-v3/include/bits/stl_construct.h | 123 ++++++++++++++++++++++++++++ libstdc++-v3/include/std/memory | 128 ------------------------------ 2 files changed, 123 insertions(+), 128 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h index 217a0416d425..98b403c4c715 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -281,6 +281,129 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif // C++17 +#if __glibcxx_start_lifetime_as >= 202207L // C++ >= 23 + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline _Tp* + start_lifetime_as(void* __p) noexcept + { +#if __glibcxx_is_implicit_lifetime >= 202302L + static_assert(is_implicit_lifetime_v<_Tp>); +#endif + auto __q = reinterpret_cast<_Tp*>(__p); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__q) + : "0" (__q), "m" (*__q)); + return __q; + } + + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline const _Tp* + start_lifetime_as(const void* __p) noexcept + { +#if __glibcxx_is_implicit_lifetime >= 202302L + static_assert(is_implicit_lifetime_v<_Tp>); +#endif + auto __q = reinterpret_cast<const _Tp*>(__p); + auto __r = reinterpret_cast<_Tp*>(const_cast<void*>(__p)); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) + : "0" (__q), "m" (*__q)); + return __q; + } + + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline volatile _Tp* + start_lifetime_as(volatile void* __p) noexcept + { +#if __glibcxx_is_implicit_lifetime >= 202302L + static_assert(is_implicit_lifetime_v<_Tp>); +#endif + auto __q = reinterpret_cast<volatile _Tp*>(__p); + auto __r = reinterpret_cast<_Tp*>(const_cast<void*>(__p)); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) + : "0" (__q), "m" (*__q)); + return __q; + } + + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline const volatile _Tp* + start_lifetime_as(const volatile void* __p) noexcept + { +#if __glibcxx_is_implicit_lifetime >= 202302L + static_assert(is_implicit_lifetime_v<_Tp>); +#endif + auto __q = reinterpret_cast<const volatile _Tp*>(__p); + auto __r = reinterpret_cast<_Tp*>(const_cast<void*>(__p)); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) + : "0" (__q), "m" (*__q)); + return __q; + } + + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline _Tp* + start_lifetime_as_array(void* __p, size_t __n) noexcept + { + auto __q = reinterpret_cast<_Tp*>(__p); + if (!__n) + return __q; + auto __r = (__extension__ reinterpret_cast<_Tp(*)[__n]>(__p)); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) + : "0" (__q), "m" (*__r)); + return __q; + } + + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline const _Tp* + start_lifetime_as_array(const void* __p, size_t __n) noexcept + { + auto __q = reinterpret_cast<const _Tp*>(__p); + if (!__n) + return __q; + auto __r = (__extension__ reinterpret_cast<const _Tp(*)[__n]>(__p)); + auto __s = (__extension__ + reinterpret_cast<_Tp(*)[__n]>(const_cast<void*>(__p))); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__s) + : "0" (__q), "m" (*__r)); + return __q; + } + + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline volatile _Tp* + start_lifetime_as_array(volatile void* __p, size_t __n) noexcept + { + auto __q = reinterpret_cast<volatile _Tp*>(__p); + if (!__n) + return __q; + auto __r = (__extension__ reinterpret_cast<volatile _Tp(*)[__n]>(__p)); + auto __s = (__extension__ + reinterpret_cast<_Tp(*)[__n]>(const_cast<void*>(__p))); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__s) + : "0" (__q), "m" (*__r)); + return __q; + } + + template<typename _Tp> + [[__gnu__::__always_inline__]] + inline const volatile _Tp* + start_lifetime_as_array(const volatile void* __p, size_t __n) noexcept + { + auto __q = reinterpret_cast<const volatile _Tp*>(__p); + if (!__n) + return __q; + auto __r = (__extension__ reinterpret_cast<const volatile _Tp(*)[__n]>(__p)); + auto __s = (__extension__ + reinterpret_cast<_Tp(*)[__n]>(const_cast<void*>(__p))); + __asm__ __volatile__("" : "=g" (__q), "=m" (*__s) + : "0" (__q), "m" (*__r)); + return __q; + } +#endif // C++23 + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index e46db885fe2c..9763760b8d61 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -173,134 +173,6 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 to C++20 -#if __cpp_lib_start_lifetime_as >= 202207L // C++ >= 23 -namespace std _GLIBCXX_VISIBILITY(default) -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline _Tp* - start_lifetime_as(void* __p) noexcept - { -#if __cpp_lib_is_implicit_lifetime >= 202302L - static_assert(is_implicit_lifetime_v<_Tp>); -#endif - auto __q = reinterpret_cast<_Tp*>(__p); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__q) - : "0" (__q), "m" (*__q)); - return __q; - } - - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline const _Tp* - start_lifetime_as(const void* __p) noexcept - { -#if __cpp_lib_is_implicit_lifetime >= 202302L - static_assert(is_implicit_lifetime_v<_Tp>); -#endif - auto __q = reinterpret_cast<const _Tp*>(__p); - auto __r = reinterpret_cast<_Tp*>(const_cast<void*>(__p)); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) - : "0" (__q), "m" (*__q)); - return __q; - } - - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline volatile _Tp* - start_lifetime_as(volatile void* __p) noexcept - { -#if __cpp_lib_is_implicit_lifetime >= 202302L - static_assert(is_implicit_lifetime_v<_Tp>); -#endif - auto __q = reinterpret_cast<volatile _Tp*>(__p); - auto __r = reinterpret_cast<_Tp*>(const_cast<void*>(__p)); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) - : "0" (__q), "m" (*__q)); - return __q; - } - - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline const volatile _Tp* - start_lifetime_as(const volatile void* __p) noexcept - { -#if __cpp_lib_is_implicit_lifetime >= 202302L - static_assert(is_implicit_lifetime_v<_Tp>); -#endif - auto __q = reinterpret_cast<const volatile _Tp*>(__p); - auto __r = reinterpret_cast<_Tp*>(const_cast<void*>(__p)); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) - : "0" (__q), "m" (*__q)); - return __q; - } - - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline _Tp* - start_lifetime_as_array(void* __p, size_t __n) noexcept - { - auto __q = reinterpret_cast<_Tp*>(__p); - if (!__n) - return __q; - auto __r = (__extension__ reinterpret_cast<_Tp(*)[__n]>(__p)); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__r) - : "0" (__q), "m" (*__r)); - return __q; - } - - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline const _Tp* - start_lifetime_as_array(const void* __p, size_t __n) noexcept - { - auto __q = reinterpret_cast<const _Tp*>(__p); - if (!__n) - return __q; - auto __r = (__extension__ reinterpret_cast<const _Tp(*)[__n]>(__p)); - auto __s = (__extension__ - reinterpret_cast<_Tp(*)[__n]>(const_cast<void*>(__p))); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__s) - : "0" (__q), "m" (*__r)); - return __q; - } - - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline volatile _Tp* - start_lifetime_as_array(volatile void* __p, size_t __n) noexcept - { - auto __q = reinterpret_cast<volatile _Tp*>(__p); - if (!__n) - return __q; - auto __r = (__extension__ reinterpret_cast<volatile _Tp(*)[__n]>(__p)); - auto __s = (__extension__ - reinterpret_cast<_Tp(*)[__n]>(const_cast<void*>(__p))); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__s) - : "0" (__q), "m" (*__r)); - return __q; - } - - template<typename _Tp> - [[__gnu__::__always_inline__]] - inline const volatile _Tp* - start_lifetime_as_array(const volatile void* __p, size_t __n) noexcept - { - auto __q = reinterpret_cast<const volatile _Tp*>(__p); - if (!__n) - return __q; - auto __r = (__extension__ reinterpret_cast<const volatile _Tp(*)[__n]>(__p)); - auto __s = (__extension__ - reinterpret_cast<_Tp(*)[__n]>(const_cast<void*>(__p))); - __asm__ __volatile__("" : "=g" (__q), "=m" (*__s) - : "0" (__q), "m" (*__r)); - return __q; - } -_GLIBCXX_END_NAMESPACE_VERSION -} // namespace -#endif - #ifdef __cpp_lib_parallel_algorithm // C++ >= 17 && HOSTED // Parallel STL algorithms # if _PSTL_EXECUTION_POLICIES_DEFINED
