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>::type |
+ Attempts 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);
}