public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 2/2] libstdc++: Add std::aligned_union.
       [not found] <5d1b2765297b384d5f278f9b389723249930ee7c.1397660778.git.ruediger@c-plusplus.de>
@ 2014-04-16 15:13 ` Rüdiger Sonderfeld
  2014-04-16 15:34   ` Jonathan Wakely
  0 siblings, 1 reply; 7+ messages in thread
From: Rüdiger Sonderfeld @ 2014-04-16 15:13 UTC (permalink / raw)
  To: libstdc++, gcc-patches

C++11: [meta.trans.other]

* libstdc++-v3/testsuite/20_util/aligned_union/1.cc: New file.
* 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).
---
 libstdc++-v3/include/std/type_traits              | 43 ++++++++++++++
 libstdc++-v3/testsuite/20_util/aligned_union/1.cc | 72 
+++++++++++++++++++++++
 2 files changed, 115 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/aligned_union/1.cc

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-
v3/include/std/type_traits
index 4b434a6..2b75345 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1837,6 +1837,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       };
     };
 
+  template <typename... _Types>
+    struct __strictest_alignment
+    {
+      static const size_t _M_alignment = 0;
+      static const size_t _M_size = 0;
+    };
+
+  template <typename _T, typename... _Types>
+    struct __strictest_alignment<_T, _Types...>
+    {
+      static const size_t _M_alignment =
+        alignof(_T) > __strictest_alignment<_Types...>::_M_alignment ?
+        alignof(_T) : __strictest_alignment<_Types...>::_M_alignment;
+      static const size_t _M_size =
+        sizeof(_T) > __strictest_alignment<_Types...>::_M_size ?
+        sizeof(_T) : __strictest_alignment<_Types...>::_M_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
+    {
+      /// The value of the strictest alignment of _Types.
+      static const size_t alignment_value =
+        __strictest_alignment<_Types...>::_M_alignment;
+      static const size_t _M_len =
+        _Len > __strictest_alignment<_Types...>::_M_size ?
+        _Len : __strictest_alignment<_Types...>::_M_size;
+      /// The storage.
+      typedef typename aligned_storage<_M_len, alignment_value>::type type;
+    };
 
   // Decay trait for arrays and functions, used for perfect forwarding
   // in make_pair, make_tuple, etc.
@@ -2173,6 +2213,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, class... 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..c01ecc0
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/aligned_union/1.cc
@@ -0,0 +1,72 @@
+// { dg-options " -std=gnu++11 " }
+
+// 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 <initializer_list>
+#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();
+}
-- 
1.9.2

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] libstdc++: Add std::aligned_union.
  2014-04-16 15:13 ` [PATCH 2/2] libstdc++: Add std::aligned_union Rüdiger Sonderfeld
@ 2014-04-16 15:34   ` Jonathan Wakely
  2014-04-16 15:47     ` [PATCHv2 " Rüdiger Sonderfeld
  0 siblings, 1 reply; 7+ messages in thread
From: Jonathan Wakely @ 2014-04-16 15:34 UTC (permalink / raw)
  To: Rüdiger Sonderfeld; +Cc: libstdc++, gcc-patches

On 16/04/14 17:06 +0200, Rüdiger Sonderfeld wrote:
>C++11: [meta.trans.other]
>
>* libstdc++-v3/testsuite/20_util/aligned_union/1.cc: New file.
>* 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).

Thanks! I was hoping to implement it the straightforward way, but was
thwarted by http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59012


>+  template <typename... _Types>
>+    struct __strictest_alignment
>+    {
>+      static const size_t _M_alignment = 0;
>+      static const size_t _M_size = 0;

The naming convention is to use _S_xxx for static members

>+  template <size_t Len, class... Types>
>+    using aligned_union_t = typename aligned_union<Len,Types...>::type;

It should be s/class/typename/ here.

Is <initializer_list> needed for the testcase?

The testcase can use { dg-do compile } to turn it into a compile-only
test, and then doesn't need a main() function.

Otherwise I think this looks good, thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCHv2 2/2] libstdc++: Add std::aligned_union.
  2014-04-16 15:34   ` Jonathan Wakely
