|
Boost-Commit : |
From: john_at_[hidden]
Date: 2008-04-01 12:48:58
Author: johnmaddock
Date: 2008-04-01 12:48:58 EDT (Tue, 01 Apr 2008)
New Revision: 43984
URL: http://svn.boost.org/trac/boost/changeset/43984
Log:
Updated and strengthened type_with_alignment tests and fixed msvc issue that prevented a type_with_alignment (or any type containing it such as Boost.Optional) from being passed by value. See http://article.gmane.org/gmane.comp.lib.boost.devel/173011 for motivating test case.
Text files modified:
trunk/boost/type_traits/type_with_alignment.hpp | 101 +++++++++++++-
trunk/libs/type_traits/test/type_with_alignment_test.cpp | 263 ++++++++-------------------------------
2 files changed, 146 insertions(+), 218 deletions(-)
Modified: trunk/boost/type_traits/type_with_alignment.hpp
==============================================================================
--- trunk/boost/type_traits/type_with_alignment.hpp (original)
+++ trunk/boost/type_traits/type_with_alignment.hpp 2008-04-01 12:48:58 EDT (Tue, 01 Apr 2008)
@@ -189,8 +189,10 @@
// This alignment method originally due to Brian Parker, implemented by David
// Abrahams, and then ported here by Doug Gregor.
+namespace detail{
+
template <std::size_t Align>
-class type_with_alignment
+class type_with_alignment_imp
{
typedef ::boost::detail::lower_alignment<Align> t1;
typedef typename mpl::if_c<
@@ -208,6 +210,13 @@
typedef align_t type;
};
+}
+
+template <std::size_t Align>
+class type_with_alignment : public detail::type_with_alignment_imp<Align>
+{
+};
+
#if defined(__GNUC__)
namespace align {
struct __attribute__((__aligned__(2))) a2 {};
@@ -233,19 +242,89 @@
}
#endif
#if defined(BOOST_MSVC) || (defined(BOOST_INTEL) && defined(_MSC_VER))
+//
+// MSVC supports types which have alignments greater than the normal
+// maximum: these are used for example in the types __m64 and __m128
+// to provide types with alignment requirements which match the SSE
+// registers. Therefore we extend type_with_alignment<> to support
+// such types, however, we have to be careful to use a builtin type
+// whenever possible otherwise we break previously working code:
+// see http://article.gmane.org/gmane.comp.lib.boost.devel/173011
+// for an example and test case. Thus types like a8 below will
+// be used *only* if the existing implementation can't provide a type
+// with suitable alignment. This does mean however, that type_with_alignment<>
+// may return a type which cannot be passed through a function call
+// by value (and neither can any type containing such a type like
+// Boost.Optional). However, this only happens when we have no choice
+// in the matter because no other "ordinary" type is available.
+//
namespace align {
-struct __declspec(align(8)) a8 { char m[8]; };
-struct __declspec(align(16)) a16 { char m[16]; };
-struct __declspec(align(32)) a32 { char m[32]; };
-struct __declspec(align(64)) a64 { char m[64]; };
-struct __declspec(align(128)) a128 { char m[128]; };
+struct __declspec(align(8)) a8 {
+ char m[8];
+ typedef a8 type;
+};
+struct __declspec(align(16)) a16 {
+ char m[16];
+ typedef a16 type;
+};
+struct __declspec(align(32)) a32 {
+ char m[32];
+ typedef a32 type;
+};
+struct __declspec(align(64)) a64
+{
+ char m[64];
+ typedef a64 type;
+};
+struct __declspec(align(128)) a128 {
+ char m[128];
+ typedef a128 type;
+};
}
-template<> class type_with_alignment<8> { public: typedef align::a8 type; };
-template<> class type_with_alignment<16> { public: typedef align::a16 type; };
-template<> class type_with_alignment<32> { public: typedef align::a32 type; };
-template<> class type_with_alignment<64> { public: typedef align::a64 type; };
-template<> class type_with_alignment<128> { public: typedef align::a128 type; };
+template<> class type_with_alignment<8>
+{
+ typedef mpl::if_c<
+ ::boost::alignment_of<detail::max_align>::value < 8,
+ align::a8,
+ detail::type_with_alignment_imp<8> >::type t1;
+public:
+ typedef t1::type type;
+};
+template<> class type_with_alignment<16>
+{
+ typedef mpl::if_c<
+ ::boost::alignment_of<detail::max_align>::value < 16,
+ align::a16,
+ detail::type_with_alignment_imp<16> >::type t1;
+public:
+ typedef t1::type type;
+};
+template<> class type_with_alignment<32>
+{
+ typedef mpl::if_c<
+ ::boost::alignment_of<detail::max_align>::value < 32,
+ align::a32,
+ detail::type_with_alignment_imp<32> >::type t1;
+public:
+ typedef t1::type type;
+};
+template<> class type_with_alignment<64> {
+ typedef mpl::if_c<
+ ::boost::alignment_of<detail::max_align>::value < 64,
+ align::a64,
+ detail::type_with_alignment_imp<64> >::type t1;
+public:
+ typedef t1::type type;
+};
+template<> class type_with_alignment<128> {
+ typedef mpl::if_c<
+ ::boost::alignment_of<detail::max_align>::value < 128,
+ align::a128,
+ detail::type_with_alignment_imp<128> >::type t1;
+public:
+ typedef t1::type type;
+};
namespace detail {
BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::align::a8,true)
Modified: trunk/libs/type_traits/test/type_with_alignment_test.cpp
==============================================================================
--- trunk/libs/type_traits/test/type_with_alignment_test.cpp (original)
+++ trunk/libs/type_traits/test/type_with_alignment_test.cpp 2008-04-01 12:48:58 EDT (Tue, 01 Apr 2008)
@@ -25,227 +25,76 @@
struct __declspec(align(128)) a128 { char m[128]; };
#endif
+void check_call2(...){}
+
+template <class T>
+void check_call(const T& v)
+{
+ check_call2(v);
+}
+
+#define TYPE_WITH_ALIGNMENT_TEST(T)\
+{\
+BOOST_CHECK(::tt::alignment_of<\
+ ::tt::type_with_alignment<\
+ ::tt::alignment_of< T >::value\
+ >::type\
+ >::value == ::boost::alignment_of< T >::value);\
+BOOST_CHECK(::tt::is_pod<\
+ ::tt::type_with_alignment<\
+ ::tt::alignment_of< T >::value>::type\
+ >::value);\
+}
+#define TYPE_WITH_ALIGNMENT_TEST_EX(T)\
+ TYPE_WITH_ALIGNMENT_TEST(T)\
+{\
+ ::tt::type_with_alignment<\
+ ::tt::alignment_of< T >::value\
+ >::type val;\
+ check_call(val);\
+}
+
+
TT_TEST_BEGIN(type_with_alignment)
BOOST_MESSAGE(typeid(::tt::type_with_alignment<
::tt::alignment_of<char>::value
>::type).name());
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<char>::value
- >::type
- >::value == ::boost::alignment_of<char>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<short>::value
- >::type
- >::value == ::boost::alignment_of<short>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int>::value
- >::type
- >::value == ::boost::alignment_of<int>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<long>::value
- >::type
- >::value == ::boost::alignment_of<long>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<float>::value
- >::type
- >::value == ::boost::alignment_of<float>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<double>::value
- >::type
- >::value == ::boost::alignment_of<double>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<long double>::value
- >::type
- >::value == ::boost::alignment_of<long double>::value);
+TYPE_WITH_ALIGNMENT_TEST_EX(char)
+TYPE_WITH_ALIGNMENT_TEST_EX(short)
+TYPE_WITH_ALIGNMENT_TEST_EX(int)
+TYPE_WITH_ALIGNMENT_TEST_EX(long)
+TYPE_WITH_ALIGNMENT_TEST_EX(float)
+TYPE_WITH_ALIGNMENT_TEST_EX(double)
+TYPE_WITH_ALIGNMENT_TEST_EX(long double)
+
#ifdef BOOST_HAS_LONG_LONG
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of< ::boost::long_long_type>::value
- >::type
- >::value == ::boost::alignment_of< ::boost::long_long_type>::value);
+TYPE_WITH_ALIGNMENT_TEST_EX(::boost::long_long_type)
#endif
#ifdef BOOST_HAS_MS_INT64
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<__int64>::value
- >::type
- >::value == ::boost::alignment_of<__int64>::value);
+TYPE_WITH_ALIGNMENT_TEST_EX(__int64)
#endif
+TYPE_WITH_ALIGNMENT_TEST_EX(int[4])
+TYPE_WITH_ALIGNMENT_TEST_EX(int(*)(int))
+TYPE_WITH_ALIGNMENT_TEST_EX(int*)
+TYPE_WITH_ALIGNMENT_TEST_EX(VB)
+TYPE_WITH_ALIGNMENT_TEST_EX(VD)
+TYPE_WITH_ALIGNMENT_TEST_EX(enum_UDT)
+TYPE_WITH_ALIGNMENT_TEST_EX(mf2)
+TYPE_WITH_ALIGNMENT_TEST_EX(POD_UDT)
+TYPE_WITH_ALIGNMENT_TEST_EX(empty_UDT)
+TYPE_WITH_ALIGNMENT_TEST_EX(union_UDT)
+
#if defined(BOOST_MSVC) || (defined(BOOST_INTEL) && defined(_MSC_VER))
#if _MSC_VER >= 1400
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<__m128>::value
- >::type
- >::value == ::boost::alignment_of<__m128>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<__m64>::value
- >::type
- >::value == ::boost::alignment_of<__m64>::value);
-#endif
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<a8>::value
- >::type
- >::value == ::boost::alignment_of<a8>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<a16>::value
- >::type
- >::value == ::boost::alignment_of<a16>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<a32>::value
- >::type
- >::value == ::boost::alignment_of<a32>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<a64>::value
- >::type
- >::value == ::boost::alignment_of<a64>::value);
+TYPE_WITH_ALIGNMENT_TEST(__m128)
+TYPE_WITH_ALIGNMENT_TEST(__m64)
#endif
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int[4]>::value
- >::type
- >::value == ::boost::alignment_of<int[4]>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int(*)(int)>::value
- >::type
- >::value == ::boost::alignment_of<int(*)(int)>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int*>::value
- >::type
- >::value == ::boost::alignment_of<int*>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<VB>::value
- >::type
- >::value == ::boost::alignment_of<VB>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<VD>::value
- >::type
- >::value == ::boost::alignment_of<VD>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<enum_UDT>::value
- >::type
- >::value == ::boost::alignment_of<enum_UDT>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<mf2>::value
- >::type
- >::value == ::boost::alignment_of<mf2>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<POD_UDT>::value
- >::type
- >::value == ::boost::alignment_of<POD_UDT>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<empty_UDT>::value
- >::type
- >::value == ::boost::alignment_of<empty_UDT>::value);
-BOOST_CHECK(::tt::alignment_of<
- ::tt::type_with_alignment<
- ::tt::alignment_of<union_UDT>::value
- >::type
- >::value == ::boost::alignment_of<union_UDT>::value);
-
-// check that the type produced are POD's:
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<char>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<short>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<long>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<float>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<double>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<long double>::value>::type
- >::value);
-#ifdef BOOST_HAS_LONG_LONG
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of< ::boost::long_long_type>::value>::type
- >::value);
-#endif
-#ifdef BOOST_HAS_MS_INT64
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<__int64>::value>::type
- >::value);
+TYPE_WITH_ALIGNMENT_TEST(a8)
+TYPE_WITH_ALIGNMENT_TEST(a16)
+TYPE_WITH_ALIGNMENT_TEST(a32)
#endif
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int[4]>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int(*)(int)>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<int*>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<VB>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<VD>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<enum_UDT>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<mf2>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<POD_UDT>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<empty_UDT>::value>::type
- >::value);
-BOOST_CHECK(::tt::is_pod<
- ::tt::type_with_alignment<
- ::tt::alignment_of<union_UDT>::value>::type
- >::value);
TT_TEST_END
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk