On Mon, Sep 22, 2025 at 2:49 PM Tomasz Kamiński <[email protected]> wrote:

> 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.
>
> 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 marcors.
>         * include/std/memory (std::start_lifetime_as_array)
>         (std::start_lifetime_as): Moved to bits/stl_construct.h.
> ---
> Tested on x86_64-linux locally.
> OK for trunk?
>
>  libstdc++-v3/include/bits/stl_construct.h | 128 ++++++++++++++++++++++
>  libstdc++-v3/include/std/memory           | 128 ----------------------
>  2 files changed, 128 insertions(+), 128 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/stl_construct.h
> b/libstdc++-v3/include/bits/stl_construct.h
> index 217a0416d42..7f6120f6280 100644
> --- a/libstdc++-v3/include/bits/stl_construct.h
> +++ b/libstdc++-v3/include/bits/stl_construct.h
> @@ -281,6 +281,134 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      }
>  #endif // C++17
>
> +#if __glibcxx_start_lifetime_as >= 202207L // C++ >= 23
> +namespace std _GLIBCXX_VISIBILITY(default)
> +{
>
We are already in the std namespace, so this is wrong, I have removed
that locally, but forgot to amend the commit before posting.


> +_GLIBCXX_BEGIN_NAMESPACE_VERSION
> +  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;
> +    }
> +_GLIBCXX_END_NAMESPACE_VERSION
> +} // namespace
>
Similarly, we should not close namespace here.

> +#endif // c++23
> +
>  _GLIBCXX_END_NAMESPACE_VERSION
>  } // namespace std
>
> diff --git a/libstdc++-v3/include/std/memory
> b/libstdc++-v3/include/std/memory
> index e46db885fe2..9763760b8d6 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
> --
> 2.51.0
>
>

Reply via email to