Home | History | Annotate | Line # | Download | only in ext
      1 // Aligned memory buffer -*- C++ -*-
      2 
      3 // Copyright (C) 2013-2024 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 */
    129