forked from boostorg/type_traits
type_with_alignment<> class template, docs and testcases
[SVN r13360]
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
34
index.htm
34
index.htm
@@ -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%"> </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%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="5%"> </td>
|
||||
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::type_with_alignment<Align>::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%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="compiler"></a>Compiler Support Information</h2>
|
||||
|
||||
<p>The legends used in the tables above have the following
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user