Alignment.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //
  2. // Alignment.h
  3. //
  4. // Library: Foundation
  5. // Package: Dynamic
  6. // Module: Alignment
  7. //
  8. // Definition of the Alignment class.
  9. //
  10. // Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. // Adapted for POCO from LLVM Compiler Infrastructure code:
  16. //
  17. // The LLVM Compiler Infrastructure
  18. //
  19. // This file is distributed under the University of Illinois Open Source License
  20. //
  21. //===----------------------------------------------------------------------===//
  22. //
  23. // This file defines the AlignOf function that computes alignments for
  24. // arbitrary types.
  25. //
  26. //===----------------------------------------------------------------------===//
  27. #ifndef Foundation_AlignOf_INCLUDED
  28. #define Foundation_AlignOf_INCLUDED
  29. #include <cstddef>
  30. #ifdef POCO_ENABLE_CPP11
  31. #include <type_traits>
  32. #define POCO_HAVE_ALIGNMENT
  33. #else
  34. namespace Poco {
  35. template <typename T>
  36. struct AlignmentCalcImpl
  37. {
  38. char x;
  39. T t;
  40. private:
  41. AlignmentCalcImpl() {} // Never instantiate.
  42. };
  43. template <typename T>
  44. struct AlignOf
  45. /// A templated class that contains an enum value representing
  46. /// the alignment of the template argument. For example,
  47. /// AlignOf<int>::Alignment represents the alignment of type "int". The
  48. /// alignment calculated is the minimum alignment, and not necessarily
  49. /// the "desired" alignment returned by GCC's __alignof__ (for example). Note
  50. /// that because the alignment is an enum value, it can be used as a
  51. /// compile-time constant (e.g., for template instantiation).
  52. {
  53. enum
  54. {
  55. Alignment = static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T))
  56. };
  57. enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
  58. enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
  59. enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
  60. enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
  61. enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
  62. enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
  63. enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
  64. enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
  65. };
  66. template <typename T>
  67. inline unsigned alignOf()
  68. /// A templated function that returns the minimum alignment of
  69. /// of a type. This provides no extra functionality beyond the AlignOf
  70. /// class besides some cosmetic cleanliness. Example usage:
  71. /// alignOf<int>() returns the alignment of an int.
  72. {
  73. return AlignOf<T>::Alignment;
  74. }
  75. template <std::size_t Alignment> struct AlignedCharArrayImpl;
  76. /// Helper for building an aligned character array type.
  77. ///
  78. /// This template is used to explicitly build up a collection of aligned
  79. /// character types. We have to build these up using a macro and explicit
  80. /// specialization to cope with old versions of MSVC and GCC where only an
  81. /// integer literal can be used to specify an alignment constraint. Once built
  82. /// up here, we can then begin to indirect between these using normal C++
  83. /// template parameters.
  84. // MSVC requires special handling here.
  85. #ifndef _MSC_VER
  86. #ifdef POCO_COMPILER_CLANG
  87. #if __has_feature(cxx_alignas)
  88. #define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
  89. template <> struct AlignedCharArrayImpl<x> \
  90. { \
  91. char aligned alignas(x); \
  92. }
  93. #define POCO_HAVE_ALIGNMENT
  94. #endif
  95. #elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
  96. #define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
  97. template <> struct AlignedCharArrayImpl<x> \
  98. { \
  99. char aligned __attribute__((aligned(x))); \
  100. }
  101. #define POCO_HAVE_ALIGNMENT
  102. #endif
  103. #ifdef POCO_HAVE_ALIGNMENT
  104. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1);
  105. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2);
  106. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4);
  107. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8);
  108. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
  109. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
  110. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
  111. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
  112. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
  113. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
  114. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
  115. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
  116. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
  117. #undef POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
  118. #endif // POCO_HAVE_ALIGNMENT
  119. #else // _MSC_VER
  120. // We provide special variations of this template for the most common
  121. // alignments because __declspec(align(...)) doesn't actually work when it is
  122. // a member of a by-value function argument in MSVC, even if the alignment
  123. // request is something reasonably like 8-byte or 16-byte.
  124. template <> struct AlignedCharArrayImpl<1> { char aligned; };
  125. template <> struct AlignedCharArrayImpl<2> { short aligned; };
  126. template <> struct AlignedCharArrayImpl<4> { int aligned; };
  127. template <> struct AlignedCharArrayImpl<8> { double aligned; };
  128. #define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
  129. template <> struct AlignedCharArrayImpl<x> { \
  130. __declspec(align(x)) char aligned; \
  131. }
  132. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
  133. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
  134. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
  135. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
  136. #if (_MSC_VER > 1600) // MSVC 2010 complains on alignment larger than 128
  137. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
  138. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
  139. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
  140. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
  141. POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
  142. #endif // _MSC_VER > 1600
  143. // Any larger and MSVC complains.
  144. #undef POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
  145. #define POCO_HAVE_ALIGNMENT
  146. #endif // _MSC_VER
  147. // POCO_HAVE_ALIGNMENT will be defined on the pre-C++11 platforms/compilers where
  148. // it can be reliably determined and used. Uncomment the line below to explicitly
  149. // disable use of alignment even for those platforms.
  150. // #undef POCO_HAVE_ALIGNMENT
  151. #ifdef POCO_HAVE_ALIGNMENT
  152. template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char>
  153. union AlignedCharArrayUnion
  154. /// This union template exposes a suitably aligned and sized character
  155. /// array member which can hold elements of any of up to four types.
  156. ///
  157. /// These types may be arrays, structs, or any other types. The goal is to
  158. /// produce a union type containing a character array which, when used, forms
  159. /// storage suitable to placement new any of these types over. Support for more
  160. /// than four types can be added at the cost of more boiler plate.
  161. {
  162. private:
  163. class AlignerImpl
  164. {
  165. T1 t1;
  166. T2 t2;
  167. T3 t3;
  168. T4 t4;
  169. AlignerImpl(); // Never defined or instantiated.
  170. };
  171. union SizerImpl
  172. {
  173. char arr1[sizeof(T1)];
  174. char arr2[sizeof(T2)];
  175. char arr3[sizeof(T3)];
  176. char arr4[sizeof(T4)];
  177. };
  178. public:
  179. char buffer[sizeof(SizerImpl)];
  180. /// The character array buffer for use by clients.
  181. ///
  182. /// No other member of this union should be referenced. They exist purely to
  183. /// constrain the layout of this character array.
  184. private:
  185. Poco::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment> _nonceMember;
  186. };
  187. #endif // POCO_HAVE_ALIGNMENT
  188. } // namespace Poco
  189. #endif // POCO_ENABLE_CPP11
  190. #endif // Foundation_AlignOf_INCLUDED