aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRüdiger Sonderfeld <ruediger@c-plusplus.de>2014-06-02 13:55:14 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2014-06-02 14:55:14 +0100
commitd371802725867b21958d4457cb7a796b6399935b (patch)
treee9fc3e80b1487ecccbd9641ea6015917edb45f64
parentae48824a7975ef0bdde6d7a57f99f8b72bbf62dc (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2011.xml5
-rw-r--r--libstdc++-v3/include/std/type_traits49
-rw-r--r--libstdc++-v3/testsuite/20_util/aligned_union/1.cc72
-rw-r--r--libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc2
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>