1 2 // (C) Copyright John Maddock 2000. 3 // Use, modification and distribution are subject to the Boost Software License, 4 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt). 6 // 7 // See http://www.boost.org/libs/type_traits for most recent version including documentation. 8 9 #ifndef BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED 10 #define BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED 11 12 #include <boost/config.hpp> 13 #include <cstddef> 14 15 #include <boost/type_traits/intrinsics.hpp> 16 // should be the last #include 17 #include <boost/type_traits/detail/size_t_trait_def.hpp> 18 19 #ifdef BOOST_MSVC 20 # pragma warning(push) 21 # pragma warning(disable: 4121 4512) // alignment is sensitive to packing 22 #endif 23 #if defined(__BORLANDC__) && (__BORLANDC__ < 0x600) 24 #pragma option push -Vx- -Ve- 25 #endif 26 27 namespace boost { 28 29 template <typename T> struct alignment_of; 30 31 // get the alignment of some arbitrary type: 32 namespace detail { 33 34 #ifdef BOOST_MSVC 35 #pragma warning(push) 36 #pragma warning(disable:4324) // structure was padded due to __declspec(align()) 37 #endif 38 template <typename T> 39 struct alignment_of_hack 40 { 41 char c; 42 T t; 43 alignment_of_hack(); 44 }; 45 #ifdef BOOST_MSVC 46 #pragma warning(pop) 47 #endif 48 49 template <unsigned A, unsigned S> 50 struct alignment_logic 51 { 52 BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S); 53 }; 54 55 56 template< typename T > 57 struct alignment_of_impl 58 { 59 #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) 60 // 61 // With MSVC both the native __alignof operator 62 // and our own logic gets things wrong from time to time :-( 63 // Using a combination of the two seems to make the most of a bad job: 64 // 65 BOOST_STATIC_CONSTANT(std::size_t, value = 66 (::boost::detail::alignment_logic< 67 sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T), 68 __alignof(T) 69 >::value)); 70 #elif !defined(BOOST_ALIGNMENT_OF) 71 BOOST_STATIC_CONSTANT(std::size_t, value = 72 (::boost::detail::alignment_logic< 73 sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T), 74 sizeof(T) 75 >::value)); 76 #else 77 // 78 // We put this here, rather than in the definition of 79 // alignment_of below, because MSVC's __alignof doesn't 80 // always work in that context for some unexplained reason. 81 // (See type_with_alignment tests for test cases). 82 // 83 BOOST_STATIC_CONSTANT(std::size_t, value = BOOST_ALIGNMENT_OF(T)); 84 #endif 85 }; 86 87 } // namespace detail 88 89 BOOST_TT_AUX_SIZE_T_TRAIT_DEF1(alignment_of,T,::boost::detail::alignment_of_impl<T>::value) 90 91 // references have to be treated specially, assume 92 // that a reference is just a special pointer: 93 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 94 template <typename T> 95 struct alignment_of<T&> 96 : public alignment_of<T*> 97 { 98 }; 99 #endif 100 #ifdef __BORLANDC__ 101 // long double gives an incorrect value of 10 (!) 102 // unless we do this... 103 struct long_double_wrapper{ long double ld; }; 104 template<> struct alignment_of<long double> 105 : public alignment_of<long_double_wrapper>{}; 106 #endif 107 108 // void has to be treated specially: 109 BOOST_TT_AUX_SIZE_T_TRAIT_SPEC1(alignment_of,void,0) 110 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS 111 BOOST_TT_AUX_SIZE_T_TRAIT_SPEC1(alignment_of,void const,0) 112 BOOST_TT_AUX_SIZE_T_TRAIT_SPEC1(alignment_of,void volatile,0) 113 BOOST_TT_AUX_SIZE_T_TRAIT_SPEC1(alignment_of,void const volatile,0) 114 #endif 115 116 } // namespace boost 117 118 #if defined(__BORLANDC__) && (__BORLANDC__ < 0x600) 119 #pragma option pop 120 #endif 121 #ifdef BOOST_MSVC 122 # pragma warning(pop) 123 #endif 124 125 #include <boost/type_traits/detail/size_t_trait_undef.hpp> 126 127 #endif // BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED 128 129