Line data Source code
1 : // Aligned memory buffer -*- C++ -*- 2 : 3 : // Copyright (C) 2013-2019 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 775322294 : _M_addr() noexcept 65 240684128 : { return static_cast<void*>(&_M_storage); } 66 : 67 : const void* 68 11907198365 : _M_addr() const noexcept 69 11815312160 : { return static_cast<const void*>(&_M_storage); } 70 : 71 : _Tp* 72 775322294 : _M_ptr() noexcept 73 588529980 : { return static_cast<_Tp*>(_M_addr()); } 74 : 75 : const _Tp* 76 11907188359 : _M_ptr() const noexcept 77 11906517826 : { 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 : // Similar to __aligned_membuf but aligned for complete objects, not members. 85 : // This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h> 86 : // and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf 87 : // instead, as it has smaller size for some types on some targets. 88 : // This type is still used to avoid an ABI change. 89 : template<typename _Tp> 90 : struct __aligned_buffer 91 : : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)> 92 : { 93 : typename 94 : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage; 95 : 96 : __aligned_buffer() = default; 97 : 98 : // Can be used to avoid value-initialization 99 : __aligned_buffer(std::nullptr_t) { } 100 : 101 : void* 102 2865 : _M_addr() noexcept 103 : { 104 1910 : return static_cast<void*>(&_M_storage); 105 : } 106 : 107 : const void* 108 : _M_addr() const noexcept 109 : { 110 : return static_cast<const void*>(&_M_storage); 111 : } 112 : 113 : _Tp* 114 2865 : _M_ptr() noexcept 115 1910 : { return static_cast<_Tp*>(_M_addr()); } 116 : 117 : const _Tp* 118 : _M_ptr() const noexcept 119 : { return static_cast<const _Tp*>(_M_addr()); } 120 : }; 121 : #endif 122 : 123 : } // namespace 124 : 125 : #endif /* _ALIGNED_BUFFER_H */