xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/ext/aligned_buffer.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // Aligned memory buffer -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 2013-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj /** @file ext/aligned_buffer.h
2638fd1498Szrj  *  This file is a GNU extension to the Standard C++ Library.
2738fd1498Szrj  */
2838fd1498Szrj 
2938fd1498Szrj #ifndef _ALIGNED_BUFFER_H
3038fd1498Szrj #define _ALIGNED_BUFFER_H 1
3138fd1498Szrj 
3238fd1498Szrj #pragma GCC system_header
3338fd1498Szrj 
3438fd1498Szrj #if __cplusplus >= 201103L
3538fd1498Szrj # include <type_traits>
3638fd1498Szrj #else
3738fd1498Szrj # include <bits/c++0x_warning.h>
3838fd1498Szrj #endif
3938fd1498Szrj 
4038fd1498Szrj namespace __gnu_cxx
4138fd1498Szrj {
4238fd1498Szrj   // A utility type containing a POD object that can hold an object of type
4338fd1498Szrj   // _Tp initialized via placement new or allocator_traits::construct.
4438fd1498Szrj   // Intended for use as a data member subobject, use __aligned_buffer for
4538fd1498Szrj   // complete objects.
4638fd1498Szrj   template<typename _Tp>
4738fd1498Szrj     struct __aligned_membuf
4838fd1498Szrj     {
4938fd1498Szrj       // Target macro ADJUST_FIELD_ALIGN can produce different alignment for
5038fd1498Szrj       // types when used as class members. __aligned_membuf is intended
5138fd1498Szrj       // for use as a class member, so align the buffer as for a class member.
52*58e805e6Szrj       // Since GCC 8 we could just use alignof(_Tp) instead, but older
53*58e805e6Szrj       // versions of non-GNU compilers might still need this trick.
5438fd1498Szrj       struct _Tp2 { _Tp _M_t; };
5538fd1498Szrj 
5638fd1498Szrj       alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
5738fd1498Szrj 
5838fd1498Szrj       __aligned_membuf() = default;
5938fd1498Szrj 
6038fd1498Szrj       // Can be used to avoid value-initialization zeroing _M_storage.
__aligned_membuf__aligned_membuf6138fd1498Szrj       __aligned_membuf(std::nullptr_t) { }
6238fd1498Szrj 
6338fd1498Szrj       void*
_M_addr__aligned_membuf6438fd1498Szrj       _M_addr() noexcept
6538fd1498Szrj       { return static_cast<void*>(&_M_storage); }
6638fd1498Szrj 
6738fd1498Szrj       const void*
_M_addr__aligned_membuf6838fd1498Szrj       _M_addr() const noexcept
6938fd1498Szrj       { return static_cast<const void*>(&_M_storage); }
7038fd1498Szrj 
7138fd1498Szrj       _Tp*
_M_ptr__aligned_membuf7238fd1498Szrj       _M_ptr() noexcept
7338fd1498Szrj       { return static_cast<_Tp*>(_M_addr()); }
7438fd1498Szrj 
7538fd1498Szrj       const _Tp*
_M_ptr__aligned_membuf7638fd1498Szrj       _M_ptr() const noexcept
7738fd1498Szrj       { return static_cast<const _Tp*>(_M_addr()); }
7838fd1498Szrj     };
7938fd1498Szrj 
8038fd1498Szrj #if _GLIBCXX_INLINE_VERSION
8138fd1498Szrj   template<typename _Tp>
8238fd1498Szrj     using __aligned_buffer = __aligned_membuf<_Tp>;
8338fd1498Szrj #else
8438fd1498Szrj   // Similar to __aligned_membuf but aligned for complete objects, not members.
8538fd1498Szrj   // This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h>
8638fd1498Szrj   // and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf
8738fd1498Szrj   // instead, as it has smaller size for some types on some targets.
8838fd1498Szrj   // This type is still used to avoid an ABI change.
8938fd1498Szrj   template<typename _Tp>
9038fd1498Szrj     struct __aligned_buffer
91*58e805e6Szrj     : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>
9238fd1498Szrj     {
9338fd1498Szrj       typename
94*58e805e6Szrj 	std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage;
9538fd1498Szrj 
9638fd1498Szrj       __aligned_buffer() = default;
9738fd1498Szrj 
9838fd1498Szrj       // Can be used to avoid value-initialization
__aligned_buffer__aligned_buffer9938fd1498Szrj       __aligned_buffer(std::nullptr_t) { }
10038fd1498Szrj 
10138fd1498Szrj       void*
_M_addr__aligned_buffer10238fd1498Szrj       _M_addr() noexcept
10338fd1498Szrj       {
10438fd1498Szrj         return static_cast<void*>(&_M_storage);
10538fd1498Szrj       }
10638fd1498Szrj 
10738fd1498Szrj       const void*
_M_addr__aligned_buffer10838fd1498Szrj       _M_addr() const noexcept
10938fd1498Szrj       {
11038fd1498Szrj         return static_cast<const void*>(&_M_storage);
11138fd1498Szrj       }
11238fd1498Szrj 
11338fd1498Szrj       _Tp*
_M_ptr__aligned_buffer11438fd1498Szrj       _M_ptr() noexcept
11538fd1498Szrj       { return static_cast<_Tp*>(_M_addr()); }
11638fd1498Szrj 
11738fd1498Szrj       const _Tp*
_M_ptr__aligned_buffer11838fd1498Szrj       _M_ptr() const noexcept
11938fd1498Szrj       { return static_cast<const _Tp*>(_M_addr()); }
12038fd1498Szrj     };
12138fd1498Szrj #endif
12238fd1498Szrj 
12338fd1498Szrj } // namespace
12438fd1498Szrj 
12538fd1498Szrj #endif /* _ALIGNED_BUFFER_H */
126