From 5544f7e0c7c89c82acf8cf1f9681e737f3955755 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Mon, 22 Apr 2013 19:37:49 +0000 Subject: [PATCH] Somehow aligned_union got dropped through the cracks. This adds it. Did a drive-by fix of alignment_of while I was in the neighborhood. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@180036 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/type_traits | 37 ++++++++++- .../meta.trans.other/aligned_storage.pass.cpp | 12 ++-- .../meta.trans.other/aligned_union.pass.cpp | 65 +++++++++++++++++++ .../alignment_of.pass.cpp | 4 +- 4 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 test/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp diff --git a/include/type_traits b/include/type_traits index 7178978f5..ab0e22201 100644 --- a/include/type_traits +++ b/include/type_traits @@ -129,6 +129,7 @@ namespace std template struct alignment_of; template struct aligned_storage; + template struct aligned_union; template struct decay; template struct common_type; @@ -828,10 +829,8 @@ template struct _LIBCPP_TYPE_VIS has_virtual_destructor // alignment_of -template struct __alignment_of {_Tp __lx;}; - template struct _LIBCPP_TYPE_VIS alignment_of - : public integral_constant::type>)> {}; + : public integral_constant {}; // aligned_storage @@ -960,6 +959,38 @@ _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000); #undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION +#ifndef _LIBCPP_HAS_NO_VARIADICS + +// aligned_union + +template +struct __static_max; + +template +struct __static_max<_I0> +{ + static const size_t value = _I0; +}; + +template +struct __static_max<_I0, _I1, _In...> +{ + static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : + __static_max<_I1, _In...>::value; +}; + +template +struct aligned_union +{ + static const size_t alignment_value = __static_max<__alignof__(_Type0), + __alignof__(_Types)...>::value; + static const size_t __len = __static_max<_Len, sizeof(_Type0), + sizeof(_Types)...>::value; + typedef typename aligned_storage<__len, alignment_value>::type type; +}; + +#endif // _LIBCPP_HAS_NO_VARIADICS + // __promote template ::type T1; - static_assert(std::alignment_of::value == (sizeof(long) == 4 ? 4 : 8), ""); + static_assert(std::alignment_of::value == 8, ""); static_assert(sizeof(T1) == 8, ""); } { typedef std::aligned_storage<9>::type T1; - static_assert(std::alignment_of::value == (sizeof(long) == 4 ? 4 : 8), ""); - static_assert(sizeof(T1) == (sizeof(long) == 4 ? 12 : 16), ""); + static_assert(std::alignment_of::value == 8, ""); + static_assert(sizeof(T1) == 16, ""); } { typedef std::aligned_storage<15>::type T1; - static_assert(std::alignment_of::value == (sizeof(long) == 4 ? 4 : 8), ""); + static_assert(std::alignment_of::value == 8, ""); static_assert(sizeof(T1) == 16, ""); } { @@ -117,7 +117,7 @@ int main() } { typedef std::aligned_storage<10>::type T1; - static_assert(std::alignment_of::value == (sizeof(long) == 4 ? 4 : 8), ""); - static_assert(sizeof(T1) == (sizeof(long) == 4 ? 12 : 16), ""); + static_assert(std::alignment_of::value == 8, ""); + static_assert(sizeof(T1) == 16, ""); } } diff --git a/test/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp b/test/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp new file mode 100644 index 000000000..b07a06479 --- /dev/null +++ b/test/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// type_traits + +// aligned_union + +#include + +int main() +{ +#ifndef _LIBCPP_HAS_NO_VARIADICS + { + typedef std::aligned_union<10, char >::type T1; + static_assert(std::alignment_of::value == 1, ""); + static_assert(sizeof(T1) == 10, ""); + } + { + typedef std::aligned_union<10, short >::type T1; + static_assert(std::alignment_of::value == 2, ""); + static_assert(sizeof(T1) == 10, ""); + } + { + typedef std::aligned_union<10, int >::type T1; + static_assert(std::alignment_of::value == 4, ""); + static_assert(sizeof(T1) == 12, ""); + } + { + typedef std::aligned_union<10, double >::type T1; + static_assert(std::alignment_of::value == 8, ""); + static_assert(sizeof(T1) == 16, ""); + } + { + typedef std::aligned_union<10, short, char >::type T1; + static_assert(std::alignment_of::value == 2, ""); + static_assert(sizeof(T1) == 10, ""); + } + { + typedef std::aligned_union<10, char, short >::type T1; + static_assert(std::alignment_of::value == 2, ""); + static_assert(sizeof(T1) == 10, ""); + } + { + typedef std::aligned_union<2, int, char, short >::type T1; + static_assert(std::alignment_of::value == 4, ""); + static_assert(sizeof(T1) == 4, ""); + } + { + typedef std::aligned_union<2, char, int, short >::type T1; + static_assert(std::alignment_of::value == 4, ""); + static_assert(sizeof(T1) == 4, ""); + } + { + typedef std::aligned_union<2, char, short, int >::type T1; + static_assert(std::alignment_of::value == 4, ""); + static_assert(sizeof(T1) == 4, ""); + } +#endif +} diff --git a/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp b/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp index 87c222488..c896aa202 100644 --- a/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp +++ b/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp @@ -30,13 +30,13 @@ public: int main() { - test_alignment_of(); + test_alignment_of(); test_alignment_of(); test_alignment_of(); test_alignment_of(); test_alignment_of(); test_alignment_of(); - test_alignment_of(); + test_alignment_of(); test_alignment_of(); test_alignment_of(); }