Split std::align/assume_aligned to bits/align.h

Message ID 20200910003830.1463264-1-rodgert@appliantology.com
State New
Headers show
Series
  • Split std::align/assume_aligned to bits/align.h
Related show

Commit Message

Thomas Rodgers Sept. 10, 2020, 12:38 a.m.
We would like to be able to use these things without having to pull in
the whole of <memory>.

        * include/Makefile.am (bits_headers): Add new header.
	* include/Makefile.in: Regenerate.
        * include/bits/align.h: New file.
        * include/std/memory (align): Move definition to bits/align.h.
        (assume_aligned): Likewise.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/align.h | 104 ++++++++++++++++++++++++++++++
 libstdc++-v3/include/std/memory   |  60 +----------------
 4 files changed, 107 insertions(+), 59 deletions(-)
 create mode 100644 libstdc++-v3/include/bits/align.h

-- 
2.26.2

Comments

Jeff Law via Gcc-patches Sept. 10, 2020, 6:04 a.m. | #1
On 09/09/20 17:38 -0700, Thomas Rodgers wrote:
>We would like to be able to use these things without having to pull in

>the whole of <memory>.

>

>        * include/Makefile.am (bits_headers): Add new header.

>	* include/Makefile.in: Regenerate.

>        * include/bits/align.h: New file.

>        * include/std/memory (align): Move definition to bits/align.h.

>        (assume_aligned): Likewise.

>---

> libstdc++-v3/include/Makefile.am  |   1 +

> libstdc++-v3/include/Makefile.in  |   1 +

> libstdc++-v3/include/bits/align.h | 104 ++++++++++++++++++++++++++++++

> libstdc++-v3/include/std/memory   |  60 +----------------

> 4 files changed, 107 insertions(+), 59 deletions(-)

> create mode 100644 libstdc++-v3/include/bits/align.h

>

>diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am

>index bae97852348..eabec88219d 100644

>--- a/libstdc++-v3/include/Makefile.am

>+++ b/libstdc++-v3/include/Makefile.am

>@@ -99,6 +99,7 @@ bits_srcdir = ${glibcxx_srcdir}/include/bits

> bits_builddir = ./bits

> bits_headers = \

> 	${bits_srcdir}/algorithmfwd.h \

>+	${bits_srcdir}/align.h \

> 	${bits_srcdir}/alloc_traits.h \

> 	${bits_srcdir}/allocated_ptr.h \

> 	${bits_srcdir}/allocator.h \

>diff --git a/libstdc++-v3/include/bits/align.h b/libstdc++-v3/include/bits/align.h

>new file mode 100644

>index 00000000000..593b337f897

>--- /dev/null

>+++ b/libstdc++-v3/include/bits/align.h

>@@ -0,0 +1,104 @@

>+// align implementation -*- C++ -*-

>+

>+// Copyright (C) 2008-2020 Free Software Foundation, Inc.


std::align was added in 2014 by
2f6ca9d31799133f80e446bd1faad5d9a67bac00 so that should be the first
date in the new file.

>+//

>+// This file is part of the GNU ISO C++ Library.  This library is free

>+// software; you can redistribute it and/or modify it under the

>+// terms of the GNU General Public License as published by the

>+// Free Software Foundation; either version 3, or (at your option)

>+// any later version.

>+

>+// This library is distributed in the hope that it will be useful,

>+// but WITHOUT ANY WARRANTY; without even the implied warranty of

>+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

>+// GNU General Public License for more details.

>+

>+// Under Section 7 of GPL version 3, you are granted additional

>+// permissions described in the GCC Runtime Library Exception, version

>+// 3.1, as published by the Free Software Foundation.

>+

>+// You should have received a copy of the GNU General Public License and

>+// a copy of the GCC Runtime Library Exception along with this program;

>+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see

>+// <http://www.gnu.org/licenses/>.

>+

>+/** @file bits/align.h

>+ *  This is an internal header file, included by other library headers.

>+ *  Do not attempt to use it directly. @headername{memory}

>+ */

>+

>+#ifndef _ALIGN_H

>+#define _ALIGN_H 1


