// (C) Copyright John Maddock 2000. // Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // // defines alignment_of: #ifndef ALIGNMENT_TYPE_TRAITS_HPP #define ALIGNMENT_TYPE_TRAITS_HPP #include #include #ifndef BOOST_ICE_TYPE_TRAITS_HPP #include #endif #include #include #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable: 4121) // alignment is sensitive to packing #endif namespace boost{ template struct alignment_of; // // get the alignment of some arbitrary type: namespace detail{ template struct alignment_of_hack { char c; T t; alignment_of_hack(); }; template struct alignment_logic { BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S); }; template struct ctv_wrap : Value {}; } // namespace detail template struct alignment_of { BOOST_STATIC_CONSTANT(std::size_t, value = (::boost::detail::alignment_logic< sizeof(detail::alignment_of_hack) - sizeof(T), sizeof(T) >::value)); }; // // references have to be treated specially, assume // that a reference is just a special pointer: #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct alignment_of { public: BOOST_STATIC_CONSTANT(std::size_t, value = ::boost::alignment_of::value); }; #endif // // void has to be treated specially: template <> struct alignment_of { BOOST_STATIC_CONSTANT(std::size_t, value = 0); }; #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template <> struct alignment_of { BOOST_STATIC_CONSTANT(std::size_t, value = 0); }; template <> struct alignment_of { BOOST_STATIC_CONSTANT(std::size_t, value = 0); }; template <> struct alignment_of { BOOST_STATIC_CONSTANT(std::size_t, value = 0); }; #endif namespace detail { class alignment_dummy; typedef void (*function_ptr)(); typedef int (alignment_dummy::*member_ptr); typedef int (alignment_dummy::*member_function_ptr)(); /* * The ct_if implementation is temporary code. It will be replaced with MPL * in the future... */ struct select_then { template struct result { typedef Then type; }; }; struct select_else { template struct result { typedef Else type; }; }; template struct ct_if_selector { typedef select_then type; }; template<> struct ct_if_selector { typedef select_else type; }; template struct ct_if { typedef typename ct_if_selector::type select; typedef typename select::template result::type type; }; #define BOOST_TT_ALIGNMENT_TYPES BOOST_PP_TUPLE_TO_LIST( \ 11, ( \ char, short, int, long, float, double, long double \ , void*, function_ptr, member_ptr, member_function_ptr)) #define BOOST_TT_CHOOSE_LOWER_ALIGNMENT(R,P,I,T) \ typename ct_if< \ alignment_of::value <= target, T, char>::type BOOST_PP_CAT(t,I); #define BOOST_TT_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I); template union lower_alignment { BOOST_PP_LIST_FOR_EACH_I( BOOST_TT_CHOOSE_LOWER_ALIGNMENT , ignored, BOOST_TT_ALIGNMENT_TYPES) }; union max_align { BOOST_PP_LIST_FOR_EACH_I( BOOST_TT_CHOOSE_T , ignored, BOOST_TT_ALIGNMENT_TYPES) }; #undef BOOST_TT_ALIGNMENT_TYPES #undef BOOST_TT_CHOOSE_LOWER_ALIGNMENT #undef BOOST_TT_CHOOSE_T } // This alignment method originally due to Brian Parker, implemented by David // Abrahams, and then ported here by Doug Gregor. template class type_with_alignment { typedef detail::lower_alignment t1; typedef type_with_alignment this_type ; BOOST_STATIC_CONSTANT(bool, t1_aligned = (alignment_of::value >= Align) & (alignment_of::value % Align == 0)); typedef typename detail::ct_if< ::boost::detail::ctv_wrap::t1_aligned , t1 , detail::max_align >::type align_t; BOOST_STATIC_CONSTANT(std::size_t, found = alignment_of::value); BOOST_STATIC_ASSERT(found >= Align); BOOST_STATIC_ASSERT(found % Align == 0); public: typedef align_t type; }; } // namespace boost #ifdef BOOST_MSVC # pragma warning(pop) #endif #endif // ALIGNMENT_TYPE_TRAITS_HPP