Return-Path: Delivered-To: apmail-stdcxx-commits-archive@www.apache.org Received: (qmail 67346 invoked from network); 19 Jun 2008 22:53:26 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 19 Jun 2008 22:53:26 -0000 Received: (qmail 92213 invoked by uid 500); 19 Jun 2008 22:53:28 -0000 Delivered-To: apmail-stdcxx-commits-archive@stdcxx.apache.org Received: (qmail 92197 invoked by uid 500); 19 Jun 2008 22:53:28 -0000 Mailing-List: contact commits-help@stdcxx.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@stdcxx.apache.org Delivered-To: mailing list commits@stdcxx.apache.org Received: (qmail 92188 invoked by uid 99); 19 Jun 2008 22:53:28 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Jun 2008 15:53:28 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Jun 2008 22:52:45 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 8583F23889F7; Thu, 19 Jun 2008 15:52:34 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp Date: Thu, 19 Jun 2008 22:52:34 -0000 To: commits@stdcxx.apache.org From: vitek@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080619225234.8583F23889F7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 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 +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 +struct __rw_conditional +{ + typedef _TypeU type; +}; + +#define _RWSTD_CONDITIONAL(C,T,U) _RW::__rw_conditional::type + + +/** + * Helper for __rw_aligned_storage. Specializations define a member type + * that is aligned on power of two boundaries. + */ +template +struct __rw_aligned_storage_impl; + +#define _RWSTD_ALIGNED_STORAGE_SPEC(N) \ + template <> struct __rw_aligned_storage_impl { \ + 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 +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 +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 +struct __rw_default_alignment +{ + enum { value = __rw_default_alignment_impl<_Size, 1>::value }; +}; + + +/** + * + */ +template ::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 +struct __rw_biggest; -template <_RWSTD_SIZE_T _Len, class _TypeT, class... _Types> -struct __rw_aligned_union_impl<_Len, _TypeT, _Types...> +template +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 +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 +struct __rw_strictest; + +template +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 +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 +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 +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 -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 -struct __rw_conditional -{ - typedef _TypeU type; -}; - -#define _RWSTD_CONDITIONAL(C,T,U) _RW::__rw_conditional::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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 struct alignment_of - : integral_constant::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 struct rank - : integral_constant::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 struct extent - : integral_constant::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 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 struct is_base_of - : integral_constant::value> + : integral_constant::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 struct is_convertible - : integral_constant::value> + : integral_constant::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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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::type*. If * \c is_function::value is true, the member typedef shall equal * \c add_pointer::type. Otherwise the member typedef type equals \c U. + * + * @tparam _TypeT The type to transform. */ template 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 struct enable_if @@ -1103,9 +1298,6 @@ typedef _TypeT type; }; -/** - * - */ template struct enable_if { @@ -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 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 +#include // for rwsprintfa() +#include // 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::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::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::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 +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 aligned_t; + + const bool pass1 = std::alignment_of::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::value); + + const size_t exp_al = max8(std::alignment_of::value, + std::alignment_of::value, + std::alignment_of::value, + std::alignment_of::value, + std::alignment_of::value, + std::alignment_of::value, + std::alignment_of::value, + std::alignment_of::value); + const size_t got_al = std::alignment_of::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::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::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::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::type, TypeU>::value) + // equal to remove_extent::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::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(), 0); TEST (enabled_if_char(), 0); + +#undef TEST } /**************************************************************************/ static void test_conditional () { +#define TEST(Cond,Expect) \ + test_enable_if(__LINE__, #Cond, Cond, Expect) + TEST (cond_if_char(), 0); TEST (cond_if_char(), 1); -#undef TEST +#undef TEST #define TEST(Trait,Select,TypeT,TypeU,TypeV) \ test_trait(__LINE__, Select, #Trait, #TypeT, #TypeU, \ - std::is_same::type, TypeV>::value) + std::is_same::type, TypeV>::value) TEST (std::conditional, true, char, long, char); TEST (std::conditional, false, char, long, long); + +#undef TEST } /**************************************************************************/