[libcxx-commits] [libcxx] 24d2a01 - [libc++] Make SFINAE'd member functions in string mutually exclusive.

Eric Fiselier via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jan 15 14:00:56 PST 2020


Author: Eric Fiselier
Date: 2020-01-15T17:00:26-05:00
New Revision: 24d2a015eade6e71e7c684c69510f067bdd55892

URL: https://github.com/llvm/llvm-project/commit/24d2a015eade6e71e7c684c69510f067bdd55892
DIFF: https://github.com/llvm/llvm-project/commit/24d2a015eade6e71e7c684c69510f067bdd55892.diff

LOG: [libc++] Make SFINAE'd member functions in string mutually exclusive.

This patch is needed in order to work around a GCC bug that fails to
explicitly instantiate a non-template function of a class template when
there is another overload that's a function template.
(See https://godbolt.org/z/4bUQ_b)

This patch SFINAE's away the function templates when the argument is
a basic_string.

Added: 
    

Modified: 
    libcxx/include/string

Removed: 
    


################################################################################
diff  --git a/libcxx/include/string b/libcxx/include/string
index 8a0ac844470c..c13cefc64e39 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -643,9 +643,10 @@ struct __libcpp_string_gets_noexcept_iterator
     : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
 
 template <class _CharT, class _Traits, class _Tp>
-struct __can_be_converted_to_string_view : public _LIBCPP_BOOL_CONSTANT(
-    ( is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
-     !is_convertible<const _Tp&, const _CharT*>::value)) {};
+struct __can_be_converted_to_string_view : public _BoolConstant<
+      is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
+     !is_convertible<const _Tp&, const _CharT*>::value
+    > {};
 
 #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
@@ -812,7 +813,7 @@ public:
     basic_string(basic_string&& __str, const allocator_type& __a);
 #endif  // _LIBCPP_CXX03_LANG
 
-    template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
+    template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t>>
     _LIBCPP_INLINE_VISIBILITY
     basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {
       _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
@@ -822,7 +823,7 @@ public:
 #   endif
     }
 
-    template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
+    template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t>>
         _LIBCPP_INLINE_VISIBILITY
         basic_string(const _CharT* __s, const _Allocator& __a);
 
@@ -833,7 +834,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     basic_string(size_type __n, _CharT __c);
 
-    template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
+    template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t>>
         _LIBCPP_INLINE_VISIBILITY
         basic_string(size_type __n, _CharT __c, const _Allocator& __a);
 
@@ -843,23 +844,24 @@ public:
     basic_string(const basic_string& __str, size_type __pos,
                  const _Allocator& __a = _Allocator());
 
-    template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
+    template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
         _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
         basic_string(const _Tp& __t, size_type __pos, size_type __n,
-                              const allocator_type& __a = allocator_type());
+                     const allocator_type& __a = allocator_type());
 
-    template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
+    template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                                          !__is_same_uncvref<_Tp, basic_string>::value> >
         _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
         explicit basic_string(const _Tp& __t);
 
-    template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
+    template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
         _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
         explicit basic_string(const _Tp& __t, const allocator_type& __a);
 
-    template<class _InputIterator, class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value>::type>
+    template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>>
         _LIBCPP_INLINE_VISIBILITY
         basic_string(_InputIterator __first, _InputIterator __last);
-    template<class _InputIterator, class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value>::type>
+    template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>>
         _LIBCPP_INLINE_VISIBILITY
         basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
 #ifndef _LIBCPP_CXX03_LANG
@@ -876,7 +878,7 @@ public:
 
     basic_string& operator=(const basic_string& __str);
 
-    template <class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
+    template <class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
     basic_string& operator=(const _Tp& __t)
         {__self_view __sv = __t; return assign(__sv);}
 
@@ -976,11 +978,12 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
+            && !__is_same_uncvref<_Tp, basic_string >::value,
             basic_string&
-        >::type
+        >
                                             operator+=(const _Tp& __t)            {__self_view __sv = __t; return append(__sv);}
     _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s)     {return append(__s);}
     _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c)            {push_back(__c); return *this;}
@@ -993,21 +996,22 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+    _EnableIf<
+            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
+            && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
-        >::type
+        >
                   append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
     basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
+            && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
-        >::type
+        >
                   append(const _Tp& __t, size_type __pos, size_type __n=npos);
     basic_string& append(const value_type* __s, size_type __n);
     basic_string& append(const value_type* __s);
@@ -1021,12 +1025,12 @@ public:
     basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
     template<class _InputIterator>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __is_exactly_cpp17_input_iterator<_InputIterator>::value
                 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             basic_string&
