1  // Aligned memory buffer -*- C++ -*-
       2  
       3  // Copyright (C) 2013-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /** @file ext/aligned_buffer.h
      26   *  This file is a GNU extension to the Standard C++ Library.
      27   */
      28  
      29  #ifndef _ALIGNED_BUFFER_H
      30  #define _ALIGNED_BUFFER_H 1
      31  
      32  #pragma GCC system_header
      33  
      34  #if __cplusplus >= 201103L
      35  # include <type_traits>
      36  #else
      37  # include <bits/c++0x_warning.h>
      38  #endif
      39  
      40  namespace __gnu_cxx
      41  {
      42    // A utility type containing a POD object that can hold an object of type
      43    // _Tp initialized via placement new or allocator_traits::construct.
      44    // Intended for use as a data member subobject, use __aligned_buffer for
      45    // complete objects.
      46    template<typename _Tp>
      47      struct __aligned_membuf
      48      {
      49        // Target macro ADJUST_FIELD_ALIGN can produce different alignment for
      50        // types when used as class members. __aligned_membuf is intended
      51        // for use as a class member, so align the buffer as for a class member.
      52        // Since GCC 8 we could just use alignof(_Tp) instead, but older
      53        // versions of non-GNU compilers might still need this trick.
      54        struct _Tp2 { _Tp _M_t; };
      55  
      56        alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
      57  
      58        __aligned_membuf() = default;
      59  
      60        // Can be used to avoid value-initialization zeroing _M_storage.
      61        __aligned_membuf(std::nullptr_t) { }
      62  
      63        void*
      64        _M_addr() noexcept
      65        { return static_cast<void*>(&_M_storage); }
      66  
      67        const void*
      68        _M_addr() const noexcept
      69        { return static_cast<const void*>(&_M_storage); }
      70  
      71        _Tp*
      72        _M_ptr() noexcept
      73        { return static_cast<_Tp*>(_M_addr()); }
      74  
      75        const _Tp*
      76        _M_ptr() const noexcept
      77        { return static_cast<const _Tp*>(_M_addr()); }
      78      };
      79  
      80  #if _GLIBCXX_INLINE_VERSION
      81    template<typename _Tp>
      82      using __aligned_buffer = __aligned_membuf<_Tp>;
      83  #else
      84  #pragma GCC diagnostic push
      85  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      86    // Similar to __aligned_membuf but aligned for complete objects, not members.
      87    // This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h>
      88    // and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf
      89    // instead, as it has smaller size for some types on some targets.
      90    // This type is still used to avoid an ABI change.
      91    template<typename _Tp>
      92      struct __aligned_buffer
      93      : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>
      94      {
      95        typename
      96  	std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage;
      97  
      98        __aligned_buffer() = default;
      99  
     100        // Can be used to avoid value-initialization
     101        __aligned_buffer(std::nullptr_t) { }
     102  
     103        void*
     104        _M_addr() noexcept
     105        {
     106          return static_cast<void*>(&_M_storage);
     107        }
     108  
     109        const void*
     110        _M_addr() const noexcept
     111        {
     112          return static_cast<const void*>(&_M_storage);
     113        }
     114  
     115        _Tp*
     116        _M_ptr() noexcept
     117        { return static_cast<_Tp*>(_M_addr()); }
     118  
     119        const _Tp*
     120        _M_ptr() const noexcept
     121        { return static_cast<const _Tp*>(_M_addr()); }
     122      };
     123  #pragma GCC diagnostic pop
     124  #endif
     125  
     126  } // namespace
     127  
     128  #endif /* _ALIGNED_BUFFER_H */