type_with_alignment<> class template, docs and testcases

[SVN r13360]
This commit is contained in:
Douglas Gregor
2002-04-03 15:50:34 +00:00
parent cd1556d599
commit 47f23f8b4f
4 changed files with 173 additions and 3 deletions

View File

@@ -16,8 +16,15 @@
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
#include <boost/type_traits/ice.hpp>
#endif
#include <boost/preprocessor/list/for_each_i.hpp>
#include <boost/preprocessor/tuple/to_list.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/type_traits/transform_traits.hpp>
#include <boost/static_assert.hpp>
namespace boost{
template <class T> struct alignment_of;
//
// get the alignment of some arbitrary type:
namespace detail{
@@ -76,9 +83,111 @@ struct alignment_of<const volatile void>
{ 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<typename Then, typename Else>
struct result
{
typedef Then type;
};
};
struct select_else
{
template<typename Then, typename Else>
struct result
{
typedef Else type;
};
};
template<bool Condition>
struct ct_if_selector
{
typedef select_then type;
};
template<>
struct ct_if_selector<false>
{
typedef select_else type;
};
template<bool Condition, typename Then, typename Else>
struct ct_if
{
typedef typename ct_if_selector<Condition>::type select;
typedef typename select::template result<Then,Else>::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<T>::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 <std::size_t target>
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 <int Align>
class type_with_alignment
{
typedef detail::lower_alignment<Align> t1;
BOOST_STATIC_CONSTANT(bool, t1_aligned =
(alignment_of<t1>::value >= Align)
& (alignment_of<t1>::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<align_t>::value);
BOOST_STATIC_ASSERT(found >= Align);
BOOST_STATIC_ASSERT(found % Align == 0);
public:
typedef align_t type;
};
} // namespace boost
#endif // ALIGNMENT_TYPE_TRAITS_HPP

View File

@@ -197,6 +197,28 @@ struct test_align<T&>
#define align_test(T) test_align<T>::do_it()
template<class T>
struct test_type_with_align
{
static void do_it()
{
typedef typename boost::type_with_alignment<
boost::alignment_of<T>::value>::type
align_t;
int align = boost::alignment_of<T>::value;
int new_align = boost::alignment_of<align_t>::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<T>::do_it()
//
// the following code allows us to test that a particular
// template functions correctly when instanciated inside another template

View File

@@ -31,6 +31,7 @@ first. </p>
<a href="#properties">Type Properties</a>
<a href="#relationships">Relationships Between Types</a>
<a href="#transformations">Transformations Between Types</a>
<a href="#synthesized">Synthesizing Types</a>
<a href="#compiler">Compiler Support Information</a>
<a href="#headers">Type traits headers</a>
<a href="#example">Example Code</a></pre>
@@ -777,6 +778,39 @@ built-in type, but for they own types too:</p>
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to
nothing on those compilers that do support partial specialization.</p>
<h2><a name="synthesized"></a>Synthesizing Types</h2>
<p> The following template synthesizes a type with the desired properties.
<table border="0" cellpadding="7" cellspacing="1" width="100%">
<tr>
<td valign="top" width="5%">&nbsp;</td>
<td valign="top" width="23%" bgcolor="#008080"><p
align="center">Expression</p>
</td>
<td valign="top" width="28%" bgcolor="#008080"><p
align="center">Description</p>
</td>
<td valign="top" width="13%" bgcolor="#008080"><p
align="center">Reference</p>
</td>
<td valign="top" width="25%" bgcolor="#008080"><p
align="center">Compiler requirements</p>
</td>
<td valign="top" width="5%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="5%">&nbsp;</td>
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::type_with_alignment&lt;Align&gt;::type</code></td>
<td valign="top" width="28%" bgcolor="#C0C0C0">Attempts to find a
built-in or POD type with an alignment that is a multiple of Align.
</td>
<td valign="top" width="13%" bgcolor="#C0C0C0"></td>
<td width="25%" bgcolor="#C0C0C0"><p align="center"></p>
</td>
<td valign="top" width="5%">&nbsp;</td>
</tr>
</table>
<h2><a name="compiler"></a>Compiler Support Information</h2>
<p>The legends used in the tables above have the following

View File

@@ -36,6 +36,11 @@ int cpp_main(int argc, char* argv[])
align_test(VD);
value_test(0, ::boost::alignment_of<void>::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);
}