Author: vitek
Date: Thu Jun 19 15:52:34 2008
New Revision: 669735
URL: http://svn.apache.org/viewvc?rev=669735&view=rev
Log:
2008-06-19 Travis Vitek <[EMAIL PROTECTED]>
STDCXX-926
* include/type_traits: Update comments describing each trait. Use
correct type for the underlying integral_constant used by traits
alignment_of, rank, extent, is_base_of and is_convertible. Enable
aligned_union. Add defaulted alignment for aligned_storage.
* include/rw/_meta_other.h: Implement __rw_aligned_storage. Add
support for defaulted alignment. Update __rw_aligned_union to
use __rw_aligned_storage to get an aligned block.
* tests/utilities/20.meta.trans.other.cpp (test_trait): Correct
assertion message to display correct string.
(test_aligned_storage): Add testing for aligned_storage.
(test_aligned_union): Add testing for aligned_union.
Modified:
stdcxx/branches/4.3.x/include/rw/_meta_other.h
stdcxx/branches/4.3.x/include/type_traits
stdcxx/branches/4.3.x/tests/utilities/20.meta.trans.other.cpp
Modified: stdcxx/branches/4.3.x/include/rw/_meta_other.h
URL:
http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/rw/_meta_other.h?rev=669735&r1=669734&r2=669735&view=diff
==============================================================================
--- stdcxx/branches/4.3.x/include/rw/_meta_other.h (original)
+++ stdcxx/branches/4.3.x/include/rw/_meta_other.h Thu Jun 19 15:52:34 2008
@@ -37,50 +37,318 @@
_RWSTD_NAMESPACE (__rw) {
-template <_RWSTD_SIZE_T _Len, _RWSTD_SIZE_T _Align = 4>
+/**
+ * Metaprogramming conditional primitive that provides a member typedef
+ * _C_type that is _TypeT if _Select is true, otherwise is _TypeU.
+ *
+ * The primary template is used when _Select is true.
+ */
+template <bool _Select, class _TypeT, class _TypeU>
+struct __rw_conditional
+{
+ typedef _TypeT type;
+};
+
+/**
+ * Metaprogramming conditional primitive that provides a member typedef
+ * type is _TypeT if _Select is true, otherwise is _TypeU.
+ *
+ * This specialization if used when _Select is false.
+ */
+template <class _TypeT, class _TypeU>
+struct __rw_conditional<false, _TypeT, _TypeU>
+{
+ typedef _TypeU type;
+};
+
+#define _RWSTD_CONDITIONAL(C,T,U) _RW::__rw_conditional<C,T,U>::type
+
+
+/**
+ * Helper for __rw_aligned_storage. Specializations define a member type
+ * that is aligned on power of two boundaries.
+ */
+template <size_t _Align>
+struct __rw_aligned_storage_impl;
+
+#define _RWSTD_ALIGNED_STORAGE_SPEC(N) \
+ template <> struct __rw_aligned_storage_impl<N> { \
+ typedef _RWSTD_TT_ALIGNED_POD(N) _C_type; \
+}
+
+_RWSTD_ALIGNED_STORAGE_SPEC(1);
+_RWSTD_ALIGNED_STORAGE_SPEC(2);
+_RWSTD_ALIGNED_STORAGE_SPEC(4);
+_RWSTD_ALIGNED_STORAGE_SPEC(8);
+_RWSTD_ALIGNED_STORAGE_SPEC(16);
+_RWSTD_ALIGNED_STORAGE_SPEC(32);
+_RWSTD_ALIGNED_STORAGE_SPEC(64);
+_RWSTD_ALIGNED_STORAGE_SPEC(128);
+_RWSTD_ALIGNED_STORAGE_SPEC(256);
+_RWSTD_ALIGNED_STORAGE_SPEC(512);
+_RWSTD_ALIGNED_STORAGE_SPEC(1024);
+_RWSTD_ALIGNED_STORAGE_SPEC(2048);
+_RWSTD_ALIGNED_STORAGE_SPEC(4096);
+_RWSTD_ALIGNED_STORAGE_SPEC(8192);
+
+/**
+ * Helper for __rw_default_alignment. The member value will evaluate
+ * to the nearest power of two that is a valid alignment value that
+ * is less than or equal to _Size.
+ *
+ * @tparam _Size The size of the object to align.
+ * @tparam _N The power of two value being tested.
+ * @tparam _Done Termination condition for recursion. Do not use.
+ */
+template <size_t _Size, size_t _N,
+ bool _Done = (_RWSTD_TT_MAX_ALIGNMENT <= _N * 2)
+ || (_Size < _N * 2)>
+struct __rw_default_alignment_impl
+{
+ enum { value = __rw_default_alignment_impl<_Size, _N * 2>::value };
+};
+
+/**
+ * Helper for __rw_default_alignment. The member value will evaluate
+ * to the nearest power of two that is less than or equal to _Size.
+ * This specialization is used to terminate recursion. It is only used
+ * when when _Done in the primary template evaluates is true.
+ *
+ * @tparam _Size The size of the object to align.
+ * @tparam _N The power of two value being tested.
+ */
+template <size_t _Size, size_t _N>
+struct __rw_default_alignment_impl<_Size, _N, true>
+{
+ enum { value = _N };
+};
+
+/**
+ * Helper for __rw_aligned_storage. The value member shall be the most
+ * most stringent alignment requirement for any C++ object whose size
+ * is no greater than _Size. This implementation will set value to be
+ * the nearest power of two value that is less than or equal to _Size.
+ *
+ * @tparam _Size Size of the object to calculate the alignment for.
+ */
+template <size_t _Size>
+struct __rw_default_alignment
+{
+ enum { value = __rw_default_alignment_impl<_Size, 1>::value };
+};
+
+
+/**
+ *
+ */
+template <size_t _Size, size_t _Align = __rw_default_alignment<_Size>::value>
struct __rw_aligned_storage
{
+ _RWSTD_STATIC_ASSERT (_Size != 0,
+ "Unsupported size");
+
+ _RWSTD_STATIC_ASSERT ((_Align & (_Align - 1)) == 0 || _Align == 0,
+ "Unsupported alignment"); // expect power of 2
+
+ _RWSTD_STATIC_ASSERT (_Align <= _RWSTD_TT_MAX_ALIGNMENT,
+ "Unsupported alignment"); // expect less than max
+
typedef union {
- unsigned char __data [_Len];
- // not implemented
+ unsigned char __size [_Size];
+
+ typename
+ __rw_aligned_storage_impl<_Align>::_C_type __align;
} type;
};
#ifndef _RWSTD_NO_VARIADIC_TEMPLATES
-template <_RWSTD_SIZE_T _Len, class... _Types>
-struct __rw_aligned_union_impl;
+/**
+ * Helper for __rw_aligned_union. Provides a typedef type that
+ * is the largest type in the sequence of provided types.
+ */
+template <class... _Types>
+struct __rw_biggest;
-template <_RWSTD_SIZE_T _Len, class _TypeT, class... _Types>
-struct __rw_aligned_union_impl<_Len, _TypeT, _Types...>
+template <class _TypeT, class... _Types>
+struct __rw_biggest
{
- typedef union {
- unsigned char __pad [_Len ? _Len : 1];
- _TypeT __type1;
- typename __rw_aligned_union_impl<_Len, _Types...>::_C_type __align;
- } _C_type;
+ typedef typename
+ __rw_biggest<_Types...>::type _TypeU;
+
+ typedef typename
+ __rw_conditional< sizeof _TypeT
+ < sizeof _TypeU
+ ? _TypeU
+ : _TypeT>::type type;
};
-template <_RWSTD_SIZE_T _Len, class _TypeT>
-struct __rw_aligned_union_impl<_Len, _TypeT>
+template <class _TypeT>
+struct __rw_biggest<_TypeT>
{
- typedef union {
- unsigned char __pad [_Len ? _Len : 1];
- } _C_type;
+ typedef _TypeT type;
};
-template <_RWSTD_SIZE_T _Len, class... Types>
+/**
+ * Helper for __rw_aligned_union. Provides a typedef type that
+ * is the type with the strictest alignment requirement in the
+ * sequence of provided types.
+ */
+template <class... _Types>
+struct __rw_strictest;
+
+template <class _TypeT, class... _Types>
+struct __rw_strictest
+{
+ typedef typename
+ __rw_strictest<_Types...>::type _TypeU;
+
+ typedef typename
+ __rw_conditional< __rw_alignment_of<_TypeT>::value
+ < __rw_alignment_of<_TypeU>::value
+ ? _TypeU
+ : _TypeT>::type type;
+};
+
+template <class _TypeT>
+struct __rw_strictest<_TypeT>
+{
+ typedef _TypeT type;
+};
+
+template <_RWSTD_SIZE_T _Len, class _TypeT, class... _Types>
struct __rw_aligned_union
{
typedef typename
- __rw_aligned_union_impl<_Len, Types...>::_C_type type;
+ __rw_biggest<_TypeT, _Types...>::type _C_biggest;
+
+ typedef typename
+ __rw_strictest<_TypeT, _Types...>::type _C_strictest;
+
+ static const _RWSTD_SIZE_T _C_size_value =
+ sizeof (_C_biggest);
+
+ static const _RWSTD_SIZE_T alignment_value =
+ __rw_alignment_of<_C_strictest>::value;
+
+ typedef typename
+ __rw_aligned_storage<_Len < _C_size_value ? _C_size_value : _Len,
+ alignment_value>::_C_type type;
};
+#ifndef _RWSTD_NO_STATIC_CONST_MEMBER_DEFINITION
+
+template <_RWSTD_SIZE_T _Len, class... _Types>
+const _RWSTD_SIZE_T
+__rw_aligned_union<_Len, _Types...>::alignment_value;
+
+template <_RWSTD_SIZE_T _Len, class... _Types>
+const _RWSTD_SIZE_T
+__rw_aligned_union<_Len, _Types...>::_C_size_value;
+
+#endif // _RWSTD_NO_STATIC_CONST_MEMBER_DEFINITION
+
#else // _RWSTD_NO_VARIADIC_TEMPLATES
struct __rw_empty { };
+/**
+ * Helper for __rw_aligned_union. Provides a typedef type that
+ * is the largest type in the sequence of provided types.
+ */
+template <class _Type1 , class _Type2 = __rw_empty,
+ class _Type3 = __rw_empty, class _Type4 = __rw_empty,
+ class _Type5 = __rw_empty, class _Type6 = __rw_empty,
+ class _Type7 = __rw_empty, class _Type8 = __rw_empty>
+struct __rw_biggest
+{
+ typedef typename
+ __rw_conditional<( sizeof _Type1 < sizeof _Type2),
+ _Type2, _Type1>::type _Type12;
+
+ typedef typename
+ __rw_conditional<( sizeof _Type3 < sizeof _Type4),
+ _Type4, _Type3>::type _Type34;
+
+ typedef typename
+ __rw_conditional<( sizeof _Type5 < sizeof _Type6),
+ _Type6, _Type5>::type _Type56;
+
+ typedef typename
+ __rw_conditional<( sizeof _Type7 < sizeof _Type8),
+ _Type8, _Type7>::type _Type78;
+
+ typedef typename
+ __rw_conditional<( sizeof _Type12 < sizeof _Type34),
+ _Type34, _Type12>::type _Type1234;
+
+ typedef typename
+ __rw_conditional<( sizeof _Type56 < sizeof _Type78),
+ _Type78, _Type56>::type _Type5678;
+
+ typedef typename
+ __rw_conditional<( sizeof _Type1234 < sizeof _Type5678),
+ _Type5678, _Type1234>::type type;
+};
+
+/**
+ * Helper for __rw_aligned_union. Provides a typedef type that
+ * is the type with the strictest alignment requirement in the
+ * sequence of provided types.
+ */
+template <class _Type1 , class _Type2 = __rw_empty,
+ class _Type3 = __rw_empty, class _Type4 = __rw_empty,
+ class _Type5 = __rw_empty, class _Type6 = __rw_empty,
+ class _Type7 = __rw_empty, class _Type8 = __rw_empty>
+struct __rw_strictest
+{
+ // these enums necessary to avoid problems with VC8
+ enum {
+ _C_select12 = __rw_alignment_of<_Type1>::value
+ < __rw_alignment_of<_Type2>::value,
+ _C_select34 = __rw_alignment_of<_Type3>::value
+ < __rw_alignment_of<_Type4>::value,
+ _C_select56 = __rw_alignment_of<_Type5>::value
+ < __rw_alignment_of<_Type6>::value,
+ _C_select78 = __rw_alignment_of<_Type7>::value
+ < __rw_alignment_of<_Type8>::value
+ };
+
+ typedef typename
+ __rw_conditional<_C_select12, _Type2, _Type1>::type _Type12;
+
+ typedef typename
+ __rw_conditional<_C_select34, _Type4, _Type3>::type _Type34;
+
+ typedef typename
+ __rw_conditional<_C_select56, _Type6, _Type5>::type _Type56;
+
+ typedef typename
+ __rw_conditional<_C_select78, _Type8, _Type7>::type _Type78;
+
+ enum {
+ _C_select1234 = __rw_alignment_of<_Type12>::value
+ < __rw_alignment_of<_Type34>::value,
+ _C_select5678 = __rw_alignment_of<_Type56>::value
+ < __rw_alignment_of<_Type78>::value
+ };
+
+ typedef typename
+ __rw_conditional<_C_select1234, _Type34, _Type12>::type _Type1234;
+
+ typedef typename
+ __rw_conditional<_C_select5678, _Type78, _Type56>::type _Type5678;
+
+ enum {
+ _C_select = __rw_alignment_of<_Type1234>::value
+ < __rw_alignment_of<_Type5678>::value
+ };
+
+ typedef typename
+ __rw_conditional<_C_select, _Type5678, _Type1234>::type type;
+};
+
template <_RWSTD_SIZE_T _Len,
class _Type1 , class _Type2 = __rw_empty,
class _Type3 = __rw_empty, class _Type4 = __rw_empty,
@@ -88,21 +356,49 @@
class _Type7 = __rw_empty, class _Type8 = __rw_empty>
struct __rw_aligned_union
{
- typedef union {
- unsigned char __pad [_Len ? _Len : 1];
- _Type1 __object1;
- _Type2 __object2;
- _Type3 __object3;
- _Type4 __object4;
- _Type5 __object5;
- _Type6 __object6;
- _Type7 __object7;
- _Type8 __object8;
- } type;
+ typedef typename
+ __rw_biggest<_Type1, _Type2, _Type3, _Type4,
+ _Type5, _Type6, _Type7, _Type8>::type _C_biggest;
+
+ typedef typename
+ __rw_strictest<_Type1, _Type2, _Type3, _Type4,
+ _Type5, _Type6, _Type7, _Type8>::type _C_strictest;
+
+ static const _RWSTD_SIZE_T _C_size_value =
+ sizeof (_C_biggest);
+
+ static const _RWSTD_SIZE_T alignment_value =
+ __rw_alignment_of<_C_strictest>::value;
+
+ typedef typename
+ __rw_aligned_storage<_C_size_value < _Len ? _Len : _C_size_value,
+ alignment_value>::type type;
};
+#ifndef _RWSTD_NO_STATIC_CONST_MEMBER_DEFINITION
+
+template <_RWSTD_SIZE_T _Len,
+ class _Type1, class _Type2, class _Type3, class _Type4,
+ class _Type5, class _Type6, class _Type7, class _Type8>
+const _RWSTD_SIZE_T
+__rw_aligned_union<_Len,
+ _Type1, _Type2, _Type3, _Type4,
+ _Type5, _Type6, _Type7, _Type8>::alignment_value;
+
+template <_RWSTD_SIZE_T _Len,
+ class _Type1, class _Type2, class _Type3, class _Type4,
+ class _Type5, class _Type6, class _Type7, class _Type8>
+const _RWSTD_SIZE_T
+__rw_aligned_union<_Len,
+ _Type1, _Type2, _Type3, _Type4,
+ _Type5, _Type6, _Type7, _Type8>::_C_size_value;
+
+#endif // _RWSTD_NO_STATIC_CONST_MEMBER_DEFINITION
+
#endif // !_RWSTD_NO_VARIADIC_TEMPLATES
+
+
/**
* Conditional primitive that provides a member typedef type that is
* _TypeT if _Enable is true, otherwise there will be no such typedef.
@@ -160,33 +456,6 @@
/**
- * Metaprogramming conditional primitive that provides a member typedef
- * _C_type that is _TypeT if _Select is true, otherwise is _TypeU.
- *
- * The primary template is used when _Select is true.
- */
-template <bool _Select, class _TypeT, class _TypeU>
-struct __rw_conditional
-{
- typedef _TypeT type;
-};
-
-/**
- * Metaprogramming conditional primitive that provides a member typedef
- * type is _TypeT if _Select is true, otherwise is _TypeU.
- *
- * This specialization if used when _Select is false.
- */
-template <class _TypeT, class _TypeU>
-struct __rw_conditional<false, _TypeT, _TypeU>
-{
- typedef _TypeU type;
-};
-
-#define _RWSTD_CONDITIONAL(C,T,U) _RW::__rw_conditional<C,T,U>::type
-
-
-/**
* TransformationTrait that implements compile time array-to-pointer
* conversions and function-to-pointer conversions for the given type
* _TypeT.
Modified: stdcxx/branches/4.3.x/include/type_traits
URL:
http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/type_traits?rev=669735&r1=669734&r2=669735&view=diff
==============================================================================
--- stdcxx/branches/4.3.x/include/type_traits (original)
+++ stdcxx/branches/4.3.x/include/type_traits Thu Jun 19 15:52:34 2008
@@ -195,6 +195,9 @@
* The class template integral_constant and its associated typedefs
* true_type and false_type are used as base classes to define the
* interface for various type traits.
+ *
+ * @tparam _TypeT The type of the integral constant value.
+ * @tparam _Value The value of the integral constant.
*/
template <class _TypeT, _TypeT _Value>
struct integral_constant
@@ -241,7 +244,10 @@
/**
* @ingroup meta_unary_cat
*
- * \e UnaryTypeTrait to determine if _TypeT is void or a cv-qualified void.
+ * \e UnaryTypeTrait to determine if _TypeT is void or a cv-qualified
+ * void.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_void
@@ -253,11 +259,12 @@
* @ingroup meta_unary_cat
*
* \e UnaryTypeTrait to determine if _TypeT is an integral type.
+ * Types \c bool, \c char, \c wchar_t, and the signed and unsigned
+ * integer types are collectively called integral types. The signed
+ * and unsigned integer types include signed and unsigned versions
+ * of \c char, \c short, \c int, \c long and \c long \c long.
*
- * Types \c bool, \c char, \c wchar_t, and the signed and unsigned integer
- * types are collectively called integral types. The signed and unsigned
- * integer types include signed and unsigned versions of \c char, \c short,
- * \c int, \c long and \c long \c long.
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_integral
@@ -272,6 +279,8 @@
*
* Types \c float, \c double, \c long \c double, and cv-qualified versions
* of those types make up the set of floating point types.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_floating_point
@@ -282,7 +291,10 @@
/**
* @ingroup meta_unary_cat
*
- * \e UnaryTypeTrait to determine if _TypeT is an array type.
+ * \e UnaryTypeTrait to determine if _TypeT is an array type. Array types
+ * include both arrays of bounded and unbounded length.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_array
@@ -294,9 +306,10 @@
* @ingroup meta_unary_cat
*
* \e UnaryTypeTrait to determine if _TypeT is a pointer type.
- *
* Includes function pointers, but not pointers to non-static member
* functions.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_pointer
@@ -308,6 +321,8 @@
* @ingroup meta_unary_cat
*
* \e UnaryTypeTrait to determine if _TypeT is an lvalue reference type.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_lvalue_reference
@@ -319,6 +334,8 @@
* @ingroup meta_unary_cat
*
* \e UnaryTypeTrait to determine if _TypeT is an rvalue reference type.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_rvalue_reference
@@ -331,7 +348,9 @@
*
* \e UnaryTypeTrait to determine if _TypeT is a reference type.
*
- * Includes references to functions.
+ * @note References to functions are still references, not functions.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_reference
@@ -343,7 +362,9 @@
* @ingroup meta_unary_cat
*
* \e UnaryTypeTrait to determine if _TypeT is a pointer to non-static
- * member pointer.
+ * member.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_member_object_pointer
@@ -356,6 +377,8 @@
*
* \e UnaryTypeTrait to determine if _TypeT is a pointer to non-static
* member function.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_member_function_pointer
@@ -368,8 +391,10 @@
*
* \e UnaryTypeTrait to determine if _TypeT is an enumeration type.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_enum
@@ -382,8 +407,8 @@
*
* \e UnaryTypeTrait to determine if _TypeT is a union type
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
*/
template <class _TypeT>
struct is_union
@@ -397,10 +422,11 @@
* \e UnaryTypeTrait to determine if _TypeT is a class type but not
* a union type.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
- *
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
* @note a C++ struct is of class type.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_class
@@ -413,8 +439,10 @@
*
* \e UnaryTypeTrait to determine if _TypeT is a function type.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_function
@@ -426,8 +454,9 @@
* @ingroup meta_unary_comp
*
* \e UnaryTypeTrait to determine if _TypeT is an arithmetic type.
- *
* Arithmetic types include both integral and floating point types.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_arithmetic
@@ -439,9 +468,10 @@
* @ingroup meta_unary_comp
*
* \e UnaryTypeTrait to determine if _TypeT is a fundamental type.
+ * Fundamental types are all the types provided natively. These types
+ * include all arithmetic types and all void types.
*
- * Fundamental types are all the types provided natively. These types include
- * all arithmetic types and all void types.
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_fundamental
@@ -453,9 +483,10 @@
* @ingroup meta_unary_comp
*
* \e UnaryTypeTrait to determine if _TypeT is an object type.
+ * An object type is a (possibly cv-qualified) type that is not
+ * a function type, not a reference type, and not a void type.
*
- * An object type is a (possibly cv-qualified) type that is not a function
- * type, not a reference type, and not a void type.
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_object
@@ -467,10 +498,11 @@
* @ingroup meta_unary_comp
*
* \e UnaryTypeTrait to determine if _TypeT is a scalar type.
+ * Arithmetic types, enumeration types, pointer types, pointer
+ * to member types, and cv-qualified versions of these types are
+ * collectively called scalar types.
*
- * Arithmetic types, enumeration types, pointer types, pointer to member
- * types, and cv-qualified versions of these types are collectively called
- * scalar types.
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_scalar
@@ -482,9 +514,11 @@
* @ingroup meta_unary_comp
*
* \e UnaryTypeTrait to determine if _TypeT is a compound type.
+ * Compound types are arrays, functions, pointers, references,
+ * classes, unions, enumerations and pointers to non-static class
+ * members.
*
- * Compound types are arrays, functions, pointers, references, classes
- * unions, enumerations and pointers to non-static class members.
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_compound
@@ -497,6 +531,8 @@
*
* \e UnaryTypeTrait to determine if _TypeT is a pointer to a member
* object or pointer to member function type.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_member_pointer
@@ -508,6 +544,8 @@
* @ingroup meta_unary_prop
*
* \e UnaryTypeTrait to determine if _TypeT is const-qualified.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_const
@@ -519,6 +557,8 @@
* @ingroup meta_unary_prop
*
* \e UnaryTypeTrait to determine if _TypeT is volatile-qualified.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_volatile
@@ -529,13 +569,17 @@
/**
* @ingroup meta_unary_prop
*
- * \e UnaryTypeTrait to determine if _TypeT is a trivial type.
+ * \e UnaryTypeTrait to determine if _TypeT is a trivial type. Scalar
+ * types, trivial class types, arrays of such types and cv-qualified
+ * versions of these types are collectively called trival types. Trivial
+ * class types have a trivial default constructor, a trivial destructor
+ * a trivial copy constructor and a trivial copy assignment operator.
*
- * _TypeT shall be a complete type, an array of unknown bound, or
- * possibly cv-qualified void.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct is_trivial
@@ -547,13 +591,23 @@
* @ingroup meta_unary_prop
*
* \e UnaryTypeTrait to determine if _TypeT is a type with standard
- * layout.
+ * layout. Scalar types, standard-layout class types, arrays of such
+ * types and cv-qualified versions of these types are collectively
+ * called standard layout types. Standard layout class types have no
+ * non-static data members of non-standard-layout class or reference.
+ * They have no virtual functions and no virtual base classes, use the
+ * same access control for all non-static data members, have no base
+ * classes of non-standard-layout type, no non-static data members in
+ * the most-derived class and at most one base class with non-static
+ * data members or has no base classes with non-static data members.
+ * Finally, a standard-layout class has no base classes of the same
+ * type as the first non-static data member.
*
- * _TypeT shall be a complete type, an array of unknown bound, or
- * possibly cv-qualified void.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct is_standard_layout
@@ -565,9 +619,16 @@
* @ingroup meta_unary_prop
*
* \e UnaryTypeTrait to determine if _TypeT is a plain-old-data type.
+ * Scalar types, pod classes, arrays of such types and cv-qualified
+ * versions of these types are collectively called pod types. The pod
+ * class types meet the requirements of both trivial and standard layout
+ * types and have no non-static data members of non-pod type.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct is_pod
@@ -580,8 +641,11 @@
*
* \e UnaryTypeTrait to determine if _TypeT is an empty class.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct is_empty
@@ -594,8 +658,11 @@
*
* \e UnaryTypeTrait to determine if _TypeT is a polymorphic class.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct is_polymorphic
@@ -608,8 +675,11 @@
*
* \e UnaryTypeTrait to determine if _TypeT is an abstract class.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct is_abstract
@@ -624,11 +694,11 @@
* class type with a trivial default constructor, or an array of
* such a class type.
*
- * _TypeT shall be a complete type, an array of unknown bound, or
- * possibly cv-qualified void.
- *
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_trivial_default_constructor
@@ -639,15 +709,14 @@
/**
* @ingroup meta_unary_prop
*
- * \e UnaryTypeTrait to determine if _TypeT is a trivial type or
- * a class type with a trivial copy constructor, or an array of
- * such a class type.
- *
- * _TypeT shall be a complete type, an array of unknown bound, or
- * possibly cv-qualified void.
+ * \e UnaryTypeTrait to determine if _TypeT is a trivial type, a
+ * reference type, or a class type with a trivial copy constructor.
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_trivial_copy_constructor
@@ -658,11 +727,15 @@
/**
* @ingroup meta_unary_prop
*
- * \e UnaryTypeTrait to determine if the assignment operator for _TypeT
- * is trivial.
+ * \e UnaryTypeTrait to determine if _TypeT is neither const nor a
+ * reference type and is a trivial type or a class type with a trivial
+ * assignment operator.
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_trivial_assign
@@ -673,10 +746,15 @@
/**
* @ingroup meta_unary_prop
*
- * \e UnaryTypeTrait to determine if the destructor for _TypeT is trivial.
+ * \e UnaryTypeTrait to determine if _TypeT is a trivial type, a reference
+ * type, or a class type with a trivial destructor, or an array of such a
+ * class type.
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_trivial_destructor
@@ -693,6 +771,9 @@
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_nothrow_default_constructor
@@ -709,6 +790,9 @@
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_nothrow_copy_constructor
@@ -725,6 +809,9 @@
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_nothrow_assign
@@ -739,6 +826,9 @@
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to evaluate. Shall be a complete type,
+ * an array of unknown bound, or possibly cv-qualified void.
*/
template <class _TypeT>
struct has_virtual_destructor
@@ -751,6 +841,8 @@
*
* \e UnaryTypeTrait to determine if _TypeT is a signed arithmetic
* type.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_signed
@@ -763,6 +855,8 @@
*
* \e UnaryTypeTrait to determine if _TypeT is an unsigned arithmetic
* type.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct is_unsigned
@@ -776,12 +870,14 @@
* \e UnaryTypeTrait to determine the alignment of objects of type
* _TypeT.
*
- * @note This may not be accurate for class types if the necessary
- * compiler support is not available.
+ * @note This may not be accurate if the necessary compiler support
+ * is not available.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct alignment_of
- : integral_constant<int, _RW::__rw_alignment_of<_TypeT>::value>
+ : integral_constant<_RWSTD_SIZE_T, _RW::__rw_alignment_of<_TypeT>::value>
{
};
@@ -789,22 +885,32 @@
* @ingroup meta_unary_prop
*
* \e UnaryTypeTrait to determine the rank of objects of type _TypeT.
+ * If _TypeT names an array type, the rank is an integer value that
+ * represents the number of dimensions of _TypeT, otherwise the value
+ * is 0.
+ *
+ * @tparam _TypeT The type to evaluate.
*/
template <class _TypeT>
struct rank
- : integral_constant<int, _RW::__rw_rank<_TypeT>::value>
+ : integral_constant<_RWSTD_SIZE_T, _RW::__rw_rank<_TypeT>::value>
{
};
/**
* @ingroup meta_unary_prop
*
- * \e UnaryTypeTrait to determine if the extent of the I'th bound of
- * objects of type _TypeT.
+ * \e UnaryTypeTrait to determine if the extent of one dimension of
+ * objects of type _TypeT. If _TypeT is an array type with rank greater
+ * than _Bound, the value will be the size of the given dimension of
+ * that array, otherwise the value is 0.
+ *
+ * @tparam _TypeT The type to evaluate.
+ * @tparam _Bound The dimension of the array to get the extent of.
*/
template <class _TypeT, unsigned _Bound = 0>
struct extent
- : integral_constant<int, _RW::__rw_extent<_TypeT, _Bound>::value>
+ : integral_constant<_RWSTD_SIZE_T, _RW::__rw_extent<_TypeT, _Bound>::value>
{
};
@@ -813,6 +919,9 @@
*
* \e UnaryTypeTrait to determine if _TypeT and _TypeU are exactly the
* same type.
+ *
+ * @tparam _TypeT The first type to compare.
+ * @tparam _TypeT The second type to compare.
*/
template <class _TypeT, class _TypeU>
struct is_same
@@ -832,10 +941,13 @@
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The base type.
+ * @tparam _TypeU The derived type.
*/
template <class _TypeT, class _TypeU>
struct is_base_of
- : integral_constant<int, _RW::__rw_is_base_of<_TypeT, _TypeU>::value>
+ : integral_constant<bool, _RW::__rw_is_base_of<_TypeT, _TypeU>::value>
{
};
@@ -847,10 +959,13 @@
*
* @note This may not be accurate for class types if the necessary
* compiler support is not available.
+ *
+ * @tparam _TypeT The type to test conversion from.
+ * @tparam _TypeT The type to test conversion to.
*/
template <class _TypeT, class _TypeU>
struct is_convertible
- : integral_constant<int, _RW::__rw_is_convertible<_TypeT, _TypeU>::value>
+ : integral_constant<bool, _RW::__rw_is_convertible<_TypeT, _TypeU>::value>
{
};
@@ -858,9 +973,10 @@
* @ingroup meta_trans_cv
*
* \e TransformationTrait to remove any top-level const-qualifier.
- *
* The member typedef \c type shall be the same as _TypeT except that
- * any top level const-qualifier has been removed
+ * any top level const-qualifier has been removed.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct remove_const
@@ -872,9 +988,10 @@
* @ingroup meta_trans_cv
*
* \e TransformationTrait to remove any top-level volatile-qualifier.
- *
* The member typedef \c type shall be the same as _TypeT except that
- * any top level volatile-qualifier has been removed
+ * any top level volatile-qualifier has been removed.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct remove_volatile
@@ -885,10 +1002,11 @@
/**
* @ingroup meta_trans_cv
*
- * \e TransformationTrait to remove any top-level cv-qualifiers.
+ * \e TransformationTrait to remove any top-level cv-qualifiers. The
+ * member typedef \c type shall be the same as _TypeT except that any
+ * top level cv-qualifier has been removed.
*
- * The member typedef \c type shall be the same as _TypeT except that
- * any top level cv-qualifier has been removed
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct remove_cv
@@ -899,11 +1017,12 @@
/**
* @ingroup meta_trans_cv
*
- * \e TransformationTrait to add a top-level const-qualifier.
- *
- * If _TypeT is a reference, function, or other type level const-
+ * \e TransformationTrait to add a top-level const-qualifier. If
+ * _TypeT is a reference, function, or other type level const-
* qualified type then \c type shall be the same as _TypeT,
- * otherwise _TypeT const
+ * otherwise _TypeT const.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct add_const
@@ -915,10 +1034,11 @@
* @ingroup meta_trans_cv
*
* \e TransformationTrait to add a top-level volatile-qualifier.
- *
* If _TypeT is a reference, function, or other type level volatile-
* qualified type then \c type shall be the same as _TypeT,
- * otherwise _TypeT volatile
+ * otherwise _TypeT volatile.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct add_volatile
@@ -931,6 +1051,7 @@
*
* \e TransformationTrait to add a top-level const and volatile-qualifier.
*
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct add_cv
@@ -944,7 +1065,9 @@
* \e TransformationTrait to remove a reference from _TypeT.
*
* The member typedef \c type shall be the same as _TypeT, except
- * any reference qualifier has been removed
+ * any reference qualifier has been removed.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct remove_reference
@@ -956,6 +1079,8 @@
* @ingroup meta_trans_ref
*
* \e TransformationTrait to add a reference to _TypeT.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct add_lvalue_reference
@@ -967,6 +1092,8 @@
* @ingroup meta_trans_ref
*
* \e TransformationTrait to add an rvalue-reference to _TypeT.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct add_rvalue_reference
@@ -979,6 +1106,8 @@
*
* \e TransformationTrait to get a signed type from an enum or non-
* boolean integral type.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct make_signed
@@ -991,6 +1120,8 @@
*
* \e TransformationTrait to get an unsigned type from an enum or non-
* boolean integral type.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct make_unsigned
@@ -1002,9 +1133,10 @@
* @ingroup meta_trans_arr
*
* \e TransformationTrait to remove a dimension from the type _TypeT.
- *
* If _TypeT is 'array of _TypeU', the member typedef \c type shall
* be _TypeU, otherwise _TypeT.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct remove_extent
@@ -1016,10 +1148,10 @@
* @ingroup meta_trans_arr
*
* \e TransformationTrait to remove all dimensions from the type
- * _TypeT.
+ * _TypeT. If _TypeT is 'multi-dimensional array of _TypeU', the
+ * member typedef \c type shall be _TypeU otherwise _TypeT.
*
- * If _TypeT is 'multi-dimensional array of _TypeU', the member typedef
- * \c type shall be _TypeU otherwise _TypeT.
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct remove_all_extents
@@ -1031,11 +1163,12 @@
* @ingroup meta_trans_pointer
*
* \e TransformationTrait to remove a pointer from the type _TypeT.
- *
* The member typedef \c type shall be the same as _TypeT, except
* any top level indirection has been removed.
*
- * @note pointers to members are left unchanged
+ * @note pointers to members are left unchanged.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct remove_pointer
@@ -1047,6 +1180,8 @@
* @ingroup meta_trans_pointer
*
* \e TransformationTrait to add a pointer to the type _TypeT.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct add_pointer
@@ -1056,23 +1191,77 @@
/**
* @ingroup meta_trans_other
+ *
+ * Special trait the defines a nested pod type that is suitable for
+ * use as uninitialized storage for any object whose size is at most
+ * _Len and alignment is a divisor of align.
+ *
+ * @tparam _Len The minimum size of the aligned storage. Shall not be 0.
+ * @tparam _Align The alignment of the aligned storage. Shall be equal
+ * to alignment_of<T> for some type T or not provided. The implementation
+ * requires that the alignment value be a non-zero power of two that is
+ * less than the maximum supported extended alignment.
*/
-template <_RWSTD_SIZE_T _Len, _RWSTD_SIZE_T _Align>
+template <_RWSTD_SIZE_T _Len,
+ _RWSTD_SIZE_T _Align = _RW::__rw_default_alignment<_Len>::value>
struct aligned_storage
{
- typedef _TYPENAME _RW::__rw_aligned_storage<_Len, _Align>::_C_Type type;
+ typedef _TYPENAME _RW::__rw_aligned_storage<_Len, _Align>::type type;
+};
+
+#ifndef _RWSTD_NO_VARIADIC_TEMPLATES
+
+/**
+ * @ingroup meta_trans_other
+ *
+ * Special trait the defines a nested pod type that is suitable for
+ * use as uninitialized storage for any object whose type is listed
+ * in _Types and whose size is at most _Len.
+ *
+ * @tparam _Len The minimum size of the aligned storage.
+ * @tparam _Types List of types which might be stored.
+ */
+template <_RWSTD_SIZE_T _Len, class... _Types>
+struct aligned_union;
+
+template <_RWSTD_SIZE_T _Len, class _TypeT, class... _Types>
+struct aligned_union
+ : _RW::__rw_aligned_union<_Len, _TypeT, _Types...>
+{
};
-///**
-// * @ingroup meta_trans_other
-// *
-// * @note This may not be accurate for class types if the necessary
-// * compiler support is not available.
-// */
-//template <_RWSTD_SIZE_T _Len, class... Types>
-//struct aligned_union
-//{
-//}
+#else
+
+/**
+ * @ingroup meta_trans_other
+ *
+ * Special trait the defines a nested pod type that is suitable for
+ * use as uninitialized storage for any object whose type is listed
+ * in _Types and whose size is at most _Len.
+ *
+ * @tparam _Len The minimum size of the aligned storage.
+ * @tparam _Type1 Type which might be stored.
+ * @tparam _Type2 Type which might be stored.
+ * @tparam _Type3 Type which might be stored.
+ * @tparam _Type4 Type which might be stored.
+ * @tparam _Type5 Type which might be stored.
+ * @tparam _Type6 Type which might be stored.
+ * @tparam _Type7 Type which might be stored.
+ * @tparam _Type8 Type which might be stored.
+ */
+template <_RWSTD_SIZE_T _Len,
+ class _Type1 , class _Type2 = _RW::__rw_empty,
+ class _Type3 = _RW::__rw_empty, class _Type4 = _RW::__rw_empty,
+ class _Type5 = _RW::__rw_empty, class _Type6 = _RW::__rw_empty,
+ class _Type7 = _RW::__rw_empty, class _Type8 = _RW::__rw_empty>
+struct aligned_union
+ : _RW::__rw_aligned_union<_Len,
+ _Type1, _Type2, _Type3, _Type4,
+ _Type5, _Type6, _Type7, _Type8>
+{
+};
+
+#endif
/**
* @ingroup meta_trans_other
@@ -1084,6 +1273,8 @@
* true, the member typedef type shall equal remove_extent<U>::type*. If
* \c is_function<U>::value is true, the member typedef shall equal
* \c add_pointer<U>::type. Otherwise the member typedef type equals \c U.
+ *
+ * @tparam _TypeT The type to transform.
*/
template <class _TypeT>
struct decay
@@ -1096,6 +1287,10 @@
*
* If _Enable is true, the member typedef \c type shall equal _TypeT;
* otherwise, there shall be no member typedef \c type.
+ *
+ * @tparam _Enable Flag used to select the primary template or the
+ * specialization.
+ * @tparam _TypeT The type of the member typedef if _Enable is true.
*/
template <bool _Enable, class _TypeT = void>
struct enable_if
@@ -1103,9 +1298,6 @@
typedef _TypeT type;
};
-/**
- *
- */
template <class _TypeT>
struct enable_if<false, _TypeT>
{
@@ -1116,6 +1308,11 @@
*
* If _Select is true, the member typedef \c type shall equal _TypeT
* otherwise \c type shall equal _TypeU.
+ *
+ * @tparam _Select Flag used to select the primary template or the
+ * specialization.
+ * @tparam _TypeT The type of the member typedef if _Select is true.
+ * @tparam _TypeU The type of the member typedef if _Select is false.
*/
template <bool _Select, class _TypeT, class _TypeU>
struct conditional
Modified: stdcxx/branches/4.3.x/tests/utilities/20.meta.trans.other.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilities/20.meta.trans.other.cpp?rev=669735&r1=669734&r2=669735&view=diff
==============================================================================
--- stdcxx/branches/4.3.x/tests/utilities/20.meta.trans.other.cpp (original)
+++ stdcxx/branches/4.3.x/tests/utilities/20.meta.trans.other.cpp Thu Jun 19
15:52:34 2008
@@ -28,6 +28,8 @@
**************************************************************************/
#include <rw_driver.h>
+#include <rw_printf.h> // for rwsprintfa()
+#include <stdlib.h> // for free()
// compile out all test code if extensions disabled
#ifndef _RWSTD_NO_EXT_CXX_0X
@@ -103,8 +105,8 @@
bool success)
{
rw_assert (success, 0, line,
- "%s<%s>::type is%{?}n't{;} %s as expected",
- trait, typeT, success, typeU);
+ "%s<%s>::type is%{?}n't%{;} %s as expected",
+ trait, typeT, !success, typeU);
}
void test_enable_if (int line, const char* typeT, int got, int exp)
@@ -115,26 +117,234 @@
typeT, !success, exp);
}
-#define TEST(Trait,TypeT,TypeU) \
- test_trait(__LINE__, #Trait, #TypeT, #TypeU, \
- std::is_same<Trait<TypeT>::type, TypeU>::value)
+void test_aligned_storage(int line,
+ size_t exp_sz, size_t got_sz,
+ size_t exp_al, size_t got_al)
+{
+ //
+ rw_assert (exp_sz <= got_sz, 0, line,
+ "std::aligned_storage<%zu, %zu>::type size is %zu; "
+ "expected %zu or more", exp_sz, exp_al, got_sz, exp_sz);
+
+ if (exp_al != 0) {
+ // alignment should be greater than or equal to expected
+ rw_assert (exp_al <= got_al, 0, line,
+ "std::aligned_storage<%zu, %zu>::type alignment is %zu; "
+ "expected %zu or more", exp_sz, exp_al, got_al, exp_al);
+ }
+ else {
+ // alignment should be less than or equal to the size of
+ // the object
+ rw_assert (got_al <= exp_sz, 0, line,
+ "std::aligned_storage<%zu, %zu>::type alignment is %zu; "
+ "expected %zu or less", exp_sz, exp_al, got_al, exp_sz);
+ }
+
+ const bool is_pow_2 = (got_al & (got_al - 1)) == 0;
+ rw_assert (is_pow_2, 0, line,
+ "std::aligned_storage<%zu, %zu>::type alignment expected "
+ "to be a power-of-two; got %zu", exp_sz, exp_al, got_al);
+};
/**************************************************************************/
static void test_aligned_storage ()
{
-}
+#define TEST(Size,Align) \
+ { \
+ typedef std::aligned_storage<Size, Align>::type storage_t; \
+ test_aligned_storage(__LINE__, \
+ Size, sizeof (storage_t), Align, __alignof (storage_t)); \
+ } typedef void __dummy
+
+ TEST (1, 1);
+ TEST (1, 2);
+ TEST (1, 4);
+ TEST (1, 8);
+
+ TEST (9, 1);
+ TEST (9, 2);
+ TEST (9, 4);
+ TEST (9, 8);
+
+ TEST (55, 1);
+ TEST (23, 2);
+ TEST (17, 4);
+ TEST (19, 8);
+
+#undef TEST
+#define TEST(Size) \
+ { \
+ typedef std::aligned_storage<Size>::type storage_t; \
+ test_aligned_storage(__LINE__, \
+ Size, sizeof (storage_t), 0, __alignof (storage_t)); \
+ } typedef void __dummy
+
+ // test default alignment
+ TEST (1);
+ TEST (1);
+ TEST (1);
+ TEST (1);
+
+ TEST (9);
+ TEST (9);
+ TEST (9);
+ TEST (9);
+
+ TEST (55);
+ TEST (23);
+ TEST (17);
+ TEST (19);
+
+#undef TEST
+}
+
+/**************************************************************************/
+
+struct null_t { };
+
+// get the maximum of 8 values
+size_t max8(size_t a1, size_t a2, size_t a3, size_t a4,
+ size_t a5, size_t a6, size_t a7, size_t a8)
+{
+ size_t r = a1;
+
+ if (r < a2) r = a2;
+ if (r < a3) r = a3;
+ if (r < a4) r = a4;
+ if (r < a5) r = a5;
+ if (r < a6) r = a6;
+ if (r < a7) r = a7;
+ if (r < a8) r = a8;
+
+ return r;
+}
+
+template <size_t Len,
+ class T1 , class T2 = null_t,
+ class T3 = null_t, class T4 = null_t,
+ class T5 = null_t, class T6 = null_t,
+ class T7 = null_t, class T8 = null_t>
+struct aligned_union_tester
+{
+ static void test (int line,
+ const char* t1 , const char* t2 = 0,
+ const char* t3 = 0, const char* t4 = 0,
+ const char* t5 = 0, const char* t6 = 0,
+ const char* t7 = 0, const char* t8 = 0)
+ {
+ const char* arr[] = {
+ t1, t2, t3, t4, t5, t6, t7, t8
+ };
+
+ char* pbuf = 0;
+ size_t bufsz = 0;
+
+ // get the list of template arguments in one buffer
+ rw_asnprintf(&pbuf, &bufsz, "%zu", Len);
+ for (size_t i = 0; i < sizeof (arr) / sizeof (*arr); ++i)
+ {
+ if (!arr [i])
+ break;
+
+ rw_asnprintf (&pbuf, &bufsz, "%{+}, %s", arr [i]);
+ }
+
+ typedef std::aligned_union<Len,T1,T2,T3,T4,T5,T6,T7,T8> aligned_t;
+
+ const bool pass1 = std::alignment_of<aligned_t::type>::value
+ == aligned_t::alignment_value;
+ rw_assert (pass1, 0, line,
+ "std::aligned_union<%s>::alignment_value is %zu; "
+ "expected %zu",
+ pbuf, aligned_t::alignment_value,
+ std::alignment_of<aligned_t::type>::value);
+
+ const size_t exp_al = max8(std::alignment_of<T1>::value,
+ std::alignment_of<T2>::value,
+ std::alignment_of<T3>::value,
+ std::alignment_of<T4>::value,
+ std::alignment_of<T5>::value,
+ std::alignment_of<T6>::value,
+ std::alignment_of<T7>::value,
+ std::alignment_of<T8>::value);
+ const size_t got_al = std::alignment_of<aligned_t::type>::value;
+
+ const bool pass2 = exp_al == got_al;
+ rw_assert (pass2, 0, line,
+ "std::aligned_union<%s>::type alignment is %zu; "
+ "expected %zu",
+ pbuf, got_al, exp_al);
+
+ const size_t min_sz = Len;
+ const size_t got_sz = sizeof (aligned_t::type);
+
+ const bool pass3 = min_sz <= got_sz;
+
+ rw_assert (pass3, 0, __LINE__,
+ "std::aligned_union<%s>::type size is %zu; expected "
+ "at least %zu",
+ pbuf, got_sz, min_sz);
-/**************************************************************************/
+ free (pbuf);
+ }
+};
+
+struct struct_t { };
static void test_aligned_union ()
{
+#define TEST(Len,T1) \
+ aligned_union_tester<Len,T1>::test(__LINE__,#T1)
+
+ TEST (1, char);
+ TEST (1, long);
+ TEST (1, void*);
+ TEST (1, void (struct_t::*)());
+
+ TEST (2, char);
+ TEST (2, long);
+ TEST (2, void*);
+ TEST (2, void (struct_t::*)());
+
+ TEST (12, char);
+ TEST (12, long);
+ TEST (12, void*);
+ TEST (12, void (struct_t::*)());
+
+#undef TEST
+#define TEST(Len,T1,T2) \
+ aligned_union_tester<Len,T1,T2>::test(__LINE__,#T1,#T2)
+
+ TEST (11, char, long);
+ TEST (134, long, long);
+ TEST (7, void*, long);
+ TEST (1, void (struct_t::*)(), long);
+
+ TEST (2, char, long);
+ TEST (2, long, long);
+ TEST (2, void*, long);
+ TEST (2, void (struct_t::*)(), long);
+
+#undef TEST
+#define TEST(Len,T1,T2,T3,T4,T5) \
+
aligned_union_tester<Len,T1,T2,T3,T4,T5>::test(__LINE__,#T1,#T2,#T3,#T4,#T5)
+
+ TEST (12, char, short, int, long, void*);
+ TEST (13, void*, long, long, long, int);
+ TEST (17, void (struct_t::*)(), long, int, void*, char);
+
+#undef TEST
}
/**************************************************************************/
static void test_decay ()
{
+#define TEST(Trait,TypeT,TypeU) \
+ test_trait(__LINE__, #Trait, #TypeT, #TypeU, \
+ std::is_same<Trait<TypeT>::type, TypeU>::value)
+
// equal to remove_extent<remove_reference<T>::type>::type* for arrays
TEST (std::decay, int[ ], int*);
TEST (std::decay, int[2], int*);
@@ -157,6 +367,8 @@
TEST (std::decay, const int&, int);
TEST (std::decay, volatile int&, int);
TEST (std::decay, const volatile int&, int);
+
+#undef TEST
}
/**************************************************************************/
@@ -167,8 +379,7 @@
{
typedef std::enable_if<true, int>::type int_type;
-#undef TEST
-#define TEST(Cond,Expect) \
+#define TEST(Cond,Expect) \
test_enable_if(__LINE__, #Cond, Cond, Expect)
TEST (enabled_if_char< char>(), 1);
@@ -197,22 +408,29 @@
TEST (enabled_if_char<char (&)[1]>(), 0);
TEST (enabled_if_char<enum_t>(), 0);
+
+#undef TEST
}
/**************************************************************************/
static void test_conditional ()
{
+#define TEST(Cond,Expect) \
+ test_enable_if(__LINE__, #Cond, Cond, Expect)
+
TEST (cond_if_char<void>(), 0);
TEST (cond_if_char<char>(), 1);
-#undef TEST
+#undef TEST
#define TEST(Trait,Select,TypeT,TypeU,TypeV) \
test_trait(__LINE__, Select, #Trait, #TypeT, #TypeU, \
- std::is_same<Trait<Select,TypeT,TypeU>::type, TypeV>::value)
+ std::is_same<Trait<Select,TypeT,TypeU>::type, TypeV>::value)
TEST (std::conditional, true, char, long, char);
TEST (std::conditional, false, char, long, long);
+
+#undef TEST
}
/**************************************************************************/