@ 2014-04-16 15:47     ` Rüdiger Sonderfeld
  2014-04-16 16:00       ` [PATCHv3 " Rüdiger Sonderfeld
  0 siblings, 1 reply; 7+ messages in thread
From: Rüdiger Sonderfeld @ 2014-04-16 15:47 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches


> Thanks! I was hoping to implement it the straightforward way, but was
> thwarted by http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59012

There are certainly nicer ways to implement it.  At least in C++14
there should be a usable constexpr std::max instead of the verbose
?: usage.  Maybe sizeof/alignof could be used with the parameter
pack expansion.

I fixed the other issues below.

Regards,
Rüdiger

-- 8< ----------------------------------------------------------- >8 --

C++11: [meta.trans.other]

* libstdc++-v3/testsuite/20_util/aligned_union/1.cc: New file.
* 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).
---
 libstdc++-v3/include/std/type_traits              | 43 ++++++++++++++
 libstdc++-v3/testsuite/20_util/aligned_union/1.cc | 72 +++++++++++++++++++++++
 2 files changed, 115 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/aligned_union/1.cc

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 4b434a6..4441290 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1837,6 +1837,46 @@ _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 _T, typename... _Types>
+    struct __strictest_alignment<_T, _Types...>
+    {
+      static const size_t _S_alignment =
+        alignof(_T) > __strictest_alignment<_Types...>::_S_alignment ?
+        alignof(_T) : __strictest_alignment<_Types...>::_S_alignment;
+      static const size_t _S_size =
+        sizeof(_T) > __strictest_alignment<_Types...>::_S_size ?
+        sizeof(_T) : __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
+    {
+      /// The value of the strictest alignment of _Types.
+      static const size_t alignment_value =
+        __strictest_alignment<_Types...>::_M_alignment;
+      static const size_t _S_len =
+        _Len > __strictest_alignment<_Types...>::_S_size ?
+        _Len : __strictest_alignment<_Types...>::_S_size;
+      /// The storage.
+      typedef typename aligned_storage<_S_len, alignment_value>::type type;
+    };
 
   // Decay trait for arrays and functions, used for perfect forwarding
   // in make_pair, make_tuple, etc.
@@ -2173,6 +2213,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)");
+}
-- 
1.9.2

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCHv3 2/2] libstdc++: Add std::aligned_union.
  2014-04-16 15:47     ` [PATCHv2 " Rüdiger Sonderfeld
@ 2014-04-16 16:00       ` Rüdiger Sonderfeld
  2014-04-16 23:44         ` Paolo Carlini
  2014-06-02 13:56         ` Jonathan Wakely
  0 siblings, 2 replies; 7+ messages in thread
From: Rüdiger Sonderfeld @ 2014-04-16 16:00 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

Of course I forgot to replace one _M_ instance.  This should work now.
Sorry about this.

-- 8< --------------------------------------------------------- >8 --

C++11: [meta.trans.other]

* libstdc++-v3/testsuite/20_util/aligned_union/1.cc: New file.
* 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).
---
 libstdc++-v3/include/std/type_traits              | 43 ++++++++++++++
 libstdc++-v3/testsuite/20_util/aligned_union/1.cc | 72 
