You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by vi...@apache.org on 2008/06/20 00:52:34 UTC

svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

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  <vi...@roguewave.com>

	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
 }
 
 /**************************************************************************/



RE: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>Travis Vitek wrote:
>> 
>> I'm not absolutely sure I'm reading the documentation you linked to
>> correctly, but here goes...
>
>It's possible that I misread the text. I was pretty sure (and still
>am) I remembered discussing the alignment issue before but I couldn't
>(and still can't) find it in the archives. I pointed to this page
>because that was the best I could come up with in the absence of
>anything else. Maybe it's a red herring. It could also be that the
>issue I think I'm remembering had less to do with alignment than
>something else (aliasing, maybe), but given the choice between
>placing the more strictly aligned type first and the unaligned
>buffer second or doing laying them down in the reverse order I'd
>go for the former even if there is no real issue.
>
>I searched library headers and sources for how we define unions and
>with the exception of limits_bits.cpp we always follow this rule.
>Unless there is a reason not to make this change to aligned_union,
>I think we should change both limits_bits.cpp and aligned_union to
>always define the member with the more strict alignment requirement
>first, just for peace of mind.

Good thing you didn't look at my original implementation of
aligned_union. :)

>
>Is there any reason/advantage to having the char buffer first?
>

Not that I know of. I'll update them all.

>> 
>> The first paragraph of that documentation says
>> 
>> Individual members of a union are mapped the same way as 
>> members of the
>> structure. That is, each of the members, if not a union, is 
>> mapped as if
>> it were a member of a structure.  This means that the first storage
>> locations for each of the members of a union do not overlay 
>> each other
>> if each of the members requires different alignment and therefore
>> different padding before the beginning of the member.
>> 
>> This violates C99 (6.7.2.1 p5)
>
>Not all compilers support C99, and of those that do not all of them
>conform to 100% of the requirements. The layout of structs and unions
>is an ABI issue, and it's quite possible that there are systems that
>can't afford to break the ABI for compatibility reasons.
>

Sure. I didn't have a copy of C90 handy, but I'd be willing to bet that
it had some similar requirement in there. I'm sure most compilers
conform to C90 given that they have had nearly 20 years to do so.


>

Re: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
>  
> 
> Martin Sebor wrote:
>> Travis Vitek wrote:
>>>  
>>>
>>> Martin Sebor wrote:
>>>> I searched library headers and sources for how we define unions and
>>>> with the exception of limits_bits.cpp we always follow this rule.
>>>> Unless there is a reason not to make this change to aligned_union,
>>>> I think we should change both limits_bits.cpp and aligned_union to
>>>> always define the member with the more strict alignment requirement
>>>> first, just for peace of mind.
>>>>
>>>> Is there any reason/advantage to having the char buffer first?
>>>>
>>> If the first member is used to define the alignment, then you have to
>>> know (at compile time) which of the union members has the strictest
>>> alignment requirement so that it can be put first.
>> Yes. But putting the char buffer first doesn't obviate the
>> need to do this, does it?
> 
> No, I'm just poking another hole in the policy of always putting the
> most strictly aligned member first. If I can't reliably determine the
> most strictly aligned member, it makes it a tad difficult to declare it
> first.
> 
> So now the policy becomes 'put the one that you think has the most
> stringent alignment requirement on platform X'.

That's essentially been the guideline in existing code.
What do you suggest as an improvement?

Martin


RE: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>Travis Vitek wrote:
>>  
>> 
>> Martin Sebor wrote:
>>> I searched library headers and sources for how we define unions and
>>> with the exception of limits_bits.cpp we always follow this rule.
>>> Unless there is a reason not to make this change to aligned_union,
>>> I think we should change both limits_bits.cpp and aligned_union to
>>> always define the member with the more strict alignment requirement
>>> first, just for peace of mind.
>>>
>>> Is there any reason/advantage to having the char buffer first?
>>>
>> 
>> If the first member is used to define the alignment, then you have to
>> know (at compile time) which of the union members has the strictest
>> alignment requirement so that it can be put first.
>
>Yes. But putting the char buffer first doesn't obviate the
>need to do this, does it?

