1    	// Aligned memory buffer -*- C++ -*-
2    	
3    	// Copyright (C) 2013-2017 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   	      struct _Tp2 { _Tp _M_t; };
53   	
54   	      alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
55   	
56   	      __aligned_membuf() = default;
57   	
58   	      // Can be used to avoid value-initialization zeroing _M_storage.
59   	      __aligned_membuf(std::nullptr_t) { }
60   	
61   	      void*
62   	      _M_addr() noexcept
63   	      { return static_cast<void*>(&_M_storage); }
64   	
65   	      const void*
66   	      _M_addr() const noexcept
67   	      { return static_cast<const void*>(&_M_storage); }
68   	
69   	      _Tp*
70   	      _M_ptr() noexcept
71   	      { return static_cast<_Tp*>(_M_addr()); }
72   	
73   	      const _Tp*
74   	      _M_ptr() const noexcept
75   	      { return static_cast<const _Tp*>(_M_addr()); }
76   	    };
77   	
78   	  // Similar to __aligned_membuf but aligned for complete objects, not members.
79   	  // This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h>
80   	  // and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf
81   	  // instead, as it has smaller size for some types on some targets.
82   	  // This type is still used to avoid an ABI change.
83   	  template<typename _Tp>
84   	    struct __aligned_buffer
85   	    : std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>
86   	    {
87   	      typename
88   		std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>::type
89   		_M_storage;
90   	
91   	      __aligned_buffer() = default;
92   	
93   	      // Can be used to avoid value-initialization
94   	      __aligned_buffer(std::nullptr_t) { }
95   	
96   	      void*
97   	      _M_addr() noexcept
98   	      {
99   	        return static_cast<void*>(&_M_storage);
100  	      }
101  	
102  	      const void*
103  	      _M_addr() const noexcept
104  	      {
105  	        return static_cast<const void*>(&_M_storage);
106  	      }
107  	
108  	      _Tp*
109  	      _M_ptr() noexcept
110  	      { return static_cast<_Tp*>(_M_addr()); }
111  	
112  	      const _Tp*
113  	      _M_ptr() const noexcept
114  	      { return static_cast<const _Tp*>(_M_addr()); }
115  	    };
116  	
117  	} // namespace
118  	
119  	#endif /* _ALIGNED_BUFFER_H */
120