AlignOf.h 4.8 KB

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