Alignment.h 7.4 KB

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