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. +// +// 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 { }; -- 2.26.2