type_with_alignment.hpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // (C) Copyright John Maddock 2000.
  2. // Use, modification and distribution are subject to the Boost Software License,
  3. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt).
  5. //
  6. // See http://www.boost.org/libs/type_traits for most recent version including documentation.
  7. #ifndef BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
  8. #define BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
  9. #include <boost/type_traits/alignment_of.hpp>
  10. #include <boost/type_traits/is_pod.hpp>
  11. #include <boost/static_assert.hpp>
  12. #include <boost/config.hpp>
  13. #include <cstddef> // size_t
  14. #include <boost/detail/workaround.hpp>
  15. #ifdef BOOST_MSVC
  16. # pragma warning(push)
  17. # pragma warning(disable: 4121) // alignment is sensitive to packing
  18. #endif
  19. #ifdef _MSC_VER
  20. #include <boost/type_traits/conditional.hpp>
  21. #endif
  22. namespace boost {
  23. #ifndef __BORLANDC__
  24. namespace detail{
  25. union max_align
  26. {
  27. char c;
  28. short s;
  29. int i;
  30. long l;
  31. #ifndef BOOST_NO_LONG_LONG
  32. boost::long_long_type ll;
  33. #endif
  34. #ifdef BOOST_HAS_INT128
  35. boost::int128_type i128;
  36. #endif
  37. float f;
  38. double d;
  39. long double ld;
  40. #ifdef BOOST_HAS_FLOAT128
  41. __float128 f128;
  42. #endif
  43. };
  44. template <std::size_t Target, bool check> struct long_double_alignment{ typedef long double type; };
  45. template <std::size_t Target> struct long_double_alignment<Target, false>{ typedef boost::detail::max_align type; };
  46. template <std::size_t Target, bool check> struct double_alignment{ typedef double type; };
  47. template <std::size_t Target> struct double_alignment<Target, false>{ typedef typename long_double_alignment<Target, boost::alignment_of<long double>::value >= Target>::type type; };
  48. #ifndef BOOST_NO_LONG_LONG
  49. template <std::size_t Target, bool check> struct long_long_alignment{ typedef boost::long_long_type type; };
  50. template <std::size_t Target> struct long_long_alignment<Target, false>{ typedef typename double_alignment<Target, boost::alignment_of<double>::value >= Target>::type type; };
  51. #endif
  52. template <std::size_t Target, bool check> struct long_alignment{ typedef long type; };
  53. #ifndef BOOST_NO_LONG_LONG
  54. template <std::size_t Target> struct long_alignment<Target, false>{ typedef typename long_long_alignment<Target, boost::alignment_of<boost::long_long_type>::value >= Target>::type type; };
  55. #else
  56. template <std::size_t Target> struct long_alignment<Target, false>{ typedef typename double_alignment<Target, boost::alignment_of<double>::value >= Target>::type type; };
  57. #endif
  58. template <std::size_t Target, bool check> struct int_alignment{ typedef int type; };
  59. template <std::size_t Target> struct int_alignment<Target, false>{ typedef typename long_alignment<Target, boost::alignment_of<long>::value >= Target>::type type; };
  60. template <std::size_t Target, bool check> struct short_alignment{ typedef short type; };
  61. template <std::size_t Target> struct short_alignment<Target, false>{ typedef typename int_alignment<Target, boost::alignment_of<int>::value >= Target>::type type; };
  62. template <std::size_t Target, bool check> struct char_alignment{ typedef char type; };
  63. template <std::size_t Target> struct char_alignment<Target, false>{ typedef typename short_alignment<Target, boost::alignment_of<short>::value >= Target>::type type; };
  64. } // namespace detail
  65. template <std::size_t Align>
  66. struct type_with_alignment
  67. {
  68. typedef typename boost::detail::char_alignment<Align, boost::alignment_of<char>::value >= Align>::type type;
  69. };
  70. #if (defined(__GNUC__) || (defined (__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) || defined(__clang__)) && !defined(BOOST_TT_DISABLE_INTRINSICS)
  71. namespace tt_align_ns {
  72. struct __attribute__((__aligned__(2))) a2 {};
  73. struct __attribute__((__aligned__(4))) a4 {};
  74. struct __attribute__((__aligned__(8))) a8 {};
  75. struct __attribute__((__aligned__(16))) a16 {};
  76. struct __attribute__((__aligned__(32))) a32 {};
  77. struct __attribute__((__aligned__(64))) a64 {};
  78. struct __attribute__((__aligned__(128))) a128 {};
  79. }
  80. template<> struct type_with_alignment<1> { public: typedef char type; };
  81. template<> struct type_with_alignment<2> { public: typedef tt_align_ns::a2 type; };
  82. template<> struct type_with_alignment<4> { public: typedef tt_align_ns::a4 type; };
  83. template<> struct type_with_alignment<8> { public: typedef tt_align_ns::a8 type; };
  84. template<> struct type_with_alignment<16> { public: typedef tt_align_ns::a16 type; };
  85. template<> struct type_with_alignment<32> { public: typedef tt_align_ns::a32 type; };
  86. template<> struct type_with_alignment<64> { public: typedef tt_align_ns::a64 type; };
  87. template<> struct type_with_alignment<128> { public: typedef tt_align_ns::a128 type; };
  88. template<> struct is_pod< ::boost::tt_align_ns::a2> : public true_type{};
  89. template<> struct is_pod< ::boost::tt_align_ns::a4> : public true_type{};
  90. template<> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{};
  91. template<> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{};
  92. template<> struct is_pod< ::boost::tt_align_ns::a32> : public true_type{};
  93. template<> struct is_pod< ::boost::tt_align_ns::a64> : public true_type{};
  94. template<> struct is_pod< ::boost::tt_align_ns::a128> : public true_type{};
  95. #endif
  96. #if (defined(BOOST_MSVC) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && !defined(BOOST_TT_DISABLE_INTRINSICS)
  97. //
  98. // MSVC supports types which have alignments greater than the normal
  99. // maximum: these are used for example in the types __m64 and __m128
  100. // to provide types with alignment requirements which match the SSE
  101. // registers. Therefore we extend type_with_alignment<> to support
  102. // such types, however, we have to be careful to use a builtin type
  103. // whenever possible otherwise we break previously working code:
  104. // see http://article.gmane.org/gmane.comp.lib.boost.devel/173011
  105. // for an example and test case. Thus types like a8 below will
  106. // be used *only* if the existing implementation can't provide a type
  107. // with suitable alignment. This does mean however, that type_with_alignment<>
  108. // may return a type which cannot be passed through a function call
  109. // by value (and neither can any type containing such a type like
  110. // Boost.Optional). However, this only happens when we have no choice
  111. // in the matter because no other "ordinary" type is available.
  112. //
  113. namespace tt_align_ns {
  114. struct __declspec(align(8)) a8 {
  115. char m[8];
  116. typedef a8 type;
  117. };
  118. struct __declspec(align(16)) a16 {
  119. char m[16];
  120. typedef a16 type;
  121. };
  122. struct __declspec(align(32)) a32 {
  123. char m[32];
  124. typedef a32 type;
  125. };
  126. struct __declspec(align(64)) a64
  127. {
  128. char m[64];
  129. typedef a64 type;
  130. };
  131. struct __declspec(align(128)) a128 {
  132. char m[128];
  133. typedef a128 type;
  134. };
  135. }
  136. template<> struct type_with_alignment<8>
  137. {
  138. typedef boost::conditional<
  139. ::boost::alignment_of<boost::detail::max_align>::value < 8,
  140. tt_align_ns::a8,
  141. boost::detail::char_alignment<8, false> >::type t1;
  142. public:
  143. typedef t1::type type;
  144. };
  145. template<> struct type_with_alignment<16>
  146. {
  147. typedef boost::conditional<
  148. ::boost::alignment_of<boost::detail::max_align>::value < 16,
  149. tt_align_ns::a16,
  150. boost::detail::char_alignment<16, false> >::type t1;
  151. public:
  152. typedef t1::type type;
  153. };
  154. template<> struct type_with_alignment<32>
  155. {
  156. typedef boost::conditional<
  157. ::boost::alignment_of<boost::detail::max_align>::value < 32,
  158. tt_align_ns::a32,
  159. boost::detail::char_alignment<32, false> >::type t1;
  160. public:
  161. typedef t1::type type;
  162. };
  163. template<> struct type_with_alignment<64> {
  164. typedef boost::conditional<
  165. ::boost::alignment_of<boost::detail::max_align>::value < 64,
  166. tt_align_ns::a64,
  167. boost::detail::char_alignment<64, false> >::type t1;
  168. public:
  169. typedef t1::type type;
  170. };
  171. template<> struct type_with_alignment<128> {
  172. typedef boost::conditional<
  173. ::boost::alignment_of<boost::detail::max_align>::value < 128,
  174. tt_align_ns::a128,
  175. boost::detail::char_alignment<128, false> >::type t1;
  176. public:
  177. typedef t1::type type;
  178. };
  179. template<> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{};
  180. template<> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{};
  181. template<> struct is_pod< ::boost::tt_align_ns::a32> : public true_type{};
  182. template<> struct is_pod< ::boost::tt_align_ns::a64> : public true_type{};
  183. template<> struct is_pod< ::boost::tt_align_ns::a128> : public true_type{};
  184. #endif
  185. #else
  186. //
  187. // Borland specific version, we have this for two reasons:
  188. // 1) The version above doesn't always compile (with the new test cases for example)
  189. // 2) Because of Borlands #pragma option we can create types with alignments that are
  190. // greater that the largest aligned builtin type.
  191. namespace tt_align_ns{
  192. #pragma option push -a16
  193. struct a2{ short s; };
  194. struct a4{ int s; };
  195. struct a8{ double s; };
  196. struct a16{ long double s; };
  197. #pragma option pop
  198. }
  199. namespace detail {
  200. typedef ::boost::tt_align_ns::a16 max_align;
  201. }
  202. //#if ! BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
  203. template <> struct is_pod< ::boost::tt_align_ns::a2> : public true_type{};
  204. template <> struct is_pod< ::boost::tt_align_ns::a4> : public true_type{};
  205. template <> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{};
  206. template <> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{};
  207. //#endif
  208. template <std::size_t N> struct type_with_alignment
  209. {
  210. // We should never get to here, but if we do use the maximally
  211. // aligned type:
  212. // BOOST_STATIC_ASSERT(0);
  213. typedef tt_align_ns::a16 type;
  214. };
  215. template <> struct type_with_alignment<1>{ typedef char type; };
  216. template <> struct type_with_alignment<2>{ typedef tt_align_ns::a2 type; };
  217. template <> struct type_with_alignment<4>{ typedef tt_align_ns::a4 type; };
  218. template <> struct type_with_alignment<8>{ typedef tt_align_ns::a8 type; };
  219. template <> struct type_with_alignment<16>{ typedef tt_align_ns::a16 type; };
  220. #endif
  221. } // namespace boost
  222. #ifdef BOOST_MSVC
  223. # pragma warning(pop)
  224. #endif
  225. #endif // BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED