xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/ext/aligned_buffer.h (revision b1e838363e3c6fc78a55519254d99869742dd33c)
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