-        >::type
+        >
     _LIBCPP_INLINE_VISIBILITY
     append(_InputIterator __first, _InputIterator __last) {
       const basic_string __temp (__first, __last, __alloc());
@@ -1035,12 +1039,12 @@ public:
     }
     template<class _ForwardIterator>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __is_cpp17_forward_iterator<_ForwardIterator>::value
                 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             basic_string&
-        >::type
+        >
     _LIBCPP_INLINE_VISIBILITY
     append(_ForwardIterator __first, _ForwardIterator __last) {
       return __append_forward_unsafe(__first, __last);
@@ -1061,11 +1065,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             basic_string&
-        >::type
+        >
                  assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
     _LIBCPP_INLINE_VISIBILITY
     basic_string& assign(const basic_string& __str) { return *this = __str; }
@@ -1078,32 +1082,33 @@ public:
     basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
+            && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
-        >::type
+        >
                   assign(const _Tp & __t, size_type __pos, size_type __n=npos);
     basic_string& assign(const value_type* __s, size_type __n);
     basic_string& assign(const value_type* __s);
     basic_string& assign(size_type __n, value_type __c);
     template<class _InputIterator>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
            __is_exactly_cpp17_input_iterator<_InputIterator>::value
                 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             basic_string&
-        >::type
+        >
         assign(_InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __is_cpp17_forward_iterator<_ForwardIterator>::value
                  && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             basic_string&
-        >::type
+        >
         assign(_ForwardIterator __first, _ForwardIterator __last);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
@@ -1115,21 +1120,21 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             basic_string&
-        >::type
+        >
                  insert(size_type __pos1, const _Tp& __t)
     { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
-        >::type
+        >
                   insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
     basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
     basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
@@ -1140,21 +1145,21 @@ public:
     iterator      insert(const_iterator __pos, size_type __n, value_type __c);
     template<class _InputIterator>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
            __is_exactly_cpp17_input_iterator<_InputIterator>::value
                 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             iterator
-        >::type
+        >
         insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __is_cpp17_forward_iterator<_ForwardIterator>::value
                  && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             iterator
-        >::type
+        >
         insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
@@ -1173,20 +1178,20 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             basic_string&
-        >::type
+        >
                   replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
     basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
-        >::type
+        >
                   replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
     basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
     basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
@@ -1196,11 +1201,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             basic_string&
-        >::type
+        >
                   replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
 
     _LIBCPP_INLINE_VISIBILITY
@@ -1211,11 +1216,11 @@ public:
     basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
     template<class _InputIterator>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __is_cpp17_input_iterator<_InputIterator>::value,
             basic_string&
-        >::type
+        >
         replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
@@ -1253,11 +1258,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
-        >::type
+        >
               find(const _Tp& __t, size_type __pos = 0) const;
     size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
@@ -1269,11 +1274,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
-        >::type
+        >
               rfind(const _Tp& __t, size_type __pos = npos) const;
     size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
@@ -1285,11 +1290,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
-        >::type
+        >
               find_first_of(const _Tp& __t, size_type __pos = 0) const;
     size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
@@ -1302,11 +1307,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
-        >::type
+        >
               find_last_of(const _Tp& __t, size_type __pos = npos) const;
     size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
@@ -1319,11 +1324,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
-        >::type
+        >
               find_first_not_of(const _Tp &__t, size_type __pos = 0) const;
     size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
@@ -1336,11 +1341,11 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
-        >::type
+        >
               find_last_not_of(const _Tp& __t, size_type __pos = npos) const;
     size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
@@ -1353,20 +1358,20 @@ public:
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             int
-        >::type
+        >
         compare(const _Tp &__t) const;
 
     template <class _Tp>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    typename enable_if
+    _EnableIf
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             int
-        >::type
+        >
          compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -1375,11 +1380,11 @@ public:
 
     template <class _Tp>
     inline _LIBCPP_INLINE_VISIBILITY
-        typename enable_if
+        _EnableIf
         <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
             int
-        >::type
+        >
         compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
     int compare(const value_type* __s) const _NOEXCEPT;
     int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
@@ -1545,20 +1550,18 @@ private:
 
     template <class _InputIterator>
     inline
-    typename enable_if
+    _EnableIf
     <
-        __is_exactly_cpp17_input_iterator<_InputIterator>::value,
-        void
-    >::type
+        __is_exactly_cpp17_input_iterator<_InputIterator>::value
+    >
     __init(_InputIterator __first, _InputIterator __last);
 
     template <class _ForwardIterator>
     inline
-    typename enable_if
+    _EnableIf
     <
-        __is_cpp17_forward_iterator<_ForwardIterator>::value,
-        void
-    >::type
+        __is_cpp17_forward_iterator<_ForwardIterator>::value
+    >
     __init(_ForwardIterator __first, _ForwardIterator __last);
 
     void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
@@ -1652,8 +1655,8 @@ private:
 template<class _InputIterator,
          class _CharT = typename iterator_traits<_InputIterator>::value_type,
          class _Allocator = allocator<_CharT>,
-         class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value, void>::type,
-         class = typename enable_if<__is_allocator<_Allocator>::value, void>::type
+         class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>
          >
 basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
   -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
@@ -1661,7 +1664,7 @@ basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
 template<class _CharT,
          class _Traits,
          class _Allocator = allocator<_CharT>,
-         class = typename enable_if<__is_allocator<_Allocator>::value, void>::type
+         class = _EnableIf<__is_allocator<_Allocator>::value>
          >
 explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
   -> basic_string<_CharT, _Traits, _Allocator>;
@@ -1669,14 +1672,13 @@ explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _A
 template<class _CharT,
          class _Traits,
          class _Allocator = allocator<_CharT>,
-         class = typename enable_if<__is_allocator<_Allocator>::value, void>::type,
+         class = _EnableIf<__is_allocator<_Allocator>::value>,
          class _Sz = typename allocator_traits<_Allocator>::size_type
          >
 basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
   -> basic_string<_CharT, _Traits, _Allocator>;
 #endif
 
-
 template <class _CharT, class _Traits, class _Allocator>
 inline
 void
@@ -2014,11 +2016,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _InputIterator>
-typename enable_if
+_EnableIf
 <
-    __is_exactly_cpp17_input_iterator<_InputIterator>::value,
-    void
->::type
+    __is_exactly_cpp17_input_iterator<_InputIterator>::value
+>
 basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
 {
     __zero();
@@ -2041,11 +2042,10 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _ForwardIterator>
-typename enable_if
+_EnableIf
 <
-    __is_cpp17_forward_iterator<_ForwardIterator>::value,
-    void
->::type
+    __is_cpp17_forward_iterator<_ForwardIterator>::value
+>
 basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
 {
     size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
@@ -2326,12 +2326,12 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
-typename enable_if
+_EnableIf
 <
      __is_exactly_cpp17_input_iterator <_InputIterator>::value
           || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
 {
     const basic_string __temp(__first, __last, __alloc());
@@ -2341,12 +2341,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _Input
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _ForwardIterator>
-typename enable_if
+_EnableIf
 <
     __is_cpp17_forward_iterator<_ForwardIterator>::value
          && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
 {
     size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
@@ -2378,11 +2378,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
+    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
     basic_string<_CharT, _Traits, _Allocator>&
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
 {
     __self_view __sv = __t;
@@ -2565,11 +2566,11 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-    typename enable_if
+    _EnableIf
     <
-        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
         basic_string<_CharT, _Traits, _Allocator>&
-    >::type
+    >
 basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
 {
     __self_view __sv = __t;
@@ -2654,12 +2655,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
-typename enable_if
+_EnableIf
 <
    __is_exactly_cpp17_input_iterator<_InputIterator>::value
         || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
    typename basic_string<_CharT, _Traits, _Allocator>::iterator
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -2673,12 +2674,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _ForwardIterator>
-typename enable_if
+_EnableIf
 <
     __is_cpp17_forward_iterator<_ForwardIterator>::value
         && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::iterator
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -2743,11 +2744,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
     basic_string<_CharT, _Traits, _Allocator>&
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
                                                   size_type __pos2, size_type __n)
 {
@@ -2900,11 +2901,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
-typename enable_if
+_EnableIf
 <
     __is_cpp17_input_iterator<_InputIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
                                                    _InputIterator __j1, _InputIterator __j2)
 {
@@ -2933,11 +2934,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
     basic_string<_CharT, _Traits, _Allocator>&
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
                                                    size_type __pos2, size_type __n2)
 {
@@ -3356,11 +3357,11 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::size_type
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
                                                 size_type __pos) const
 {
@@ -3414,11 +3415,11 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::size_type
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
                                                 size_type __pos) const
 {
@@ -3472,11 +3473,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::size_type
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
                                                 size_type __pos) const
 {
@@ -3530,11 +3531,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::size_type
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
                                                 size_type __pos) const
 {
@@ -3588,11 +3589,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string&
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::size_type
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
                                                 size_type __pos) const
 {
@@ -3647,11 +3648,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string&
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::size_type
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
                                                 size_type __pos) const
 {
@@ -3685,11 +3686,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     int
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const
 {
     __self_view __sv = __t;
@@ -3739,11 +3740,11 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
     int
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
                                                    const _Tp& __t) const
@@ -3764,11 +3765,12 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
-typename enable_if
+_EnableIf
 <
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
+    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
+    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
     int
->::type
+>
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
                                                    const _Tp& __t,


        


More information about the libcxx-commits mailing list