WPILibC++  unspecified
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
AlignOf.h
1 //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the AlignOf function that computes alignments for
11 // arbitrary types.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_SUPPORT_ALIGNOF_H
16 #define LLVM_SUPPORT_ALIGNOF_H
17 
18 #include <cstddef>
19 
20 #ifndef __has_feature
21 # define __has_feature(x) 0
22 #endif
23 
24 namespace llvm {
25 template <typename T>
27  char x;
28 #if defined(_MSC_VER)
29 // Disables "structure was padded due to __declspec(align())" warnings that are
30 // generated by any class using AlignOf<T> with a manually specified alignment.
31 // Although the warning is disabled in the LLVM project we need this pragma
32 // as AlignOf.h is a published support header that's available for use
33 // out-of-tree, and we would like that to compile cleanly at /W4.
34 #pragma warning(suppress : 4324)
35 #endif
36  T t;
37 private:
38  AlignmentCalcImpl() {} // Never instantiate.
39 };
40 
48 template <typename T>
49 struct AlignOf {
50 #ifndef _MSC_VER
51  // Avoid warnings from GCC like:
52  // comparison between 'enum llvm::AlignOf<X>::<anonymous>' and 'enum
53  // llvm::AlignOf<Y>::<anonymous>' [-Wenum-compare]
54  // by using constexpr instead of enum.
55  // (except on MSVC, since it doesn't support constexpr yet).
56  static constexpr unsigned Alignment =
57  static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T));
58 #else
59  enum { Alignment =
60  static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) };
61 #endif
62  enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
63  enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
64  enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
65  enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
66 
67  enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
68  enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
69  enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
70  enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
71 };
72 
73 #ifndef _MSC_VER
74 template <typename T> constexpr unsigned AlignOf<T>::Alignment;
75 #endif
76 
81 template <typename T>
82 inline unsigned alignOf() { return AlignOf<T>::Alignment; }
83 
93 
94 // MSVC requires special handling here.
95 #ifndef _MSC_VER
96 
97 #if __has_feature(cxx_alignas)
98 template<std::size_t Alignment, std::size_t Size>
99 struct AlignedCharArray {
100  alignas(Alignment) char buffer[Size];
101 };
102 
103 #elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
104 template<std::size_t Alignment, std::size_t Size>
106 struct AlignedCharArray;
107 
108 #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
109  template<std::size_t Size> \
110  struct AlignedCharArray<x, Size> { \
111  __attribute__((aligned(x))) char buffer[Size]; \
112  };
113 
114 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1)
115 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2)
116 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4)
117 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8)
118 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
119 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
120 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
121 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
122 
123 #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
124 
125 #else
126 # error No supported align as directive.
127 #endif
128 
129 #else // _MSC_VER
130 
132 template<std::size_t Alignment, std::size_t Size>
133 struct AlignedCharArray;
134 
135 // We provide special variations of this template for the most common
136 // alignments because __declspec(align(...)) doesn't actually work when it is
137 // a member of a by-value function argument in MSVC, even if the alignment
138 // request is something reasonably like 8-byte or 16-byte. Note that we can't
139 // even include the declspec with the union that forces the alignment because
140 // MSVC warns on the existence of the declspec despite the union member forcing
141 // proper alignment.
142 
143 template<std::size_t Size>
144 struct AlignedCharArray<1, Size> {
145  union {
146  char aligned;
147  char buffer[Size];
148  };
149 };
150 
151 template<std::size_t Size>
152 struct AlignedCharArray<2, Size> {
153  union {
154  short aligned;
155  char buffer[Size];
156  };
157 };
158 
159 template<std::size_t Size>
160 struct AlignedCharArray<4, Size> {
161  union {
162  int aligned;
163  char buffer[Size];
164  };
165 };
166 
167 template<std::size_t Size>
168 struct AlignedCharArray<8, Size> {
169  union {
170  double aligned;
171  char buffer[Size];
172  };
173 };
174 
175 
176 // The rest of these are provided with a __declspec(align(...)) and we simply
177 // can't pass them by-value as function arguments on MSVC.
178 
179 #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
180  template<std::size_t Size> \
181  struct AlignedCharArray<x, Size> { \
182  __declspec(align(x)) char buffer[Size]; \
183  };
184 
185 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
186 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
187 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
188 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
189 
190 #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
191 
192 #endif // _MSC_VER
193 
194 namespace detail {
195 template <typename T1,
196  typename T2 = char, typename T3 = char, typename T4 = char,
197  typename T5 = char, typename T6 = char, typename T7 = char,
198  typename T8 = char, typename T9 = char, typename T10 = char>
199 class AlignerImpl {
200  T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
201 
202  AlignerImpl(); // Never defined or instantiated.
203 };
204 
205 template <typename T1,
206  typename T2 = char, typename T3 = char, typename T4 = char,
207  typename T5 = char, typename T6 = char, typename T7 = char,
208  typename T8 = char, typename T9 = char, typename T10 = char>
209 union SizerImpl {
210  char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
211  arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
212  arr9[sizeof(T9)], arr10[sizeof(T10)];
213 };
214 } // end namespace detail
215 
223 template <typename T1,
224  typename T2 = char, typename T3 = char, typename T4 = char,
225  typename T5 = char, typename T6 = char, typename T7 = char,
226  typename T8 = char, typename T9 = char, typename T10 = char>
227 struct AlignedCharArrayUnion : llvm::AlignedCharArray<
228  AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5,
229  T6, T7, T8, T9, T10> >::Alignment,
230  sizeof(detail::SizerImpl<T1, T2, T3, T4, T5,
231  T6, T7, T8, T9, T10>)> {
232 };
233 } // end namespace llvm
234 #endif
AlignOf - A templated class that contains an enum value representing the alignment of the template ar...
Definition: AlignOf.h:49
Helper for building an aligned character array type.
Definition: AlignOf.h:26
Definition: AlignOf.h:209
This union template exposes a suitably aligned and sized character array member which can hold elemen...
Definition: AlignOf.h:227
Definition: AlignOf.h:199