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 <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
This commit is contained in:
Tomasz Kamiński
2025-09-22 13:31:17 +02:00
parent 915803d88b
commit f8681ec8d0
2 changed files with 123 additions and 128 deletions

View File

@@ -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

View File

@@ -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