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()); 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()); @@ -164,13 +165,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); 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); 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 +192,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); 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 +206,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 +226,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); 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 +237,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); 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 +260,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 noexcept; 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; 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; 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; 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; 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; 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; 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; int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos) const; // C++14 template @@ -807,10 +822,15 @@ 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& __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); @@ -831,13 +851,16 @@ basic_string& operator=(const basic_string& __str); + template + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + operator=(const _Tp& __t) {return assign(__t);} + #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 @@ -925,7 +948,16 @@ 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) {return append(__t);} + _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 @@ -934,8 +966,15 @@ _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); basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); template _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS @@ -991,9 +1030,16 @@ _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); + _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 @@ -1038,8 +1084,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 @@ -1047,6 +1092,15 @@ __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& >::type + insert(size_type __pos1, const _Tp& __t); + + 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); @@ -1087,8 +1141,16 @@ _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); + 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 @@ -1103,9 +1165,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); + _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); @@ -1152,8 +1222,14 @@ _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; @@ -1161,8 +1237,14 @@ _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; @@ -1170,8 +1252,14 @@ _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; @@ -1180,8 +1268,14 @@ _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; @@ -1190,8 +1284,14 @@ _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; @@ -1200,8 +1300,14 @@ _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; @@ -1210,11 +1316,23 @@ _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 @@ -1824,9 +1942,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); @@ -1834,10 +1954,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); @@ -2204,6 +2326,19 @@ __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string<_CharT, _Traits, _Allocator>& >::type +basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t) +{ + __self_view __sv = __t; + return assign(__sv.data(), __sv.size()); +} + +template +template +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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; @@ -2374,6 +2509,19 @@ __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string<_CharT, _Traits, _Allocator>& >::type +basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t) +{ + __self_view __sv = __t; + return append(__sv.data(), __sv.size()); +} + +template +template + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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; @@ -2552,6 +2700,19 @@ __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string<_CharT, _Traits, _Allocator>& >::type +basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t) +{ + __self_view __sv = __t; + return insert(__pos1, __sv.data(), __sv.size()); +} + +template +template +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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) { @@ -2742,6 +2903,19 @@ __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string<_CharT, _Traits, _Allocator>& >::type +basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t) +{ + __self_view __sv = __t; + return replace(__pos1, __n1, __sv.data(), __sv.size()); +} + +template +template +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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) { @@ -2770,6 +2944,19 @@ } template +template +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string<_CharT, _Traits, _Allocator>& +>::type +basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) +{ + __self_view __sv = __t; + return replace(__i1 - begin(), __i2 - __i1, __sv); +} + +template inline _LIBCPP_INLINE_VISIBILITY basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) @@ -3148,11 +3335,15 @@ } 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()); } @@ -3201,11 +3392,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()); } @@ -3254,11 +3450,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()); } @@ -3307,11 +3508,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()); } @@ -3360,11 +3566,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()); } @@ -3414,11 +3625,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()); } @@ -3447,10 +3663,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(), @@ -3496,12 +3717,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()); } @@ -4092,6 +4318,20 @@ } #endif +#if _LIBCPP_STD_VER > 14 +template + explicit basic_string(basic_string_view<_CharT, _Traits>) + -> basic_string<_CharT, _Traits, std::allocator<_CharT>>; + +template::value, void>::type + > + explicit basic_string(basic_string_view<_CharT, _Traits>, const _Alloc &) + -> basic_string<_CharT, _Traits, _Alloc>; +#endif + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS Index: test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp +++ test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp @@ -48,6 +48,10 @@ static_assert(std::is_same_v>, ""); assert(s1.size() == 10); assert(s1.compare(0, s1.size(), s, s1.size()) == 0); + + std::string s2(s, s+10); // Can't use {} here + static_assert(std::is_same_v, ""); + assert(s1 == s2); } { Index: test/std/strings/basic.string/string.cons/string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/string_view.pass.cpp +++ test/std/strings/basic.string/string.cons/string_view.pass.cpp @@ -107,5 +107,10 @@ test(SV("123456798012345679801234567980123456798012345679801234567980")); test(SV("123456798012345679801234567980123456798012345679801234567980"), A()); } +// LWG 2946 + { + std::string s({"abc", 1}); + assert(s.size() == 1); + } #endif } Index: test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp +++ test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp @@ -70,5 +70,11 @@ "1234567890123456789012345678901234567890123456789012345678901234567890"), SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); } +// LWG 2946 + { + std::string s; + s = {"abc", 1}; + assert(s.size() == 1); + } #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,44 @@ +//===----------------------------------------------------------------------===// +// +// 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(basic_string_view<_CharT, _Traits>) +// -> basic_string<_CharT, _Traits, allocator<_CharT>>; +// +// template +// basic_string(basic_string_view<_CharT, _Traits>, const _Alloc &) +// -> basic_string<_CharT, _Traits, _Alloc>; +// +// The second 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" + +using namespace std::literals; + +template +struct NotAnAllocator { typedef T value_type; }; + +int main() +{ + { // Not an allocator + std::basic_string s1{L"12345678901234"sv, NotAnAllocator{}}; // 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,93 @@ +//===----------------------------------------------------------------------===// +// +// 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(basic_string_view<_CharT, _Traits>) +// -> basic_string<_CharT, _Traits, allocator<_CharT>>; +// +// template +// basic_string(basic_string_view<_CharT, _Traits>, const _Alloc &) +// -> basic_string<_CharT, _Traits, _Alloc>; +// +// The second 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" + +using namespace std::literals; + +int main() +{ + { + auto sv = "12345678901234"sv; + 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(sv) == 0); + } + + { + auto sv = "12345678901234"sv; + 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(sv) == 0); + } + { + auto sv = L"12345678901234"sv; + 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(sv) == 0); + } + + { + auto sv = u"12345678901234"sv; + 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(sv) == 0); + } + { + auto sv = U"12345678901234"sv; + 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(sv) == 0); + } +} Index: test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp @@ -79,5 +79,11 @@ test(S("12345678901234567890"), SV("12345678901234567890"), S("1234567890123456789012345678901234567890")); } +// LWG 2946 + { + std::string s; + s.append({"abc", 1}); + assert(s.size() == 1); + } #endif } Index: test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp @@ -101,5 +101,11 @@ testAlloc(S(), SV("1234567890"), min_allocator()); testAlloc(S(), SV("12345678901234567890"), min_allocator()); } +// LWG 2946 + { + std::string s; + s.assign({"abc", 1}); + assert(s.size() == 1); + } #endif } Index: test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp @@ -219,6 +219,13 @@ test(S("abcdefghijklmnopqrst"), 21, SV("1234567890"), S("can't happen")); test(S("abcdefghijklmnopqrst"), 21, SV("12345678901234567890"), S("can't happen")); } + +// LWG 2946 + { + std::string s; + s.insert(0, {"abc", 1}); + assert(s.size() == 1); + } #endif { // test inserting into self 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 @@ -76,5 +76,11 @@ test(S("12345678901234567890"), S("12345678901234567890"), S("1234567890123456789012345678901234567890")); } +// LWG 2946 + { + std::string s; + s += {"abc", 1}; + assert(s.size() == 1); + } #endif } Index: test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp @@ -282,5 +282,11 @@ test1(); test2(); } +// LWG 2946 + { + std::string s; + s.replace(s.cbegin(), s.cbegin(), {"abc", 1}); + assert(s.size() == 1); + } #endif } Index: test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp +++ test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp @@ -380,5 +380,11 @@ test1(); test2(); } +// LWG 2946 + { + std::string s; + s.replace(0, 1, {"abc", 1}); + assert(s.size() == 1); + } #endif } Index: test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp +++ test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp @@ -379,5 +379,10 @@ test1(); test2(); } +// 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_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp +++ test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp @@ -75,5 +75,10 @@ test(S("abcdefghijklmnopqrst"), SV("abcdefghij"), 10); test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), 0); } +// 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_view_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.first.not.of/string_view_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.first.not.of/string_view_size.pass.cpp @@ -155,5 +155,10 @@ test0(); test1(); } +// LWG 2946 + { + std::string s; + assert(s.find_first_not_of({"abc", 1}) == std::string::npos); + } #endif } Index: test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp @@ -155,5 +155,10 @@ test0(); test1(); } +// 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_view_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp @@ -155,5 +155,10 @@ // test0(); // test1(); } +// LWG 2946 + { + std::string s; + assert(s.find_last_not_of({"abc", 1}) == std::string::npos); + } #endif } Index: test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp @@ -155,5 +155,10 @@ test0(); test1(); } +// 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_view_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp @@ -155,5 +155,10 @@ test0(); test1(); } +// 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_view_size.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp +++ test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp @@ -155,5 +155,10 @@ test0(); test1(); } +// LWG 2946 + { + std::string s; + assert(s.rfind({"abc", 1}) == std::string::npos); + } #endif }