I'm a little worried this macro isn't unique enough and will clash
with something. Please use _GLIBCXX_ALIGN_H for the header guard
macro.

>+

>+#include <bits/c++config.h>

>+

>+#include <bit>          // std::has_single_bit

>+#include <stdint.h>     // uintptr_t

>+

>+namespace std _GLIBCXX_VISIBILITY(default)

>+{

>+_GLIBCXX_BEGIN_NAMESPACE_VERSION

>+

>+/**

>+ *  @brief Fit aligned storage in buffer.

>+ *  @ingroup memory

>+ *

>+ *  This function tries to fit @a __size bytes of storage with alignment

>+ *  @a __align into the buffer @a __ptr of size @a __space bytes.  If such

>+ *  a buffer fits then @a __ptr is changed to point to the first byte of the

>+ *  aligned storage and @a __space is reduced by the bytes used for alignment.

>+ *

>+ *  C++11 20.6.5 [ptr.align]

>+ *

>+ *  @param __align   A fundamental or extended alignment value.

>+ *  @param __size    Size of the aligned storage required.

>+ *  @param __ptr     Pointer to a buffer of @a __space bytes.

>+ *  @param __space   Size of the buffer pointed to by @a __ptr.

>+ *  @return the updated pointer if the aligned storage fits, otherwise nullptr.

>+ *

>+ */

>+inline void*

>+align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept

>+{

>+#ifdef _GLIBCXX_USE_C99_STDINT_TR1

>+  const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);

>+#else

>+  // Cannot use std::uintptr_t so assume that std::size_t can be used instead.

>+  static_assert(sizeof(size_t) >= sizeof(void*),

>+      "std::size_t must be a suitable substitute for std::uintptr_t");

>+  const auto __intptr = reinterpret_cast<unsigned long long>(__ptr);


Why on earth did I check that we can use size_t ... and then not use
size_t?! Not your problem though, that can be fixed separately.

OK for trunk with the copyright year and header guard changes, thanks!

Patch

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index bae97852348..eabec88219d 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -99,6 +99,7 @@  bits_srcdir = ${glibcxx_srcdir}/include/bits
 bits_builddir = ./bits
 bits_headers = \
 	${bits_srcdir}/algorithmfwd.h \
+	${bits_srcdir}/align.h \
 	${bits_srcdir}/alloc_traits.h \
 	${bits_srcdir}/allocated_ptr.h \
 	${bits_srcdir}/allocator.h \
diff --git a/libstdc++-v3/include/bits/align.h b/libstdc++-v3/include/bits/align.h
new file mode 100644
index 00000000000..593b337f897
--- /dev/null
+++ b/libstdc++-v3/include/bits/align.h
@@ -0,0 +1,104 @@ 
+// align implementation -*- C++ -*-
+
+// Copyright (C) 2008-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/align.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{memory}
+ */
+
+#ifndef _ALIGN_H
+#define _ALIGN_H 1
+
+#include <bits/c++config.h>
+
+#include <bit>          // std::has_single_bit
+#include <stdint.h>     // uintptr_t
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+/**
+ *  @brief Fit aligned storage in buffer.
+ *  @ingroup memory
+ *
+ *  This function tries to fit @a __size bytes of storage with alignment
+ *  @a __align into the buffer @a __ptr of size @a __space bytes.  If such
+ *  a buffer fits then @a __ptr is changed to point to the first byte of the
+ *  aligned storage and @a __space is reduced by the bytes used for alignment.
+ *
+ *  C++11 20.6.5 [ptr.align]
+ *
+ *  @param __align   A fundamental or extended alignment value.
+ *  @param __size    Size of the aligned storage required.
+ *  @param __ptr     Pointer to a buffer of @a __space bytes.
+ *  @param __space   Size of the buffer pointed to by @a __ptr.
+ *  @return the updated pointer if the aligned storage fits, otherwise nullptr.
+ *
+ */
+inline void*
+align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
+{
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+  const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
+#else
+  // Cannot use std::uintptr_t so assume that std::size_t can be used instead.
+  static_assert(sizeof(size_t) >= sizeof(void*),
+      "std::size_t must be a suitable substitute for std::uintptr_t");
+  const auto __intptr = reinterpret_cast<unsigned long long>(__ptr);
+#endif
+  const auto __aligned = (__intptr - 1u + __align) & -__align;
+  const auto __diff = __aligned - __intptr;
+  if ((__size + __diff) > __space)
+    return nullptr;
+  else
+    {
+      __space -= __diff;
+      return __ptr = reinterpret_cast<void*>(__aligned);
+    }
+}
+
+#if __cplusplus > 201703L
+#define __cpp_lib_assume_aligned 201811L
+  /** @brief Inform the compiler that a pointer is aligned.
+   *
+   *  @tparam _Align An alignment value (i.e. a power of two)
+   *  @tparam _Tp    An object type
+   *  @param  __ptr  A pointer that is aligned to _Align
+   *  @ingroup memory
+   */
+  template<size_t _Align, class _Tp>
+    [[nodiscard,__gnu__::__always_inline__]]
+    constexpr _Tp* assume_aligned(_Tp* __ptr)
+    {
+      static_assert(std::has_single_bit(_Align));
+      _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0);
+      return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
+    }
+#endif // C++2a
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif /* _ALIGN_H */
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 1e8eebd731c..a56952fb114 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -61,6 +61,7 @@ 
  */
 
 #include <bits/stl_algobase.h>
