This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Fix two libstdc++ test failures with -std=gnu++14


On 16/06/2015 22:45, Jonathan Wakely wrote:
> On 16/06/15 22:18 +0200, François Dumont wrote:
>> On 12/06/2015 01:22, Jonathan Wakely wrote:
>>> This fixes two test failures when the default compiler mode is
>>> -std=gnu++14
>>>
>>> FAIL: 25_algorithms/headers/algorithm/synopsis.cc (test for excess
>>> errors)
>>> FAIL: ext/profile/mutex_extensions_neg.cc (test for excess errors)
>>>
>>> I don't really like the change to the synopsis.cc test, but I don't
>>> think reproducing the SFINAE constraints in the test is ideal either.
>>>
>>> The mutex_extensions_neg.cc test works now, but I think we're missing
>>> specializations of __is_tuple_like_impl for __gnu_debug::array and
>>> __gnu_profile::array.
>>>
>>> Tested powerpc64le-linux, committed to trunk.
>>>
>> This patch introduced a regression in
>> 20_util/tuple/creation_functions/tuple_cat.cc in debug mode.
>
> Yes, I noticed this today while testing some changes to <debug/list>,
> but hadn't had time to do anything about it, so thanks for taking care
> of it.
>
>> Attached is a proposal to fix it properly. I am using <utility> as a
>> pivot header between <tuple> and <array>. This way <tuple> do not need
>> to include <array> anymore.
>
> I think that's a good improvement.

But it doesn't work. <array> needs to be included before tuple to make
sure that constexpr involving array will work.

So here is a less ambitious patch keeping <array> in <tuple>.

What I don't understand is that when I try to remove <array> from
<tuple> following code stop working:

#include <tuple>
#include <array>

static_assert(std::is_same<decltype
          (std::tuple_cat(std::declval<std::array<int, 3>>())),
              std::tuple<int, int, int>>::value, "Error");

but if I invert <tuple> and <array> it does work.

Now with <array> in <tuple> it works fine in any situation. However when
I write:

#include <tuple>
#include <debug/array>

static_assert(std::is_same<decltype
          (std::tuple_cat(std::declval<std::__debug::array<int, 3>>())),
              std::tuple<int, int, int>>::value, "Error");

it works too and I don't understand why !

    * include/debug/array: Include normal array. Add version namespace when
    specializing tuple interface to array. Add specialization for
    __is_tuple_like_impl.
    * include/profile/array: Likewise.
    * include/std/array: Include <utility>. Add specialization for
    __is_tuple_like_impl.
    * include/std/tuple
    (__is_tuple_like_impl<>, __is_tuple_like_impl<pair>): Move...
    * include/std/utility: ... here. Include <type_traits>.

Tested under Linux x86_64 normal and debug modes.

Ok to commit ?

François


diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array
index 34e6281..a1c7d40 100644
--- a/libstdc++-v3/include/debug/array
+++ b/libstdc++-v3/include/debug/array
@@ -31,6 +31,8 @@
 
 #pragma GCC system_header
 
+#include <array>
+
 #include <debug/formatter.h>
 #include <debug/macros.h>
 
@@ -292,20 +294,27 @@ namespace __debug
     }
 } // namespace __debug
 
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Tuple interface to class template array.
 
   /// tuple_size
   template<typename _Tp, std::size_t _Nm>
-    struct tuple_size<__debug::array<_Tp, _Nm>>
+    struct tuple_size<std::__debug::array<_Tp, _Nm>>
     : public integral_constant<std::size_t, _Nm> { };
 
   /// tuple_element
   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
-    struct tuple_element<_Int, __debug::array<_Tp, _Nm>>
+    struct tuple_element<_Int, std::__debug::array<_Tp, _Nm>>
     {
       static_assert(_Int < _Nm, "index is out of bounds");
       typedef _Tp type;
     };
+
+  template<typename _Tp, std::size_t _Nm>
+    struct __is_tuple_like_impl<std::__debug::array<_Tp, _Nm>> : true_type
+    { };
+
+_GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
 #endif // _GLIBCXX_DEBUG_ARRAY
diff --git a/libstdc++-v3/include/profile/array b/libstdc++-v3/include/profile/array
index 434ca96..687c052 100644
--- a/libstdc++-v3/include/profile/array
+++ b/libstdc++-v3/include/profile/array
@@ -31,6 +31,8 @@
 
 #pragma GCC system_header
 
+#include <array>
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 namespace __profile
@@ -253,20 +255,27 @@ namespace __profile
     }
 } // namespace __profile
 
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Tuple interface to class template array.
 
   /// tuple_size
   template<typename _Tp, std::size_t _Nm>
-    struct tuple_size<__profile::array<_Tp, _Nm>>
+    struct tuple_size<std::__profile::array<_Tp, _Nm>>
     : public integral_constant<std::size_t, _Nm> { };
 
   /// tuple_element
   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
-    struct tuple_element<_Int, __profile::array<_Tp, _Nm>>
+    struct tuple_element<_Int, std::__profile::array<_Tp, _Nm>>
     {
       static_assert(_Int < _Nm, "index is out of bounds");
       typedef _Tp type;
     };
+
+  template<typename _Tp, std::size_t _Nm>
+    struct __is_tuple_like_impl<std::__profile::array<_Tp, _Nm>> : true_type
+    { };
+
+_GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
 #endif // _GLIBCXX_PROFILE_ARRAY
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 40fbd46..d1b5e6d 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -35,6 +35,7 @@
 # include <bits/c++0x_warning.h>
 #else
 
+#include <utility>
 #include <stdexcept>
 #include <bits/stl_algobase.h>
 #include <bits/range_access.h>
@@ -331,6 +332,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef _Tp type;
     };
 
+  template<typename _Tp, std::size_t _Nm>
+    struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type
+    { };
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 953d16b..0504012 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -976,22 +976,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     forward_as_tuple(_Elements&&... __args) noexcept
     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
 
-  template<typename>
-    struct __is_tuple_like_impl : false_type
-    { };
-
   template<typename... _Tps>
     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
     { };
 
-  template<typename _T1, typename _T2>
-    struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
-    { };
-
-  template<typename _Tp, std::size_t _Nm>
-    struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type
-    { };
-
   // Internal type trait that allows us to sfinae-protect tuple_cat.
   template<typename _Tp>
     struct __is_tuple_like
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 1aac77c..89b6852 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -71,6 +71,7 @@
 
 #if __cplusplus >= 201103L
 
+#include <type_traits>
 #include <bits/move.h>
 #include <initializer_list>
 
@@ -84,7 +85,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<std::size_t _Int, class _Tp>
     class tuple_element;
 
-   // Various functions which give std::pair a tuple-like interface.
+  template<typename>
+    struct __is_tuple_like_impl : false_type
+    { };
+
+  // Various functions which give std::pair a tuple-like interface.
+
+  /// Partial specialization for std::pair
+  template<typename _T1, typename _T2>
+    struct __is_tuple_like_impl<std::pair<_T1, _T2>> : true_type
+    { };
 
   /// Partial specialization for std::pair
   template<class _Tp1, class _Tp2>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]