[ARM] MVE integer min and max
[llvm-complete.git] / include / llvm / Support / AlignOf.h
blobd12401f0eb49a32983cdd9feab1103e1ca280b9b
1 //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
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 // This file defines the AlignedCharArray and AlignedCharArrayUnion classes.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_SUPPORT_ALIGNOF_H
14 #define LLVM_SUPPORT_ALIGNOF_H
16 #include "llvm/Support/Compiler.h"
17 #include <cstddef>
19 namespace llvm {
21 /// \struct AlignedCharArray
22 /// Helper for building an aligned character array type.
23 ///
24 /// This template is used to explicitly build up a collection of aligned
25 /// character array types. We have to build these up using a macro and explicit
26 /// specialization to cope with MSVC (at least till 2015) where only an
27 /// integer literal can be used to specify an alignment constraint. Once built
28 /// up here, we can then begin to indirect between these using normal C++
29 /// template parameters.
31 // MSVC requires special handling here.
32 #ifndef _MSC_VER
34 template<std::size_t Alignment, std::size_t Size>
35 struct AlignedCharArray {
36 alignas(Alignment) char buffer[Size];
39 #else // _MSC_VER
41 /// Create a type with an aligned char buffer.
42 template<std::size_t Alignment, std::size_t Size>
43 struct AlignedCharArray;
45 // We provide special variations of this template for the most common
46 // alignments because __declspec(align(...)) doesn't actually work when it is
47 // a member of a by-value function argument in MSVC, even if the alignment
48 // request is something reasonably like 8-byte or 16-byte. Note that we can't
49 // even include the declspec with the union that forces the alignment because
50 // MSVC warns on the existence of the declspec despite the union member forcing
51 // proper alignment.
53 template<std::size_t Size>
54 struct AlignedCharArray<1, Size> {
55 union {
56 char aligned;
57 char buffer[Size];
61 template<std::size_t Size>
62 struct AlignedCharArray<2, Size> {
63 union {
64 short aligned;
65 char buffer[Size];
69 template<std::size_t Size>
70 struct AlignedCharArray<4, Size> {
71 union {
72 int aligned;
73 char buffer[Size];
77 template<std::size_t Size>
78 struct AlignedCharArray<8, Size> {
79 union {
80 double aligned;
81 char buffer[Size];
86 // The rest of these are provided with a __declspec(align(...)) and we simply
87 // can't pass them by-value as function arguments on MSVC.
89 #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
90 template<std::size_t Size> \
91 struct AlignedCharArray<x, Size> { \
92 __declspec(align(x)) char buffer[Size]; \
95 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
96 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
97 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
98 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
100 #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
102 #endif // _MSC_VER
104 namespace detail {
105 template <typename T1,
106 typename T2 = char, typename T3 = char, typename T4 = char,
107 typename T5 = char, typename T6 = char, typename T7 = char,
108 typename T8 = char, typename T9 = char, typename T10 = char>
109 class AlignerImpl {
110 T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
112 AlignerImpl() = delete;
115 template <typename T1,
116 typename T2 = char, typename T3 = char, typename T4 = char,
117 typename T5 = char, typename T6 = char, typename T7 = char,
118 typename T8 = char, typename T9 = char, typename T10 = char>
119 union SizerImpl {
120 char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
121 arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
122 arr9[sizeof(T9)], arr10[sizeof(T10)];
124 } // end namespace detail
126 /// This union template exposes a suitably aligned and sized character
127 /// array member which can hold elements of any of up to ten types.
129 /// These types may be arrays, structs, or any other types. The goal is to
130 /// expose a char array buffer member which can be used as suitable storage for
131 /// a placement new of any of these types. Support for more than ten types can
132 /// be added at the cost of more boilerplate.
133 template <typename T1,
134 typename T2 = char, typename T3 = char, typename T4 = char,
135 typename T5 = char, typename T6 = char, typename T7 = char,
136 typename T8 = char, typename T9 = char, typename T10 = char>
137 struct AlignedCharArrayUnion : llvm::AlignedCharArray<
138 alignof(llvm::detail::AlignerImpl<T1, T2, T3, T4, T5,
139 T6, T7, T8, T9, T10>),
140 sizeof(::llvm::detail::SizerImpl<T1, T2, T3, T4, T5,
141 T6, T7, T8, T9, T10>)> {
143 } // end namespace llvm
145 #endif // LLVM_SUPPORT_ALIGNOF_H