+#include <bits/align.h>
 #include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
@@ -101,46 +102,6 @@  namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-/**
- *  @brief Fit aligned storage in buffer.
- *  @ingroup memory
- *
- *  This function tries to fit @a __size bytes of storage with alignment
- *  @a __align into the buffer @a __ptr of size @a __space bytes.  If such
- *  a buffer fits then @a __ptr is changed to point to the first byte of the
- *  aligned storage and @a __space is reduced by the bytes used for alignment.
- *
- *  C++11 20.6.5 [ptr.align]
- *
- *  @param __align   A fundamental or extended alignment value.
- *  @param __size    Size of the aligned storage required.
- *  @param __ptr     Pointer to a buffer of @a __space bytes.
- *  @param __space   Size of the buffer pointed to by @a __ptr.
- *  @return the updated pointer if the aligned storage fits, otherwise nullptr.
- *
- */
-inline void*
-align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
-{
-#ifdef _GLIBCXX_USE_C99_STDINT_TR1
-  const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
-#else
-  // Cannot use std::uintptr_t so assume that std::size_t can be used instead.
-  static_assert(sizeof(size_t) >= sizeof(void*),
-      "std::size_t must be a suitable substitute for std::uintptr_t");
-  const auto __intptr = reinterpret_cast<unsigned long long>(__ptr);
-#endif
-  const auto __aligned = (__intptr - 1u + __align) & -__align;
-  const auto __diff = __aligned - __intptr;
-  if ((__size + __diff) > __space)
-    return nullptr;
-  else
-    {
-      __space -= __diff;
-      return __ptr = reinterpret_cast<void*>(__aligned);
-    }
-}
-
 /** @defgroup ptr_safety Pointer Safety and Garbage Collection
  *  @ingroup memory
  *
@@ -179,25 +140,6 @@  inline pointer_safety
 get_pointer_safety() noexcept { return pointer_safety::relaxed; }
 // @}
 
-#if __cplusplus > 201703L
-#define __cpp_lib_assume_aligned 201811L
-  /** @brief Inform the compiler that a pointer is aligned.
-   *
-   *  @tparam _Align An alignment value (i.e. a power of two)
-   *  @tparam _Tp    An object type
-   *  @param  __ptr  A pointer that is aligned to _Align
-   *  @ingroup memory
-   */
-  template<size_t _Align, class _Tp>
-    [[nodiscard,__gnu__::__always_inline__]]
-    constexpr _Tp* assume_aligned(_Tp* __ptr)
-    {
-      static_assert(std::has_single_bit(_Align));
-      _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0);
-      return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
-    }
-#endif // C++2a
-
 #if __cplusplus > 201703L
   template<typename _Tp>
     struct __is_pair : false_type { };