Workaround GCC bug PR78489 - SFINAE order is not respected.
authorEric Fiselier <eric@efcs.ca>
Thu, 22 Mar 2018 22:32:55 +0000 (22:32 +0000)
committerEric Fiselier <eric@efcs.ca>
Thu, 22 Mar 2018 22:32:55 +0000 (22:32 +0000)
This patch works around variant test failures which are new to
GCC 8. GCC 8 either doesn't perform SFINAE in lexical order, or
it doesn't halt after encountering the first failure. This
causes hard error to occur instead of substitution failure.

See gcc.gnu.org/PR78489

llvm-svn: 328261

libcxx/include/variant
libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp

index f9098f42249a78d54803e0073d8a7e739aeef183..6f78e2de1573b7b15a50885fc75bebddbde0d085 100644 (file)
@@ -1156,29 +1156,24 @@ public:
       : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
 
   template <size_t _Ip, class... _Args,
-            class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
-            class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
-            enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
+            enable_if_t<(_Ip < sizeof...(_Types)), size_t> _Ip2 = _Ip,
+            class _Tp = variant_alternative_t<_Ip2, variant<_Types...>>,
+            enable_if_t<is_constructible<_Tp, _Args...>::value, int> = 0>
   inline _LIBCPP_INLINE_VISIBILITY
-  explicit constexpr variant(
-      in_place_index_t<_Ip>,
-      _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
+  explicit constexpr variant(in_place_index_t<_Ip>,
+                             _Args&&... __args)
+        noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
       : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
 
-  template <
-      size_t _Ip,
-      class _Up,
-      class... _Args,
-      enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
-      class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
+  template <size_t _Ip, class _Up, class... _Args,
+      enable_if_t<(_Ip < sizeof...(_Types)), size_t> _Ip2 = _Ip,
+      class _Tp = variant_alternative_t<_Ip2, variant<_Types...>>,
       enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
                   int> = 0>
   inline _LIBCPP_INLINE_VISIBILITY
-  explicit constexpr variant(
-      in_place_index_t<_Ip>,
-      initializer_list<_Up> __il,
-      _Args&&... __args) noexcept(
-      is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
+  explicit constexpr variant(in_place_index_t<_Ip>, initializer_list<_Up> __il,
+                             _Args&&... __args)
+        noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
       : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
 
   template <
index 608cdf9d6efbbf17a78bf73f6fa515a087092700..9d0bf55fb538569f64ebac415f985dda9aa65640 100644 (file)
@@ -73,6 +73,12 @@ void test_ctor_sfinae() {
         !std::is_constructible<V, std::in_place_index_t<2>, IL>::value, "");
     static_assert(!test_convertible<V, std::in_place_index_t<2>, IL>(), "");
   }
+  { // index not in variant
+    using V = std::variant<InitList, InitListArg, int>;
+    static_assert(
+        !std::is_constructible<V, std::in_place_index_t<3>, IL>::value, "");
+    static_assert(!test_convertible<V, std::in_place_index_t<3>, IL>(), "");
+  }
 }
 
 void test_ctor_basic() {