AlignOf.h 4.7 KB

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