+++++++++++++++++++++++
 2 files changed, 115 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/aligned_union/1.cc

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-
v3/include/std/type_traits
index 4b434a6..7fb3b74 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1837,6 +1837,46 @@ _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 _T, typename... _Types>
+    struct __strictest_alignment<_T, _Types...>
+    {
+      static const size_t _S_alignment =
+        alignof(_T) > __strictest_alignment<_Types...>::_S_alignment ?
+        alignof(_T) : __strictest_alignment<_Types...>::_S_alignment;
+      static const size_t _S_size =
+        sizeof(_T) > __strictest_alignment<_Types...>::_S_size ?
+        sizeof(_T) : __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
+    {
+      /// The value of the strictest alignment of _Types.
+      static const size_t alignment_value =
+        __strictest_alignment<_Types...>::_S_alignment;
+      static const size_t _S_len =
+        _Len > __strictest_alignment<_Types...>::_S_size ?
+        _Len : __strictest_alignment<_Types...>::_S_size;
+      /// The storage.
+      typedef typename aligned_storage<_S_len, alignment_value>::type type;
+    };
 
   // Decay trait for arrays and functions, used for perfect forwarding
   // in make_pair, make_tuple, etc.
@@ -2173,6 +2213,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();
+}
-- 
1.9.2

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCHv3 2/2] libstdc++: Add std::aligned_union.
  2014-04-16 16:00       ` [PATCHv3 " Rüdiger Sonderfeld
@ 2014-04-16 23:44         ` Paolo Carlini
  2014-04-16 23:57           ` Paolo Carlini
  2014-06-02 13:56         ` Jonathan Wakely
  1 sibling, 1 reply; 7+ messages in thread
From: Paolo Carlini @ 2014-04-16 23:44 UTC (permalink / raw)
  To: Rüdiger Sonderfeld, Jonathan Wakely; +Cc: libstdc++, gcc-patches

Hi,

On 04/16/2014 05:47 PM, Rüdiger Sonderfeld wrote:
> +  template <typename _T, typename... _Types>
Please avoid _ + Uppercase, those are badnames for many targets. 
Normally we add a p at the end. Also, I would mention in a comment the 
front-end bug preventing a much more straightforward implementation.

Thanks,
Paolo.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCHv3 2/2] libstdc++: Add std::aligned_union.
  2014-04-16 23:44         ` Paolo Carlini
@ 2014-04-16 23:57           ` Paolo Carlini
  0 siblings, 0 replies; 7+ messages in thread
From: Paolo Carlini @ 2014-04-16 23:57 UTC (permalink / raw)
  To: Rüdiger Sonderfeld, Jonathan Wakely; +Cc: libstdc++, gcc-patches

.. also, per the GNU conventions, ? of a conditional expression should 
be at the beginning of a line (not at the end of the previous one).

Paolo.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCHv3 2/2] libstdc++: Add std::aligned_union.
  2014-04-16 16:00       ` [PATCHv3 " Rüdiger Sonderfeld
  2014-04-16 23:44         ` Paolo Carlini
@ 2014-06-02 13:56         ` Jonathan Wakely
  1 sibling, 0 replies; 7+ messages in thread
From: Jonathan Wakely @ 2014-06-02 13:56 UTC (permalink / raw)
  To: Rüdiger Sonderfeld; +Cc: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 747 bytes --]

On 16/04/14 17:47 +0200, Rüdiger Sonderfeld wrote:
>Of course I forgot to replace one _M_ instance.  This should work now.
>Sorry about this.
>
>-- 8< --------------------------------------------------------- >8 --
>
>C++11: [meta.trans.other]
>
>* libstdc++-v3/testsuite/20_util/aligned_union/1.cc: New file.
>* 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).

Hi,

I've fixed up the patch to meet the coding standards, define the
static member aligned_union::alignment_value, check the precondition,
update the docs and fix a test failure.

Tested x86_64-linux, committed to trunk.

Thanks for adding this missing piece!


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 6873 bytes --]

commit 7018ff5142ba1413b140d9d69c7263565ecae000
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sun Jun 1 23:33:29 2014 +0100

    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.

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>
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-06-02 13:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <5d1b2765297b384d5f278f9b389723249930ee7c.1397660778.git.ruediger@c-plusplus.de>
2014-04-16 15:13 ` [PATCH 2/2] libstdc++: Add std::aligned_union Rüdiger Sonderfeld
2014-04-16 15:34   ` Jonathan Wakely
2014-04-16 15:47     ` [PATCHv2 " Rüdiger Sonderfeld
2014-04-16 16:00       ` [PATCHv3 " Rüdiger Sonderfeld
2014-04-16 23:44         ` Paolo Carlini
2014-04-16 23:57           ` Paolo Carlini
2014-06-02 13:56         ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).