1//===----------------------------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H 10#define _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H 11 12#include <__config> 13#include <__type_traits/conditional.h> 14#include <__type_traits/integral_constant.h> 15#include <__type_traits/nat.h> 16#include <__type_traits/type_list.h> 17#include <cstddef> 18 19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20# pragma GCC system_header 21#endif 22 23_LIBCPP_BEGIN_NAMESPACE_STD 24 25template <class _Tp> 26struct __align_type 27{ 28 static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp); 29 typedef _Tp type; 30}; 31 32struct __struct_double {long double __lx;}; 33struct __struct_double4 {double __lx[4];}; 34 35typedef 36 __type_list<__align_type<unsigned char>, 37 __type_list<__align_type<unsigned short>, 38 __type_list<__align_type<unsigned int>, 39 __type_list<__align_type<unsigned long>, 40 __type_list<__align_type<unsigned long long>, 41 __type_list<__align_type<double>, 42 __type_list<__align_type<long double>, 43 __type_list<__align_type<__struct_double>, 44 __type_list<__align_type<__struct_double4>, 45 __type_list<__align_type<int*>, 46 __nat 47 > > > > > > > > > > __all_types; 48 49template <size_t _Align> 50struct _ALIGNAS(_Align) __fallback_overaligned {}; 51 52template <class _TL, size_t _Align> struct __find_pod; 53 54template <class _Hp, size_t _Align> 55struct __find_pod<__type_list<_Hp, __nat>, _Align> 56{ 57 typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, __fallback_overaligned<_Align> > type; 58}; 59 60template <class _Hp, class _Tp, size_t _Align> 61struct __find_pod<__type_list<_Hp, _Tp>, _Align> 62{ 63 typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, typename __find_pod<_Tp, _Align>::type> type; 64}; 65 66template <class _TL, size_t _Len> struct __find_max_align; 67 68template <class _Hp, size_t _Len> 69struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {}; 70 71template <size_t _Len, size_t _A1, size_t _A2> 72struct __select_align 73{ 74private: 75 static const size_t __min = _A2 < _A1 ? _A2 : _A1; 76 static const size_t __max = _A1 < _A2 ? _A2 : _A1; 77public: 78 static const size_t value = _Len < __max ? __min : __max; 79}; 80 81template <class _Hp, class _Tp, size_t _Len> 82struct __find_max_align<__type_list<_Hp, _Tp>, _Len> 83 : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {}; 84 85template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> 86struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage 87{ 88 typedef typename __find_pod<__all_types, _Align>::type _Aligner; 89 union type 90 { 91 _Aligner __align; 92 unsigned char __data[(_Len + _Align - 1)/_Align * _Align]; 93 }; 94}; 95 96#if _LIBCPP_STD_VER > 11 97 98 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 99template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> 100 using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type; 101 _LIBCPP_SUPPRESS_DEPRECATED_POP 102 103#endif 104 105#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \ 106template <size_t _Len>\ 107struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\ 108{\ 109 struct _ALIGNAS(n) type\ 110 {\ 111 unsigned char __lx[(_Len + n - 1)/n * n];\ 112 };\ 113} 114 115_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1); 116_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2); 117_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4); 118_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8); 119_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10); 120_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20); 121_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40); 122_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80); 123_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100); 124_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200); 125_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400); 126_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800); 127_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000); 128_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000); 129// PE/COFF does not support alignment beyond 8192 (=0x2000) 130#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) 131_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000); 132#endif // !defined(_LIBCPP_OBJECT_FORMAT_COFF) 133 134#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION 135 136_LIBCPP_END_NAMESPACE_STD 137 138#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H 139