No, I'm just poking another hole in the policy of always putting the
most strictly aligned member first. If I can't reliably determine the
most strictly aligned member, it makes it a tad difficult to declare it
first.

So now the policy becomes 'put the one that you think has the most
stringent alignment requirement on platform X'.

>Btw., if you're not subscribed to c++std-lib@accu.org yet,

Yes, I am finally subscribed. 

>aligned_union was among the alignment features discussed
>last week. An new issue has been filed to remove
>aligned_union because it's superseded by the alignas()
>core language feature:
>http://tinyurl.com/5da3l8

I tinyurl'd this to fit into a 70 character line.

According to the issue, aligned_union<> is supposedly being supersceeded
by 'extended unions', but I understand that some things could be done
with alignas(). If alignas() is supported, then aligned_storage<> can,
for the most part, be implemented trivially, but aligned_union<> still
requires some work.

I realize that this is really not the place to argue against its
removal, but I don't really understand why either should be removed. At
the very least, both of these allow library implementations to support
functionality when the compiler support doesn't exist yet (I can
implement aligned_union<>, but I most definitely cannot implement
alignas()). Not only that, but I honestly find code using the trait much
more readable than using the keyword directly.

>I also plan to submit an issue to remove the other aligned
>traits for the same reason, although the initial feedback
>suggests that this issue might be more controversial than
>the removal of aligned_union.
>
>In any case, it seems likely that the question of which of
>the members of aligned_union comes first may soon be moot
>anyway. That said...
>
>> 
>> This problem comes up in the definition of 
>__rw_aligned_buffer. On most
>> implementations the members are ordered according to the scheme you
>> mentioned previously, but it is very possible for them to be out of
>> order.
>
>...I'm not sure I see your point WRT __rw_aligned_buffer. In
>the absence of alignas (or some such), how do you suggest we
>prevent this?

I don't. As I mentioned above, I'm poking holes in the policy.

>
>Martin
>
>> 
>>     union {
>>   #ifndef _RWSTD_NO_LONG_DOUBLE
>>         long double _C_pad;
>>   #else
>>         double      _C_pad;
>>   #endif   // _RWSTD_NO_LONG_DOUBLE
>>         void       *_C_void_pad;
>>         void      (*_C_pfn_pad)();
>>         char        _C_data [sizeof (_TypeT)];
>>     } _C_buf;
>> 
>> Travis
>
>

Re: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
>  
> 
> Martin Sebor wrote:
>> I searched library headers and sources for how we define unions and
>> with the exception of limits_bits.cpp we always follow this rule.
>> Unless there is a reason not to make this change to aligned_union,
>> I think we should change both limits_bits.cpp and aligned_union to
>> always define the member with the more strict alignment requirement
>> first, just for peace of mind.
>>
>> Is there any reason/advantage to having the char buffer first?
>>
> 
> If the first member is used to define the alignment, then you have to
> know (at compile time) which of the union members has the strictest
> alignment requirement so that it can be put first.

Yes. But putting the char buffer first doesn't obviate the
need to do this, does it?

Btw., if you're not subscribed to c++std-lib@accu.org yet,
aligned_union was among the alignment features discussed
last week. An new issue has been filed to remove
aligned_union because it's superseded by the alignas()
core language feature:
http://home.twcny.rr.com/hinnant/cpp_extensions/issues_preview/lwg-active.html#856

I also plan to submit an issue to remove the other aligned
traits for the same reason, although the initial feedback
suggests that this issue might be more controversial than
the removal of aligned_union.

In any case, it seems likely that the question of which of
the members of aligned_union comes first may soon be moot
anyway. That said...

> 
> This problem comes up in the definition of __rw_aligned_buffer. On most
> implementations the members are ordered according to the scheme you
> mentioned previously, but it is very possible for them to be out of
> order.

...I'm not sure I see your point WRT __rw_aligned_buffer. In
the absence of alignas (or some such), how do you suggest we
prevent this?

Martin

