14d5abbe8Smrg // Aligned memory buffer -*- C++ -*- 24d5abbe8Smrg 3*b1e83836Smrg // Copyright (C) 2013-2022 Free Software Foundation, Inc. 44d5abbe8Smrg // 54d5abbe8Smrg // This file is part of the GNU ISO C++ Library. This library is free 64d5abbe8Smrg // software; you can redistribute it and/or modify it under the 74d5abbe8Smrg // terms of the GNU General Public License as published by the 84d5abbe8Smrg // Free Software Foundation; either version 3, or (at your option) 94d5abbe8Smrg // any later version. 104d5abbe8Smrg 114d5abbe8Smrg // This library is distributed in the hope that it will be useful, 124d5abbe8Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 134d5abbe8Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144d5abbe8Smrg // GNU General Public License for more details. 154d5abbe8Smrg 164d5abbe8Smrg // Under Section 7 of GPL version 3, you are granted additional 174d5abbe8Smrg // permissions described in the GCC Runtime Library Exception, version 184d5abbe8Smrg // 3.1, as published by the Free Software Foundation. 194d5abbe8Smrg 204d5abbe8Smrg // You should have received a copy of the GNU General Public License and 214d5abbe8Smrg // a copy of the GCC Runtime Library Exception along with this program; 224d5abbe8Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234d5abbe8Smrg // <http://www.gnu.org/licenses/>. 244d5abbe8Smrg 254d5abbe8Smrg /** @file ext/aligned_buffer.h 264d5abbe8Smrg * This file is a GNU extension to the Standard C++ Library. 274d5abbe8Smrg */ 284d5abbe8Smrg 294d5abbe8Smrg #ifndef _ALIGNED_BUFFER_H 304d5abbe8Smrg #define _ALIGNED_BUFFER_H 1 314d5abbe8Smrg 324d5abbe8Smrg #pragma GCC system_header 334d5abbe8Smrg 344d5abbe8Smrg #if __cplusplus >= 201103L 354d5abbe8Smrg # include <type_traits> 364d5abbe8Smrg #else 374d5abbe8Smrg # include <bits/c++0x_warning.h> 384d5abbe8Smrg #endif 394d5abbe8Smrg 404d5abbe8Smrg namespace __gnu_cxx 414d5abbe8Smrg { 424d5abbe8Smrg // A utility type containing a POD object that can hold an object of type 434d5abbe8Smrg // _Tp initialized via placement new or allocator_traits::construct. 444d5abbe8Smrg // Intended for use as a data member subobject, use __aligned_buffer for 454d5abbe8Smrg // complete objects. 464d5abbe8Smrg template<typename _Tp> 474d5abbe8Smrg struct __aligned_membuf 484d5abbe8Smrg { 494d5abbe8Smrg // Target macro ADJUST_FIELD_ALIGN can produce different alignment for 504d5abbe8Smrg // types when used as class members. __aligned_membuf is intended 514d5abbe8Smrg // for use as a class member, so align the buffer as for a class member. 52a3e9eb18Smrg // Since GCC 8 we could just use alignof(_Tp) instead, but older 53a3e9eb18Smrg // versions of non-GNU compilers might still need this trick. 544d5abbe8Smrg struct _Tp2 { _Tp _M_t; }; 554d5abbe8Smrg 564d5abbe8Smrg alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)]; 574d5abbe8Smrg 584d5abbe8Smrg __aligned_membuf() = default; 594d5abbe8Smrg 604d5abbe8Smrg // Can be used to avoid value-initialization zeroing _M_storage. __aligned_membuf__aligned_membuf614d5abbe8Smrg __aligned_membuf(std::nullptr_t) { } 624d5abbe8Smrg 634d5abbe8Smrg void* _M_addr__aligned_membuf644d5abbe8Smrg _M_addr() noexcept 654d5abbe8Smrg { return static_cast<void*>(&_M_storage); } 664d5abbe8Smrg 674d5abbe8Smrg const void* _M_addr__aligned_membuf684d5abbe8Smrg _M_addr() const noexcept 694d5abbe8Smrg { return static_cast<const void*>(&_M_storage); } 704d5abbe8Smrg 714d5abbe8Smrg _Tp* _M_ptr__aligned_membuf724d5abbe8Smrg _M_ptr() noexcept 734d5abbe8Smrg { return static_cast<_Tp*>(_M_addr()); } 744d5abbe8Smrg 754d5abbe8Smrg const _Tp* _M_ptr__aligned_membuf764d5abbe8Smrg _M_ptr() const noexcept 774d5abbe8Smrg { return static_cast<const _Tp*>(_M_addr()); } 784d5abbe8Smrg }; 794d5abbe8Smrg 80a3e9eb18Smrg #if _GLIBCXX_INLINE_VERSION 81a3e9eb18Smrg template<typename _Tp> 82a3e9eb18Smrg using __aligned_buffer = __aligned_membuf<_Tp>; 83a3e9eb18Smrg #else 844d5abbe8Smrg // Similar to __aligned_membuf but aligned for complete objects, not members. 854d5abbe8Smrg // This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h> 864d5abbe8Smrg // and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf 874d5abbe8Smrg // instead, as it has smaller size for some types on some targets. 884d5abbe8Smrg // This type is still used to avoid an ABI change. 894d5abbe8Smrg template<typename _Tp> 904d5abbe8Smrg struct __aligned_buffer 91a3e9eb18Smrg : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)> 924d5abbe8Smrg { 934d5abbe8Smrg typename 94a3e9eb18Smrg std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage; 954d5abbe8Smrg 964d5abbe8Smrg __aligned_buffer() = default; 974d5abbe8Smrg 984d5abbe8Smrg // Can be used to avoid value-initialization __aligned_buffer__aligned_buffer994d5abbe8Smrg __aligned_buffer(std::nullptr_t) { } 1004d5abbe8Smrg 1014d5abbe8Smrg void* _M_addr__aligned_buffer1024d5abbe8Smrg _M_addr() noexcept 1034d5abbe8Smrg { 1044d5abbe8Smrg return static_cast<void*>(&_M_storage); 1054d5abbe8Smrg } 1064d5abbe8Smrg 1074d5abbe8Smrg const void* _M_addr__aligned_buffer1084d5abbe8Smrg _M_addr() const noexcept 1094d5abbe8Smrg { 1104d5abbe8Smrg return static_cast<const void*>(&_M_storage); 1114d5abbe8Smrg } 1124d5abbe8Smrg 1134d5abbe8Smrg _Tp* _M_ptr__aligned_buffer1144d5abbe8Smrg _M_ptr() noexcept 1154d5abbe8Smrg { return static_cast<_Tp*>(_M_addr()); } 1164d5abbe8Smrg 1174d5abbe8Smrg const _Tp* _M_ptr__aligned_buffer1184d5abbe8Smrg _M_ptr() const noexcept 1194d5abbe8Smrg { return static_cast<const _Tp*>(_M_addr()); } 1204d5abbe8Smrg }; 121a3e9eb18Smrg #endif 1224d5abbe8Smrg 1234d5abbe8Smrg } // namespace 1244d5abbe8Smrg 1254d5abbe8Smrg #endif /* _ALIGNED_BUFFER_H */ 126