From 47f23f8b4f875131bf834214214134a388044264 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 3 Apr 2002 15:50:34 +0000 Subject: [PATCH] type_with_alignment<> class template, docs and testcases [SVN r13360] --- .../boost/type_traits/alignment_traits.hpp | 115 +++++++++++++++++- .../boost/type_traits/type_traits_test.hpp | 22 ++++ index.htm | 34 ++++++ tests/alignment_test.cpp | 5 + 4 files changed, 173 insertions(+), 3 deletions(-) diff --git a/include/boost/type_traits/alignment_traits.hpp b/include/boost/type_traits/alignment_traits.hpp index c71565a..a10ca23 100644 --- a/include/boost/type_traits/alignment_traits.hpp +++ b/include/boost/type_traits/alignment_traits.hpp @@ -16,8 +16,15 @@ #ifndef BOOST_ICE_TYPE_TRAITS_HPP #include #endif +#include +#include +#include +#include +#include namespace boost{ +template struct alignment_of; + // // get the alignment of some arbitrary type: namespace detail{ @@ -76,9 +83,111 @@ 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; + + BOOST_STATIC_CONSTANT(bool, t1_aligned = + (alignment_of::value >= Align) + & (alignment_of::value % Align == 0)); + + typedef typename detail::ct_if< + 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 #endif // ALIGNMENT_TYPE_TRAITS_HPP - - - diff --git a/include/boost/type_traits/type_traits_test.hpp b/include/boost/type_traits/type_traits_test.hpp index eae5bb2..09c861f 100644 --- a/include/boost/type_traits/type_traits_test.hpp +++ b/include/boost/type_traits/type_traits_test.hpp @@ -197,6 +197,28 @@ struct test_align #define align_test(T) test_align::do_it() +template +struct test_type_with_align +{ + static void do_it() + { + typedef typename boost::type_with_alignment< + boost::alignment_of::value>::type + align_t; + int align = boost::alignment_of::value; + int new_align = boost::alignment_of::value; + ++test_count; + if (new_align % align != 0) { + ++failures; + std::cerr << "checking for an object with same alignment as " + << typeid(T).name() << "...failed" << std::endl; + std::cerr << "\tfound: " << typeid(align_t).name() << std::endl; + } + } +}; + +#define type_with_align_test(T) test_type_with_align::do_it() + // // the following code allows us to test that a particular // template functions correctly when instanciated inside another template diff --git a/index.htm b/index.htm index 8b2ffe6..4965884 100644 --- a/index.htm +++ b/index.htm @@ -31,6 +31,7 @@ first.

Type Properties Relationships Between Types Transformations Between Types +Synthesizing Types Compiler Support Information Type traits headers Example Code @@ -777,6 +778,39 @@ built-in type, but for they own types too:

BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to nothing on those compilers that do support partial specialization.

+

Synthesizing Types

+

The following template synthesizes a type with the desired properties. + + + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler requirements

+
 
 ::boost::type_with_alignment<Align>::typeAttempts to find a + built-in or POD type with an alignment that is a multiple of Align. +

+
 
+

Compiler Support Information

The legends used in the tables above have the following diff --git a/tests/alignment_test.cpp b/tests/alignment_test.cpp index a70ecd6..70cc82f 100644 --- a/tests/alignment_test.cpp +++ b/tests/alignment_test.cpp @@ -36,6 +36,11 @@ int cpp_main(int argc, char* argv[]) align_test(VD); value_test(0, ::boost::alignment_of::value); + type_with_align_test(int); + type_with_align_test(int(*)(int)); + type_with_align_test(VB); + type_with_align_test(VD); + type_with_align_test(char[13]); return check_result(argc, argv); }