> 
>     union {
>   #ifndef _RWSTD_NO_LONG_DOUBLE
>         long double _C_pad;
>   #else
>         double      _C_pad;
>   #endif   // _RWSTD_NO_LONG_DOUBLE
>         void       *_C_void_pad;
>         void      (*_C_pfn_pad)();
>         char        _C_data [sizeof (_TypeT)];
>     } _C_buf;
> 
> Travis


RE: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>I searched library headers and sources for how we define unions and
>with the exception of limits_bits.cpp we always follow this rule.
>Unless there is a reason not to make this change to aligned_union,
>I think we should change both limits_bits.cpp and aligned_union to
>always define the member with the more strict alignment requirement
>first, just for peace of mind.
>
>Is there any reason/advantage to having the char buffer first?
>

If the first member is used to define the alignment, then you have to
know (at compile time) which of the union members has the strictest
alignment requirement so that it can be put first.

This problem comes up in the definition of __rw_aligned_buffer. On most
implementations the members are ordered according to the scheme you
mentioned previously, but it is very possible for them to be out of
order.

    union {
  #ifndef _RWSTD_NO_LONG_DOUBLE
        long double _C_pad;
  #else
        double      _C_pad;
  #endif   // _RWSTD_NO_LONG_DOUBLE
        void       *_C_void_pad;
        void      (*_C_pfn_pad)();
        char        _C_data [sizeof (_TypeT)];
    } _C_buf;

Travis

