Home | History | Annotate | Download | only in type_traits
      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