Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -5638,15 +5638,15 @@ }; #endif -#if _LIBCPP_STD_VER > 14 -template +template struct __is_allocator : false_type {}; template struct __is_allocator<_Alloc, - void_t().allocate(size_t{}))>> + typename __void_t::type, + typename __void_t().allocate(size_t(0)))>::type + > : true_type {}; -#endif _LIBCPP_END_NAMESPACE_STD Index: include/string =================================================================== --- include/string +++ include/string @@ -104,7 +104,8 @@ const Allocator& a = Allocator()); template basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17 - explicit basic_string(const basic_string_view sv, const Allocator& a = Allocator()); + template + explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17 basic_string(const value_type* s, const allocator_type& a = allocator_type()); basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); @@ -120,7 +121,8 @@ operator basic_string_view() const noexcept; basic_string& operator=(const basic_string& str); - basic_string& operator=(basic_string_view sv); + template + basic_string& operator=(const T& t); // C++17 basic_string& operator=(basic_string&& str) noexcept( allocator_type::propagate_on_container_move_assignment::value || @@ -164,13 +166,15 @@ reference at(size_type n); basic_string& operator+=(const basic_string& str); - basic_string& operator+=(basic_string_view sv); + template + basic_string& operator+=(const T& t); // C++17 basic_string& operator+=(const value_type* s); basic_string& operator+=(value_type c); basic_string& operator+=(initializer_list); basic_string& append(const basic_string& str); - basic_string& append(basic_string_view sv); + template + basic_string& append(const T& t); // C++17 basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14 template basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17 @@ -189,7 +193,8 @@ const_reference back() const; basic_string& assign(const basic_string& str); - basic_string& assign(basic_string_view sv); + template + basic_string& assign(const T& t); // C++17 basic_string& assign(basic_string&& str); basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14 template @@ -202,7 +207,8 @@ basic_string& assign(initializer_list); basic_string& insert(size_type pos1, const basic_string& str); - basic_string& insert(size_type pos1, basic_string_view sv); + template + basic_string& insert(size_type pos1, const T& t); basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n); template @@ -221,7 +227,8 @@ iterator erase(const_iterator first, const_iterator last); basic_string& replace(size_type pos1, size_type n1, const basic_string& str); - basic_string& replace(size_type pos1, size_type n1, basic_string_view sv); + template + basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17 basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos); // C++14 template @@ -231,7 +238,8 @@ basic_string& replace(size_type pos, size_type n1, const value_type* s); basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); - basic_string& replace(const_iterator i1, const_iterator i2, basic_string_view sv); + template + basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); @@ -253,45 +261,53 @@ allocator_type get_allocator() const noexcept; size_type find(const basic_string& str, size_type pos = 0) const noexcept; - size_type find(basic_string_view sv, size_type pos = 0) const noexcept; + template + size_type find(const T& t, size_type pos = 0) const; // C++17 size_type find(const value_type* s, size_type pos, size_type n) const noexcept; size_type find(const value_type* s, size_type pos = 0) const noexcept; size_type find(value_type c, size_type pos = 0) const noexcept; size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; - size_type rfind(basic_string_view sv, size_type pos = npos) const noexcept; + template + size_type rfind(const T& t, size_type pos = npos) const; // C++17 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; size_type rfind(const value_type* s, size_type pos = npos) const noexcept; size_type rfind(value_type c, size_type pos = npos) const noexcept; size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; - size_type find_first_of(basic_string_view sv, size_type pos = 0) const noexcept; + template + size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; - size_type find_last_of(basic_string_view sv, size_type pos = npos) const noexcept; + template + size_type find_last_of(const T& t, size_type pos = npos) const noexcept; // C++17 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_of(value_type c, size_type pos = npos) const noexcept; size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; - size_type find_first_not_of(basic_string_view sv, size_type pos = 0) const noexcept; + template + size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; - size_type find_last_not_of(basic_string_view sv, size_type pos = npos) const noexcept; + template + size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; int compare(const basic_string& str) const noexcept; - int compare(basic_string_view sv) const noexcept; + template + int compare(const T& t) const noexcept; // C++17 int compare(size_type pos1, size_type n1, const basic_string& str) const; - int compare(size_type pos1, size_type n1, basic_string_view sv) const; + template + int compare(size_type pos1, size_type n1, const T& t) const; // C++17 int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos) const; // C++14 template @@ -665,6 +681,7 @@ "traits_type::char_type must be the same type as CharT"); static_assert(( is_same::value), "Allocator::value_type must be same type as value_type"); + #if defined(_LIBCPP_RAW_ITERATORS) typedef pointer iterator; typedef const_pointer const_iterator; @@ -788,17 +805,26 @@ _LIBCPP_INLINE_VISIBILITY basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s); + + template ::value, nullptr_t>::type> + _LIBCPP_INLINE_VISIBILITY + basic_string(const _CharT* __s); + + template ::value, nullptr_t>::type> + _LIBCPP_INLINE_VISIBILITY + basic_string(const _CharT* __s, const _Allocator& __a); + _LIBCPP_INLINE_VISIBILITY - basic_string(const _CharT* __s, const _Allocator& __a); - _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s, size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, _CharT __c); - _LIBCPP_INLINE_VISIBILITY - basic_string(size_type __n, _CharT __c, const _Allocator& __a); + + template ::value, nullptr_t>::type> + _LIBCPP_INLINE_VISIBILITY + basic_string(size_type __n, _CharT __c, const _Allocator& __a); + basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()); _LIBCPP_INLINE_VISIBILITY @@ -809,10 +835,17 @@ basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type(), typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0); - _LIBCPP_INLINE_VISIBILITY explicit - basic_string(__self_view __sv); - _LIBCPP_INLINE_VISIBILITY - basic_string(__self_view __sv, const _Allocator& __a); + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + explicit basic_string(const _Tp& __t, + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0); + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + basic_string(const _Tp& __t, const allocator_type& __a, + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0); + template _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last); @@ -833,13 +866,12 @@ basic_string& operator=(const basic_string& __str); + template ::value, void>::type> + basic_string& operator=(const _Tp& __t) + {__self_view __sv = __t; return assign(__sv);} + #ifndef _LIBCPP_CXX03_LANG - template -#endif _LIBCPP_INLINE_VISIBILITY - basic_string& operator=(__self_view __sv) {return assign(__sv);} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY basic_string& operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); _LIBCPP_INLINE_VISIBILITY @@ -927,7 +959,15 @@ reference at(size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);} - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(__self_view __sv) {return append(__sv);} + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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;} #ifndef _LIBCPP_CXX03_LANG @@ -936,9 +976,17 @@ _LIBCPP_INLINE_VISIBILITY basic_string& append(const basic_string& __str); - _LIBCPP_INLINE_VISIBILITY - basic_string& append(__self_view __sv) { return append(__sv.data(), __sv.size()); } + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if @@ -993,9 +1041,15 @@ _LIBCPP_INLINE_VISIBILITY reference back(); _LIBCPP_INLINE_VISIBILITY const_reference back() const; + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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(__self_view __sv) { return assign(__sv.data(), __sv.size()); } - _LIBCPP_INLINE_VISIBILITY basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY @@ -1040,8 +1094,7 @@ _LIBCPP_INLINE_VISIBILITY basic_string& insert(size_type __pos1, const basic_string& __str); - _LIBCPP_INLINE_VISIBILITY - basic_string& insert(size_type __pos1, __self_view __sv) { return insert(__pos1, __sv.data(), __sv.size()); } + template _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if @@ -1049,6 +1102,16 @@ __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 + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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); @@ -1089,8 +1152,15 @@ _LIBCPP_INLINE_VISIBILITY basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); - _LIBCPP_INLINE_VISIBILITY - basic_string& replace(size_type __pos1, size_type __n1, __self_view __sv) { return replace(__pos1, __n1, __sv.data(), __sv.size()); } + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS @@ -1105,9 +1175,17 @@ basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 - basic_string& replace(const_iterator __i1, const_iterator __i2, __self_view __sv) { return replace(__i1 - begin(), __i2 - __i1, __sv); } - _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s); @@ -1154,8 +1232,15 @@ _LIBCPP_INLINE_VISIBILITY size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1163,8 +1248,15 @@ _LIBCPP_INLINE_VISIBILITY size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type rfind(__self_view __sv, size_type __pos = npos) const _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1172,8 +1264,15 @@ _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_first_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1182,8 +1281,15 @@ _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_last_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1192,8 +1298,15 @@ _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_first_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1202,8 +1315,15 @@ _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_last_not_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1212,13 +1332,29 @@ _LIBCPP_INLINE_VISIBILITY int compare(const basic_string& __str) const _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int + >::type + compare(const _Tp &__t) const; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __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 - int compare(__self_view __sv) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - int compare(size_type __pos1, size_type __n1, __self_view __sv) const; - _LIBCPP_INLINE_VISIBILITY int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const; + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -1503,6 +1639,23 @@ > basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; + +template, + class = typename enable_if<__is_allocator<_Allocator>::value, void>::type + > +explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) + -> basic_string<_CharT, _Traits, _Allocator>; + +template, + class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, + 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 @@ -1623,7 +1776,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +template basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); @@ -1634,7 +1787,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +template basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__second_tag(), __a) { @@ -1771,7 +1924,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +template basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) : __r_(__second_tag(), __a) { @@ -1826,9 +1979,11 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv) +template +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *) { + __self_view __sv = __t; __init(__sv.data(), __sv.size()); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1836,10 +1991,12 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const _Allocator& __a) +template +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a, + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *) : __r_(__second_tag(), __a) { + __self_view __sv = __t; __init(__sv.data(), __sv.size()); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -3149,11 +3306,16 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find(__self_view __sv, - size_type __pos) const _NOEXCEPT +template +typename enable_if +< + __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 { + __self_view __sv = __t; return __str_find (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3202,11 +3364,16 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::rfind(__self_view __sv, - size_type __pos) const _NOEXCEPT +template +typename enable_if +< + __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 { + __self_view __sv = __t; return __str_rfind (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3255,11 +3422,16 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_first_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template +typename enable_if +< + __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 { + __self_view __sv = __t; return __str_find_first_of (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3308,11 +3480,16 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_last_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template +typename enable_if +< + __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 { + __self_view __sv = __t; return __str_find_last_of (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3361,11 +3538,16 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template +typename enable_if +< + __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 { + __self_view __sv = __t; return __str_find_first_not_of (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3415,11 +3597,16 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template +typename enable_if +< + __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 { + __self_view __sv = __t; return __str_find_last_not_of (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3448,10 +3635,15 @@ // compare template -inline _LIBCPP_INLINE_VISIBILITY -int -basic_string<_CharT, _Traits, _Allocator>::compare(__self_view __sv) const _NOEXCEPT +template +typename enable_if +< + __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; size_t __lhs_sz = size(); size_t __rhs_sz = __sv.size(); int __result = traits_type::compare(data(), __sv.data(), @@ -3497,12 +3689,17 @@ } template -inline _LIBCPP_INLINE_VISIBILITY -int +template +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int +>::type basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, - __self_view __sv) const + const _Tp& __t) const { + __self_view __sv = __t; return compare(__pos1, __n1, __sv.data(), __sv.size()); } Index: test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp +++ test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp @@ -68,4 +68,13 @@ S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s = {"abc", 1}; + assert(s.size() == 1); + assert(s == "a"); + } +#endif } Index: test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp +++ test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp @@ -22,13 +22,6 @@ #include "test_macros.h" #include "test_allocator.h" -template -struct some_alloc -{ - typedef T value_type; - some_alloc(const some_alloc&); -}; - int main() { { @@ -40,7 +33,7 @@ static_assert(std::is_nothrow_default_constructible::value, ""); } { - typedef std::basic_string, some_alloc> C; + typedef std::basic_string, limited_allocator> C; static_assert(!std::is_nothrow_default_constructible::value, ""); } } Index: test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp +++ test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp @@ -20,11 +20,12 @@ #include "test_allocator.h" template -struct some_alloc +struct throwing_alloc { typedef T value_type; - some_alloc(const some_alloc&); - ~some_alloc() noexcept(false); + throwing_alloc(const throwing_alloc&); + T *allocate(size_t); + ~throwing_alloc() noexcept(false); }; // Test that it's possible to take the address of basic_string's destructors @@ -44,7 +45,7 @@ } #if defined(_LIBCPP_VERSION) { - typedef std::basic_string, some_alloc> C; + typedef std::basic_string, throwing_alloc> C; static_assert(!std::is_nothrow_destructible::value, ""); } #endif // _LIBCPP_VERSION Index: test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp +++ test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp @@ -36,7 +36,7 @@ // (2) basic_string(A const&) - BROKEN // (3) basic_string(size_type, CharT, const A& = A()) // (4) basic_string(BS const&, size_type, A const& = A()) -// (5) basic_string(BS const&, size_type, size_type, A const& = A()) - PARTIALLY BROKEN +// (5) basic_string(BS const&, size_type, size_type, A const& = A()) // (6) basic_string(const CharT*, size_type, A const& = A()) // (7) basic_string(const CharT*, A const& = A()) // (8) basic_string(InputIt, InputIt, A const& = A()) - BROKEN @@ -46,7 +46,7 @@ // (12) basic_string(BS&&, A const&) // (13) basic_string(initializer_list, A const& = A()) // (14) basic_string(BSV, A const& = A()) -// (15) basic_string(const T&, size_type, size_type, A const& = A()) - BROKEN +// (15) basic_string(const T&, size_type, size_type, A const& = A()) int main() { using TestSizeT = test_allocator::size_type; @@ -106,7 +106,6 @@ assert(w == L"def"); } { // Testing (5) w/o allocator -#if 0 // FIXME: This doesn't work const std::string sin("abc"); std::basic_string s(sin, (size_t)1, (size_t)3); ASSERT_SAME_TYPE(decltype(s), std::string); @@ -119,7 +118,6 @@ std::basic_string w(win, (TestSizeT)2, (TestSizeT)3); ASSERT_SAME_TYPE(decltype(w), WStr); assert(w == L"cde"); -#endif } { // Testing (5) w/ allocator const std::string sin("abc"); @@ -178,21 +176,20 @@ assert(w == L"abcdef"); } { // (8) w/o allocator - // This overload isn't compatible with implicit deduction guides as - // specified in the standard. - // FIXME: Propose adding an explicit guide to the standard? - } - { // (8) w/ allocator - // This overload isn't compatible with implicit deduction guides as - // specified in the standard. - // FIXME: Propose adding an explicit guide to the standard? -#if 0 using It = input_iterator; const char* input = "abcdef"; std::basic_string s(It(input), It(input + 3), std::allocator{}); ASSERT_SAME_TYPE(decltype(s), std::string); -#endif + assert(s == "abc"); } + { // (8) w/ allocator + using ExpectW = std::basic_string, test_allocator>; + using It = input_iterator; + const wchar_t* input = L"abcdef"; + std::basic_string s(It(input), It(input + 3), test_allocator{}); + ASSERT_SAME_TYPE(decltype(s), ExpectW); + assert(s == L"abc"); + } { // Testing (9) const std::string sin("abc"); std::basic_string s(sin); @@ -293,8 +290,28 @@ ASSERT_SAME_TYPE(decltype(w), ExpectW); assert(w == L"abcdef"); } - { // Testing (15) - // This overload isn't compatible with implicit deduction guides as - // specified in the standard. + { // Testing (15) w/o allocator + std::string s0("abc"); + std::basic_string s(s0, 1, 1); + ASSERT_SAME_TYPE(decltype(s), std::string); + assert(s == "b"); + + std::wstring w0(L"abcdef"); + std::basic_string w(w0, 2, 2); + ASSERT_SAME_TYPE(decltype(w), std::wstring); + assert(w == L"cd"); } + { // Testing (15) w/ allocator + using ExpectS = std::basic_string, test_allocator>; + ExpectS s0("abc"); + std::basic_string s(s0, 1, 1, test_allocator{4}); + ASSERT_SAME_TYPE(decltype(s), ExpectS); + assert(s == "b"); + + using ExpectW = std::basic_string, test_allocator>; + ExpectW w0(L"abcdef"); + std::basic_string w(w0, 2, 2, test_allocator{6}); + ASSERT_SAME_TYPE(decltype(w), ExpectW); + assert(w == L"cd"); + } } Index: test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp +++ test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp @@ -32,6 +32,7 @@ { typedef T value_type; some_alloc(const some_alloc&); + T *allocate(size_t); }; template @@ -41,6 +42,7 @@ some_alloc2() {} some_alloc2(const some_alloc2&); + T *allocate(size_t); void deallocate(void*, unsigned) {} typedef std::false_type propagate_on_container_move_assignment; @@ -54,6 +56,7 @@ some_alloc3() {} some_alloc3(const some_alloc3&); + T *allocate(size_t); void deallocate(void*, unsigned) {} typedef std::false_type propagate_on_container_move_assignment; Index: test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp +++ test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp @@ -22,13 +22,6 @@ #include "test_macros.h" #include "test_allocator.h" -template -struct some_alloc -{ - typedef T value_type; - some_alloc(const some_alloc&); -}; - int main() { { @@ -40,7 +33,7 @@ static_assert(std::is_nothrow_move_constructible::value, ""); } { - typedef std::basic_string, some_alloc> C; + typedef std::basic_string, limited_allocator> C; #if TEST_STD_VER <= 14 static_assert(!std::is_nothrow_move_constructible::value, ""); #else Index: test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp +++ test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp @@ -83,4 +83,12 @@ test("123456798012345679801234567980123456798012345679801234567980", 60, A()); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s({"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } Index: test/std/strings/basic.string/string.cons/string_view_deduction.fail.cpp =================================================================== --- test/std/strings/basic.string/string.cons/string_view_deduction.fail.cpp +++ test/std/strings/basic.string/string.cons/string_view_deduction.fail.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// XFAIL: libcpp-no-deduction-guides + +// template +// basic_string(InputIterator begin, InputIterator end, +// const Allocator& a = Allocator()); + +// template +// > +// basic_string(basic_string_view, const Allocator& = Allocator()) +// -> basic_string; +// +// The deduction guide shall not participate in overload resolution if Allocator +// is a type that does not qualify as an allocator. + + +#include +#include +#include +#include +#include + +int main() +{ + { + std::string_view sv = "12345678901234"; + std::basic_string s1{sv, 23}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}} + } +} Index: test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp +++ test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// XFAIL: libcpp-no-deduction-guides + +// template +// basic_string(InputIterator begin, InputIterator end, +// const Allocator& a = Allocator()); + +// template +// > +// basic_string(basic_string_view, const Allocator& = Allocator()) +// -> basic_string; +// +// The deduction guide shall not participate in overload resolution if Allocator +// is a type that does not qualify as an allocator. + + +#include +#include +#include +#include +#include +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "../input_iterator.h" +#include "min_allocator.h" + +int main() +{ + { + std::string_view sv = "12345678901234"; + std::basic_string s1(sv); + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == sv.size()); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + + { + std::string_view sv = "12345678901234"; + std::basic_string s1{sv, std::allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == sv.size()); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + { + std::wstring_view sv = L"12345678901234"; + std::basic_string s1{sv, test_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == sv.size()); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + { + std::u16string_view sv = u"12345678901234"; + std::basic_string s1{sv, min_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == sv.size()); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + { + std::u32string_view sv = U"12345678901234"; + std::basic_string s1{sv, explicit_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == sv.size()); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } +} Index: test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp =================================================================== --- test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp +++ test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// XFAIL: libcpp-no-deduction-guides + +// template +// basic_string(InputIterator begin, InputIterator end, +// const Allocator& a = Allocator()); + +// template +// > +// basic_string(basic_string_view, +// typename see below::size_type, +// typename see below::size_type, +// const Allocator& = Allocator()) +// -> basic_string; +// +// A size_type parameter type in a basic_string deduction guide refers to the size_type +// member type of the type deduced by the deduction guide. +// +// The deduction guide shall not participate in overload resolution if Allocator +// is a type that does not qualify as an allocator. + + +#include +#include +#include +#include +#include + +int main() +{ + { + std::string_view sv = "12345678901234"; + std::basic_string s1{sv, 0, 4, 23}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}} + } +} Index: test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp +++ test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// XFAIL: libcpp-no-deduction-guides + +// template +// basic_string(InputIterator begin, InputIterator end, +// const Allocator& a = Allocator()); + +// template +// > +// basic_string(basic_string_view, +// typename see below::size_type, +// typename see below::size_type, +// const Allocator& = Allocator()) +// -> basic_string; +// +// A size_type parameter type in a basic_string deduction guide refers to the size_type +// member type of the type deduced by the deduction guide. +// +// The deduction guide shall not participate in overload resolution if Allocator +// is a type that does not qualify as an allocator. + + +#include +#include +#include +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "../input_iterator.h" +#include "min_allocator.h" + +int main() +{ + { + std::string_view sv = "12345678901234"; + std::basic_string s1{sv, 0, 4}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == 4); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + + { + std::string_view sv = "12345678901234"; + std::basic_string s1{sv, 0, 4, std::allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == 4); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + { + std::wstring_view sv = L"12345678901234"; + std::basic_string s1{sv, 0, 4, test_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == 4); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + { + std::u16string_view sv = u"12345678901234"; + std::basic_string s1{sv, 0, 4, min_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == 4); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } + { + std::u32string_view sv = U"12345678901234"; + std::basic_string s1{sv, 0, 4, explicit_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == 4); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } +} Index: test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp @@ -77,4 +77,13 @@ S("1234567890123456789012345678901234567890")); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s.append({"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } Index: test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp @@ -218,4 +218,13 @@ test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), S("can't happen")); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s.insert(0, {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } Index: test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp @@ -77,4 +77,13 @@ S("1234567890123456789012345678901234567890")); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s += {"abc", 1}; + assert(s.size() == 1); + assert(s == "a"); + } +#endif } Index: test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp @@ -281,4 +281,13 @@ test2(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " "; + s.replace(s.cbegin(), s.cend(), {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } Index: test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp @@ -379,4 +379,13 @@ test2(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " "; + s.replace(0, 1, {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } Index: test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp =================================================================== --- test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp +++ test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp @@ -35,8 +35,8 @@ some_alloc() {} some_alloc(const some_alloc&); + T *allocate(size_t); void deallocate(void*, unsigned) {} - typedef std::true_type propagate_on_container_swap; }; @@ -47,6 +47,7 @@ some_alloc2() {} some_alloc2(const some_alloc2&); + T *allocate(size_t); void deallocate(void*, unsigned) {} typedef std::false_type propagate_on_container_swap; Index: test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp +++ test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp @@ -15,10 +15,9 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" -#include "test_macros.h" - int sign(int x) { if (x == 0) @@ -378,4 +377,11 @@ test2(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.compare(0, 1, {"abc", 1}) < 0); + } +#endif } Index: test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp +++ test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" int sign(int x) @@ -74,4 +75,11 @@ test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), 0); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.compare({"abc", 1}) < 0); + } +#endif } Index: test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" template @@ -154,4 +155,11 @@ test1(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_first_not_of({"abc", 1}) == 0); + } +#endif } Index: test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" template @@ -154,4 +155,11 @@ test1(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_first_of({"abc", 1}) == std::string::npos); + } +#endif } Index: test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" template @@ -154,4 +155,11 @@ test1(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_last_not_of({"abc", 1}) == s.size() - 1); + } +#endif } Index: test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" template @@ -154,4 +155,11 @@ test1(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_last_of({"abc", 1}) == std::string::npos); + } +#endif } Index: test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" template @@ -154,4 +155,11 @@ test1(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find({"abc", 1}) == std::string::npos); + } +#endif } Index: test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "test_macros.h" #include "min_allocator.h" template @@ -154,4 +155,11 @@ test1(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.rfind({"abc", 1}) == std::string::npos); + } +#endif }