Re: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
> Martin Sebor wrote:
>> vitek@apache.org wrote:
>>> 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  <vi...@roguewave.com>
>>>
>>> 	STDCXX-926
>> [...]
>>> +template <size_t _Size, size_t _Align = 
>>> __rw_default_alignment<_Size>::value>
>>>  struct __rw_aligned_storage
>>>  {
> 
> [...]
> 
>>>      typedef union {
>>> -        unsigned char __data [_Len];
>>> -        // not implemented
>>> +        unsigned char __size [_Size];
>>> +
>>> +        typename
>>> +        __rw_aligned_storage_impl<_Align>::_C_type __align;
>> I believe there are platforms where unions are aligned on
>> the boundary given by the first member. This one looks like
>> it might be one of them: http://tinyurl.com/472744. Unless
>> I'm mistaken we should switch the order of the two members
>> to make sure the union is properly aligned.
>>
> 
> I'm not absolutely sure I'm reading the documentation you linked to
> correctly, but here goes...

It's possible that I misread the text. I was pretty sure (and still
am) I remembered discussing the alignment issue before but I couldn't
(and still can't) find it in the archives. I pointed to this page
because that was the best I could come up with in the absence of
anything else. Maybe it's a red herring. It could also be that the
issue I think I'm remembering had less to do with alignment than
something else (aliasing, maybe), but given the choice between
placing the more strictly aligned type first and the unaligned
buffer second or doing laying them down in the reverse order I'd
go for the former even if there is no real issue.

I searched library headers and sources for how we define unions and
with the exception of limits_bits.cpp we always follow this rule.
Unless there is a reason not to make this change to aligned_union,
I think we should change both limits_bits.cpp and aligned_union to
always define the member with the more strict alignment requirement
first, just for peace of mind.

Is there any reason/advantage to having the char buffer first?

> 
> The first paragraph of that documentation says
> 
> Individual members of a union are mapped the same way as members of the
> structure. That is, each of the members, if not a union, is mapped as if
> it were a member of a structure.  This means that the first storage
> locations for each of the members of a union do not overlay each other
> if each of the members requires different alignment and therefore
> different padding before the beginning of the member.
> 
> This violates C99 (6.7.2.1 p5)

Not all compilers support C99, and of those that do not all of them
conform to 100% of the requirements. The layout of structs and unions
is an ABI issue, and it's quite possible that there are systems that
can't afford to break the ABI for compatibility reasons.

Martin

> 
>   As discussed in 6.2.5, a structure is a type consisting
>   of a sequence of members, whose storage is allocated in
>   an ordered sequence, and a union is a type consisting
>   of a sequence of members whose storage overlap.
> 
> And (6.7.2.1 p14)
> 
>   The size of a union is sufficient to contain the largest
>   of its members. The value of at most one of the members
>   can be stored in a union object at any time. A pointer
>   to a union object, suitably converted, points to each of
>   its members, and vise versa.
> 
> It also voilates C++03 (expr.rel p2)
> 
>   If two pointers point to data members of the same union
>   object, they compare equal (after conversion to void*,
>   if necessary).
> 
> Even so, the last paragraph of "Rules for mapping one pair" says
> 
>   The pair is now a unit of fixed length and alignment
>   requirement, its length is the sum of the two lengths
>   plus padding, and its alignment requirement is the
>   higher of the two alignment requirements (if they
>   differ).
> 
> So the alignment would still be correct as the alignment requirement is
> weakest (smallest) for char types, so the alignment that would be used
> would be the alignment of the other type.
> 
> Please correct me if I'm misinterpreting any of this.
> 
> Travis
> 
>> Also, strictly speaking, names of data members should have
>> the _C_ prefix (double underscores are used for locals and
>> function parameters).
> 
> Agreed. I will fix.
> 
>> Martin
>>


RE: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Travis Vitek <Tr...@roguewave.com>.
Martin Sebor wrote:
>
>vitek@apache.org wrote:
>> 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  <vi...@roguewave.com>
>> 
>> 	STDCXX-926
>[...]
>> +template <size_t _Size, size_t _Align = 
>>__rw_default_alignment<_Size>::value>
>>  struct __rw_aligned_storage
>>  {

[...]

>>      typedef union {
>> -        unsigned char __data [_Len];
>> -        // not implemented
>> +        unsigned char __size [_Size];
>> +
>> +        typename
>> +        __rw_aligned_storage_impl<_Align>::_C_type __align;
>
>I believe there are platforms where unions are aligned on
>the boundary given by the first member. This one looks like
>it might be one of them: http://tinyurl.com/472744. Unless
>I'm mistaken we should switch the order of the two members
>to make sure the union is properly aligned.
>

I'm not absolutely sure I'm reading the documentation you linked to
correctly, but here goes...

The first paragraph of that documentation says

Individual members of a union are mapped the same way as members of the
structure. That is, each of the members, if not a union, is mapped as if
it were a member of a structure.  This means that the first storage
locations for each of the members of a union do not overlay each other
if each of the members requires different alignment and therefore
different padding before the beginning of the member.

This violates C99 (6.7.2.1 p5)

  As discussed in 6.2.5, a structure is a type consisting
  of a sequence of members, whose storage is allocated in
  an ordered sequence, and a union is a type consisting
  of a sequence of members whose storage overlap.

And (6.7.2.1 p14)

  The size of a union is sufficient to contain the largest
  of its members. The value of at most one of the members
  can be stored in a union object at any time. A pointer
  to a union object, suitably converted, points to each of
  its members, and vise versa.

It also voilates C++03 (expr.rel p2)

  If two pointers point to data members of the same union
  object, they compare equal (after conversion to void*,
  if necessary).

Even so, the last paragraph of "Rules for mapping one pair" says

  The pair is now a unit of fixed length and alignment
  requirement, its length is the sum of the two lengths
  plus padding, and its alignment requirement is the
  higher of the two alignment requirements (if they
  differ).

So the alignment would still be correct as the alignment requirement is
weakest (smallest) for char types, so the alignment that would be used
would be the alignment of the other type.

Please correct me if I'm misinterpreting any of this.

Travis

>Also, strictly speaking, names of data members should have
>the _C_ prefix (double underscores are used for locals and
>function parameters).

Agreed. I will fix.

>
>Martin
>

Re: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp

Posted by Martin Sebor <se...@roguewave.com>.
vitek@apache.org wrote:
> 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  <vi...@roguewave.com>
> 
> 	STDCXX-926
[...]
> 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 @@
[...]
> +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;

I believe there are platforms where unions are aligned on
the boundary given by the first member. This one looks like
it might be one of them: http://tinyurl.com/472744. Unless
I'm mistaken we should switch the order of the two members
to make sure the union is properly aligned.

Also, strictly speaking, names of data members should have
the _C_ prefix (double underscores are used for locals and
function parameters).

Martin