diff options
author | Rüdiger Sonderfeld <ruediger@c-plusplus.de> | 2014-06-02 13:55:14 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2014-06-02 14:55:14 +0100 |
commit | d371802725867b21958d4457cb7a796b6399935b (patch) | |
tree | e9fc3e80b1487ecccbd9641ea6015917edb45f64 | |
parent | ae48824a7975ef0bdde6d7a57f99f8b72bbf62dc (diff) | |
download | gcc-d371802725867b21958d4457cb7a796b6399935b.zip gcc-d371802725867b21958d4457cb7a796b6399935b.tar.gz gcc-d371802725867b21958d4457cb7a796b6399935b.tar.bz2 |
type_traits (__strictest_alignment): New helper struct.
2014-06-02 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
Jonathan Wakely <jwakely@redhat.com>
* libstdc++-v3/include/std/type_traits (__strictest_alignment): New
helper struct.
(aligned_union): New struct (C++11).
(aligned_union_t): New type alias (C++14).
* doc/xml/manual/status_cxx2011.xml: Update.
* libstdc++-v3/testsuite/20_util/aligned_union/1.cc: New file.
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
line number.
Co-Authored-By: Jonathan Wakely <jwakely@redhat.com>
From-SVN: r211137
-rw-r--r-- | libstdc++-v3/ChangeLog | 12 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/manual/status_cxx2011.xml | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/std/type_traits | 49 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/aligned_union/1.cc | 72 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc | 2 |
5 files changed, 136 insertions, 4 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 56e7d34..885718f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2014-06-02 Rüdiger Sonderfeld <ruediger@c-plusplus.de> + Jonathan Wakely <jwakely@redhat.com> + + * libstdc++-v3/include/std/type_traits (__strictest_alignment): New + helper struct. + (aligned_union): New struct (C++11). + (aligned_union_t): New type alias (C++14). + * doc/xml/manual/status_cxx2011.xml: Update. + * libstdc++-v3/testsuite/20_util/aligned_union/1.cc: New file. + * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error + line number. + 2014-06-01 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/61374 diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml index b3c24d8..cad4111 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml @@ -871,11 +871,10 @@ particular release. <entry/> </row> <row> - <?dbhtml bgcolor="#B0B0B0" ?> <entry>20.9.7.6</entry> <entry>Other transformations</entry> - <entry>Partial</entry> - <entry>Missing <code>aligned_union</code>.</entry> + <entry>Y</entry> + <entry/> </row> <row> <entry>20.10</entry> diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 1ff2e62..da8a95f 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -1870,6 +1870,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; }; + template <typename... _Types> + struct __strictest_alignment + { + static const size_t _S_alignment = 0; + static const size_t _S_size = 0; + }; + + template <typename _Tp, typename... _Types> + struct __strictest_alignment<_Tp, _Types...> + { + static const size_t _S_alignment = + alignof(_Tp) > __strictest_alignment<_Types...>::_S_alignment + ? alignof(_Tp) : __strictest_alignment<_Types...>::_S_alignment; + static const size_t _S_size = + sizeof(_Tp) > __strictest_alignment<_Types...>::_S_size + ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size; + }; + + /** + * @brief Provide aligned storage for types. + * + * [meta.trans.other] + * + * Provides aligned storage for any of the provided types of at + * least size _Len. + * + * @see aligned_storage + */ + template <size_t _Len, typename... _Types> + struct aligned_union + { + private: + static_assert(sizeof...(_Types) != 0, "At least one type is required"); + + using __strictest = __strictest_alignment<_Types...>; + static const size_t _S_len = _Len > __strictest::_S_size + ? _Len : __strictest::_S_size; + public: + /// The value of the strictest alignment of _Types. + static const size_t alignment_value = __strictest::_S_alignment; + /// The storage. + typedef typename aligned_storage<_S_len, alignment_value>::type type; + }; + + template <size_t _Len, typename... _Types> + const size_t aligned_union<_Len, _Types...>::alignment_value; // Decay trait for arrays and functions, used for perfect forwarding // in make_pair, make_tuple, etc. @@ -2206,6 +2252,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __alignof__(typename __aligned_storage_msa<_Len>::__type)> using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; + template <size_t _Len, typename... _Types> + using aligned_union_t = typename aligned_union<_Len, _Types...>::type; + /// Alias template for decay template<typename _Tp> using decay_t = typename decay<_Tp>::type; diff --git a/libstdc++-v3/testsuite/20_util/aligned_union/1.cc b/libstdc++-v3/testsuite/20_util/aligned_union/1.cc new file mode 100644 index 0000000..5285bb0 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/aligned_union/1.cc @@ -0,0 +1,72 @@ +// { dg-options " -std=gnu++11 " } +// { dg-do compile } + +// 2014-04-16 Rüdiger Sonderfeld <ruediger@c-plusplus.de> + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 3, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// C++11 [meta.trans.other] 20.9.7.6: aligned_union + +#include <type_traits> +#include <testsuite_tr1.h> + +struct MSAlignType { } __attribute__((__aligned__)); + +template<typename...T> + struct mymax + { + static const std::size_t alignment = 0; + static const std::size_t size = 0; + }; + +template<typename L, typename...T> + struct mymax<L, T...> + { + static const std::size_t alignment = alignof(L) > mymax<T...>::alignment + ? alignof(L) : mymax<T...>::alignment; + static const std::size_t size = sizeof(L) > mymax<T...>::size + ? sizeof(L) : mymax<T...>::size; + }; + +void test01() +{ + using std::aligned_union; + using std::alignment_of; + using std::size_t; + using namespace __gnu_test; + + const size_t max_a = mymax<char, short, int, double, int[4], + ClassType, MSAlignType>::alignment; + const size_t max_s = mymax<char, short, int, double, int[4], + ClassType, MSAlignType>::size; + + typedef aligned_union<0, char, short, int, double, int[4], + ClassType, MSAlignType> au_type; + static_assert(au_type::alignment_value == max_a, "Alignment value"); + static_assert(sizeof(au_type::type) >= max_s, "Storage size"); + + typedef aligned_union<max_s+100, char, short, int, double, int[4], + ClassType, MSAlignType> au_type2; + static_assert(sizeof(au_type2::type) >= max_s+100, + "Storage size (at least len)"); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc index 04e6b71..774858c 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -// { dg-error "static assertion failed" "" { target *-*-* } 2036 } +// { dg-error "static assertion failed" "" { target *-*-* } 2082 } #include <utility> |