aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/libcxx/include/__type_traits/aligned_storage.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/libcxx/include/__type_traits/aligned_storage.h')
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/aligned_storage.h142
1 files changed, 142 insertions, 0 deletions
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/aligned_storage.h b/contrib/llvm-project/libcxx/include/__type_traits/aligned_storage.h
new file mode 100644
index 000000000000..9659a90ae50c
--- /dev/null
+++ b/contrib/llvm-project/libcxx/include/__type_traits/aligned_storage.h
@@ -0,0 +1,142 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H
+#define _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H
+
+#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/nat.h>
+#include <__type_traits/type_list.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __align_type
+{
+ static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
+ typedef _Tp type;
+};
+
+struct __struct_double {long double __lx;};
+struct __struct_double4 {double __lx[4];};
+
+typedef
+ __type_list<__align_type<unsigned char>,
+ __type_list<__align_type<unsigned short>,
+ __type_list<__align_type<unsigned int>,
+ __type_list<__align_type<unsigned long>,
+ __type_list<__align_type<unsigned long long>,
+ __type_list<__align_type<double>,
+ __type_list<__align_type<long double>,
+ __type_list<__align_type<__struct_double>,
+ __type_list<__align_type<__struct_double4>,
+ __type_list<__align_type<int*>,
+ __nat
+ > > > > > > > > > > __all_types;
+
+template <size_t _Align>
+struct _ALIGNAS(_Align) __fallback_overaligned {};
+
+template <class _TL, size_t _Align> struct __find_pod;
+
+template <class _Hp, size_t _Align>
+struct __find_pod<__type_list<_Hp, __nat>, _Align>
+{
+ typedef typename conditional<
+ _Align == _Hp::value,
+ typename _Hp::type,
+ __fallback_overaligned<_Align>
+ >::type type;
+};
+
+template <class _Hp, class _Tp, size_t _Align>
+struct __find_pod<__type_list<_Hp, _Tp>, _Align>
+{
+ typedef typename conditional<
+ _Align == _Hp::value,
+ typename _Hp::type,
+ typename __find_pod<_Tp, _Align>::type
+ >::type type;
+};
+
+template <class _TL, size_t _Len> struct __find_max_align;
+
+template <class _Hp, size_t _Len>
+struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};
+
+template <size_t _Len, size_t _A1, size_t _A2>
+struct __select_align
+{
+private:
+ static const size_t __min = _A2 < _A1 ? _A2 : _A1;
+ static const size_t __max = _A1 < _A2 ? _A2 : _A1;
+public:
+ static const size_t value = _Len < __max ? __min : __max;
+};
+
+template <class _Hp, class _Tp, size_t _Len>
+struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
+ : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
+
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+struct _LIBCPP_TEMPLATE_VIS aligned_storage
+{
+ typedef typename __find_pod<__all_types, _Align>::type _Aligner;
+ union type
+ {
+ _Aligner __align;
+ unsigned char __data[(_Len + _Align - 1)/_Align * _Align];
+ };
+};
+
+#if _LIBCPP_STD_VER > 11
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+ using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
+#endif
+
+#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
+template <size_t _Len>\
+struct _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
+{\
+ struct _ALIGNAS(n) type\
+ {\
+ unsigned char __lx[(_Len + n - 1)/n * n];\
+ };\
+}
+
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000);
+// PE/COFF does not support alignment beyond 8192 (=0x2000)
+#if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000);
+#endif // !defined(_LIBCPP_OBJECT_FORMAT_COFF)
+
+#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H