Index: include/bits/basic_string.h =================================================================== --- include/bits/basic_string.h (revision 250685) +++ include/bits/basic_string.h (working copy) @@ -117,6 +117,23 @@ __and_, __not_>>::value, _Res>; + + // Performs an implicit conversion from _Tp to __sv_type. + template + static __sv_type _S_to_string_view(const _Tp& __svt) + { + return __svt; + } + + // Wraps a string_view by explicit conversion and thus + // allows to add an internal constructor that does not + // participate in overload resolution when a string_view + // is provided. + struct __sv_wrapper + { + explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) {} + __sv_type _M_sv; + }; #endif // Use empty-base optimization: http://www.cantrip.org/emptyopt.html @@ -593,7 +610,7 @@ #if __cplusplus > 201402L /** * @brief Construct string from a substring of a string_view. - * @param __t Source string view. + * @param __t Source object convertible to string view. * @param __pos The index of the first character to copy from __t. * @param __n The number of characters to copy from __t. * @param __a Allocator to use. @@ -601,16 +618,27 @@ template> basic_string(const _Tp& __t, size_type __pos, size_type __n, const _Alloc& __a = _Alloc()) - : basic_string(__sv_type(__t).substr(__pos, __n), __a) { } - + : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { } + /** * @brief Construct string from a string_view. - * @param __sv Source string view. + * @param __t Source object convertible to string view. * @param __a Allocator to use (default is default allocator). */ + template> explicit - basic_string(__sv_type __sv, const _Alloc& __a = _Alloc()) - : basic_string(__sv.data(), __sv.size(), __a) { } + basic_string(const _Tp& __t, const _Alloc& __a = _Alloc()) + : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { } + + /** + * @brief Only internally used: Construct string from a string view + * wrapper. + * @param __svw string view wrapper. + * @param __a Allocator to use. + */ + explicit + basic_string(__sv_wrapper __svw, const _Alloc& __a) + : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { } #endif // C++17 /** @@ -756,12 +784,12 @@ #if __cplusplus > 201402L /** * @brief Set value to string constructed from a string_view. - * @param __sv A string_view. + * @param __svt An object convertible to string_view. */ - template - _If_sv<_Tp, basic_string&> - operator=(_Tp __sv) - { return this->assign(__sv); } + template + _If_sv<_Tp, basic_string&> + operator=(const _Tp& __svt) + { return this->assign(__svt); } /** * @brief Convert to a string_view. @@ -1157,12 +1185,13 @@ #if __cplusplus > 201402L /** * @brief Append a string_view. - * @param __sv The string_view to be appended. + * @param __svt An object convertible to string_view to be appended. * @return Reference to this string. */ - basic_string& - operator+=(__sv_type __sv) - { return this->append(__sv); } + template + _If_sv<_Tp, basic_string&> + operator+=(const _Tp& __svt) + { return this->append(__svt); } #endif // C++17 /** @@ -1265,29 +1294,33 @@ #if __cplusplus > 201402L /** * @brief Append a string_view. - * @param __sv The string_view to be appended. + * @param __svt An object convertible to string_view to be appended. * @return Reference to this string. */ - basic_string& - append(__sv_type __sv) - { return this->append(__sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + append(const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->append(__sv.data(), __sv.size()); + } /** * @brief Append a range of characters from a string_view. - * @param __sv The string_view to be appended from. + * @param __svt An object convertible to string_view to be appended from. * @param __pos The position in the string_view to append from. * @param __n The number of characters to append from the string_view. * @return Reference to this string. */ template - _If_sv<_Tp, basic_string&> - append(const _Tp& __svt, size_type __pos, size_type __n = npos) - { - __sv_type __sv = __svt; - return _M_append(__sv.data() + _If_sv<_Tp, basic_string&> + append(const _Tp& __svt, size_type __pos, size_type __n = npos) + { + __sv_type __sv = __svt; + return _M_append(__sv.data() + __sv._M_check(__pos, "basic_string::append"), __sv._M_limit(__pos, __n)); - } + } #endif // C++17 /** @@ -1433,29 +1466,33 @@ #if __cplusplus > 201402L /** * @brief Set value from a string_view. - * @param __sv The source string_view. + * @param __svt The source object convertible to string_view. * @return Reference to this string. */ - basic_string& - assign(__sv_type __sv) - { return this->assign(__sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + assign(const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->assign(__sv.data(), __sv.size()); + } /** * @brief Set value from a range of characters in a string_view. - * @param __sv The source string_view. + * @param __svt The source object convertible to string_view. * @param __pos The position in the string_view to assign from. * @param __n The number of characters to assign. * @return Reference to this string. */ - template - _If_sv<_Tp, basic_string&> - assign(const _Tp& __svt, size_type __pos, size_type __n = npos) - { - __sv_type __sv = __svt; - return _M_replace(size_type(0), this->size(), __sv.data() + template + _If_sv<_Tp, basic_string&> + assign(const _Tp& __svt, size_type __pos, size_type __n = npos) + { + __sv_type __sv = __svt; + return _M_replace(size_type(0), this->size(), __sv.data() + __sv._M_check(__pos, "basic_string::assign"), __sv._M_limit(__pos, __n)); - } + } #endif // C++17 #if __cplusplus >= 201103L @@ -1692,32 +1729,36 @@ /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. - * @param __sv The string_view to insert. + * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ - basic_string& - insert(size_type __pos, __sv_type __sv) - { return this->insert(__pos, __sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + insert(size_type __pos, const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->insert(__pos, __sv.data(), __sv.size()); + } /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. - * @param __sv The string_view to insert from. + * @param __svt The object convertible to string_view to insert from. * @param __pos Iterator referencing position in string_view to insert * from. * @param __n The number of characters to insert. * @return Reference to this string. */ - template - _If_sv<_Tp, basic_string&> - insert(size_type __pos1, const _Tp& __svt, + template + _If_sv<_Tp, basic_string&> + insert(size_type __pos1, const _Tp& __svt, size_type __pos2, size_type __n = npos) - { - __sv_type __sv = __svt; - return this->replace(__pos1, size_type(0), __sv.data() + { + __sv_type __sv = __svt; + return this->replace(__pos1, size_type(0), __sv.data() + __sv._M_check(__pos2, "basic_string::insert"), __sv._M_limit(__pos2, __n)); - } + } #endif // C++17 /** @@ -2120,32 +2161,36 @@ * @brief Replace range of characters with string_view. * @param __pos The position to replace at. * @param __n The number of characters to replace. - * @param __sv The string_view to insert. + * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ - basic_string& - replace(size_type __pos, size_type __n, __sv_type __sv) - { return this->replace(__pos, __n, __sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + replace(size_type __pos, size_type __n, const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->replace(__pos, __n, __sv.data(), __sv.size()); + } /** * @brief Replace range of characters with string_view. * @param __pos1 The position to replace at. * @param __n1 The number of characters to replace. - * @param __sv The string_view to insert from. + * @param __svt The object convertible to string_view to insert from. * @param __pos2 The position in the string_view to insert from. * @param __n2 The number of characters to insert. * @return Reference to this string. */ - template - _If_sv<_Tp, basic_string&> - replace(size_type __pos1, size_type __n1, const _Tp& __svt, + template + _If_sv<_Tp, basic_string&> + replace(size_type __pos1, size_type __n1, const _Tp& __svt, size_type __pos2, size_type __n2 = npos) - { - __sv_type __sv = __svt; - return this->replace(__pos1, __n1, __sv.data() + { + __sv_type __sv = __svt; + return this->replace(__pos1, __n1, __sv.data() + __sv._M_check(__pos2, "basic_string::replace"), __sv._M_limit(__pos2, __n2)); - } + } /** * @brief Replace range of characters with string_view. @@ -2153,12 +2198,16 @@ to replace at. * @param __i2 An iterator referencing the end position for the replace. - * @param __sv The string_view to insert from. + * @param __svt The object convertible to string_view to insert from. * @return Reference to this string. */ - basic_string& - replace(const_iterator __i1, const_iterator __i2, __sv_type __sv) - { return this->replace(__i1 - begin(), __i2 - __i1, __sv); } + template + _If_sv<_Tp, basic_string&> + replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->replace(__i1 - begin(), __i2 - __i1, __sv); + } #endif // C++17 private: @@ -2288,13 +2337,18 @@ #if __cplusplus > 201402L /** * @brief Find position of a string_view. - * @param __sv The string_view to locate. + * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. */ - size_type - find(__sv_type __sv, size_type __pos = 0) const noexcept - { return this->find(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find(const _Tp& __svt, size_type __pos = 0) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -2345,13 +2399,18 @@ #if __cplusplus > 201402L /** * @brief Find last position of a string_view. - * @param __sv The string_view to locate. + * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search back from (default end). * @return Index of start of last occurrence. */ - size_type - rfind(__sv_type __sv, size_type __pos = npos) const noexcept - { return this->rfind(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + rfind(const _Tp& __svt, size_type __pos = npos) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->rfind(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -2419,13 +2478,19 @@ #if __cplusplus > 201402L /** * @brief Find position of a character of a string_view. - * @param __sv A string_view containing characters to locate. + * @param __svt An object convertible to string_view containing + * characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ - size_type - find_first_of(__sv_type __sv, size_type __pos = 0) const noexcept - { return this->find_first_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_first_of(const _Tp& __svt, size_type __pos = 0) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_first_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -2497,13 +2562,19 @@ #if __cplusplus > 201402L /** * @brief Find last position of a character of string. - * @param __sv A string_view containing characters to locate. + * @param __svt An object convertible to string_view containing + * characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ - size_type - find_last_of(__sv_type __sv, size_type __pos = npos) const noexcept - { return this->find_last_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_last_of(const _Tp& __svt, size_type __pos = npos) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_last_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -2574,13 +2645,19 @@ #if __cplusplus > 201402L /** * @brief Find position of a character not in a string_view. - * @param __sv A string_view containing characters to avoid. + * @param __svt A object convertible to string_view containing characters + * to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ - size_type - find_first_not_of(__sv_type __sv, size_type __pos = 0) const noexcept - { return this->find_first_not_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_first_not_of(const _Tp& __svt, size_type __pos = 0) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_first_not_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -2650,13 +2727,19 @@ #if __cplusplus > 201402L /** * @brief Find last position of a character not in a string_view. - * @param __sv A string_view containing characters to avoid. + * @param __svt An object convertible to string_view containing + * characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ - size_type - find_last_not_of(__sv_type __sv, size_type __pos = npos) const noexcept - { return this->find_last_not_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_last_not_of(const _Tp& __svt, size_type __pos = npos) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_last_not_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -2754,12 +2837,14 @@ #if __cplusplus > 201402L /** * @brief Compare to a string_view. - * @param __sv A string_view to compare against. + * @param __svt An object convertible to string_view to compare against. * @return Integer < 0, 0, or > 0. */ - int - compare(__sv_type __sv) const + template + _If_sv<_Tp, int> + compare(const _Tp& __svt) const noexcept(is_same<_Tp, __sv_type>::value) { + __sv_type __sv = __svt; const size_type __size = this->size(); const size_type __osize = __sv.size(); const size_type __len = std::min(__size, __osize); @@ -2774,18 +2859,24 @@ * @brief Compare to a string_view. * @param __pos A position in the string to start comparing from. * @param __n The number of characters to compare. - * @param __sv A string_view to compare against. + * @param __svt An object convertible to string_view to compare + * against. * @return Integer < 0, 0, or > 0. */ - int - compare(size_type __pos, size_type __n, __sv_type __sv) const - { return __sv_type(*this).substr(__pos, __n).compare(__sv); } + template + _If_sv<_Tp, int> + compare(size_type __pos, size_type __n, const _Tp& __svt) const + { + __sv_type __sv = __svt; + return __sv_type(*this).substr(__pos, __n).compare(__sv); + } /** * @brief Compare to a string_view. * @param __pos1 A position in the string to start comparing from. * @param __n1 The number of characters to compare. - * @param __sv A string_view to compare against. + * @param __svt An object convertible to string_view to compare + * against. * @param __pos2 A position in the string_view to start comparing from. * @param __n2 The number of characters to compare. * @return Integer < 0, 0, or > 0. @@ -3348,6 +3439,23 @@ __and_, __not_>>::value, _Res>; + + // Performs an implicit conversion from _Tp to __sv_type. + template + static __sv_type _S_to_string_view(const _Tp& __svt) + { + return __svt; + } + + // Wraps a string_view by explicit conversion and thus + // allows to add an internal constructor that does not + // participate in overload resolution when a string_view + // is provided. + struct __sv_wrapper + { + explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) {} + __sv_type _M_sv; + }; #endif public: @@ -3474,24 +3582,35 @@ #if __cplusplus > 201402L /** * @brief Construct string from a substring of a string_view. - * @param __t Source string view. + * @param __t Source object convertible to string view. * @param __pos The index of the first character to copy from __t. * @param __n The number of characters to copy from __t. * @param __a Allocator to use. */ - template> + template> basic_string(const _Tp& __t, size_type __pos, size_type __n, const _Alloc& __a = _Alloc()) - : basic_string(__sv_type(__t).substr(__pos, __n), __a) { } - + : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { } + /** * @brief Construct string from a string_view. - * @param __sv Source string view. + * @param __t Source object convertible to string view. * @param __a Allocator to use (default is default allocator). */ + template> explicit - basic_string(__sv_type __sv, const _Alloc& __a = _Alloc()) - : basic_string(__sv.data(), __sv.size(), __a) { } + basic_string(const _Tp& __t, const _Alloc& __a = _Alloc()) + : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { } + + /** + * @brief Only internally used: Construct string from a string view + * wrapper. + * @param __svw string view wrapper. + * @param __a Allocator to use. + */ + explicit + basic_string(__sv_wrapper __svw, const _Alloc& __a) + : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { } #endif // C++17 /** @@ -3562,12 +3681,12 @@ #if __cplusplus > 201402L /** * @brief Set value to string constructed from a string_view. - * @param __sv A string_view. + * @param __svt An object convertible to string_view. */ - template - _If_sv<_Tp, basic_string&> - operator=(_Tp __sv) - { return this->assign(__sv); } + template + _If_sv<_Tp, basic_string&> + operator=(const _Tp& __svt) + { return this->assign(__svt); } /** * @brief Convert to a string_view. @@ -3984,12 +4103,13 @@ #if __cplusplus > 201402L /** * @brief Append a string_view. - * @param __sv The string_view to be appended. + * @param __svt The object convertible to string_view to be appended. * @return Reference to this string. */ - basic_string& - operator+=(__sv_type __sv) - { return this->append(__sv); } + template + _If_sv<_Tp, basic_string&> + operator+=(const _Tp& __svt) + { return this->append(__svt); } #endif // C++17 /** @@ -4075,16 +4195,21 @@ #if __cplusplus > 201402L /** * @brief Append a string_view. - * @param __sv The string_view to be appended. + * @param __svt The object convertible to string_view to be appended. * @return Reference to this string. */ - basic_string& - append(__sv_type __sv) - { return this->append(__sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + append(const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->append(__sv.data(), __sv.size()); + } /** * @brief Append a range of characters from a string_view. - * @param __sv The string_view to be appended from. + * @param __svt The object convertible to string_view to be appended + * from. * @param __pos The position in the string_view to append from. * @param __n The number of characters to append from the string_view. * @return Reference to this string. @@ -4228,16 +4353,20 @@ #if __cplusplus > 201402L /** * @brief Set value from a string_view. - * @param __sv The source string_view. + * @param __svt The source object convertible to string_view. * @return Reference to this string. */ - basic_string& - assign(__sv_type __sv) - { return this->assign(__sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + assign(const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->assign(__sv.data(), __sv.size()); + } /** * @brief Set value from a range of characters in a string_view. - * @param __sv The source string_view. + * @param __svt The source object convertible to string_view. * @param __pos The position in the string_view to assign from. * @param __n The number of characters to assign. * @return Reference to this string. @@ -4432,17 +4561,21 @@ /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. - * @param __sv The string_view to insert. + * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ - basic_string& - insert(size_type __pos, __sv_type __sv) - { return this->insert(__pos, __sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + insert(size_type __pos, const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->insert(__pos, __sv.data(), __sv.size()); + } /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. - * @param __sv The string_view to insert from. + * @param __svt The object convertible to string_view to insert from. * @param __pos Iterator referencing position in string_view to insert * from. * @param __n The number of characters to insert. @@ -4819,18 +4952,22 @@ * @brief Replace range of characters with string_view. * @param __pos The position to replace at. * @param __n The number of characters to replace. - * @param __sv The string_view to insert. + * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ - basic_string& - replace(size_type __pos, size_type __n, __sv_type __sv) - { return this->replace(__pos, __n, __sv.data(), __sv.size()); } + template + _If_sv<_Tp, basic_string&> + replace(size_type __pos, size_type __n, const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->replace(__pos, __n, __sv.data(), __sv.size()); + } /** * @brief Replace range of characters with string_view. * @param __pos1 The position to replace at. * @param __n1 The number of characters to replace. - * @param __sv The string_view to insert from. + * @param __svt The object convertible to string_view to insert from. * @param __pos2 The position in the string_view to insert from. * @param __n2 The number of characters to insert. * @return Reference to this string. @@ -4852,12 +4989,16 @@ to replace at. * @param __i2 An iterator referencing the end position for the replace. - * @param __sv The string_view to insert from. + * @param __svt The object convertible to string_view to insert from. * @return Reference to this string. */ - basic_string& - replace(const_iterator __i1, const_iterator __i2, __sv_type __sv) - { return this->replace(__i1 - begin(), __i2 - __i1, __sv); } + template + _If_sv<_Tp, basic_string&> + replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt) + { + __sv_type __sv = __svt; + return this->replace(__i1 - begin(), __i2 - __i1, __sv); + } #endif // C++17 private: @@ -5062,13 +5203,18 @@ #if __cplusplus > 201402L /** * @brief Find position of a string_view. - * @param __sv The string_view to locate. + * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. */ - size_type - find(__sv_type __sv, size_type __pos = 0) const noexcept - { return this->find(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find(const _Tp& __svt, size_type __pos = 0) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -5135,13 +5281,18 @@ #if __cplusplus > 201402L /** * @brief Find last position of a string_view. - * @param __sv The string_view to locate. + * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search back from (default end). * @return Index of start of last occurrence. */ - size_type - rfind(__sv_type __sv, size_type __pos = npos) const noexcept - { return this->rfind(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + rfind(const _Tp& __svt, size_type __pos = npos) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->rfind(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -5213,13 +5364,19 @@ #if __cplusplus > 201402L /** * @brief Find position of a character of a string_view. - * @param __sv A string_view containing characters to locate. + * @param __svt An object convertible to string_view containing + * characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ - size_type - find_first_of(__sv_type __sv, size_type __pos = 0) const noexcept - { return this->find_first_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_first_of(const _Tp& __svt, size_type __pos = 0) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_first_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -5291,13 +5448,19 @@ #if __cplusplus > 201402L /** * @brief Find last position of a character of string. - * @param __sv A string_view containing characters to locate. + * @param __svt An object convertible to string_view containing + * characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ - size_type - find_last_of(__sv_type __sv, size_type __pos = npos) const noexcept - { return this->find_last_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_last_of(const _Tp& __svt, size_type __pos = npos) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_last_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -5366,13 +5529,19 @@ #if __cplusplus > 201402L /** * @brief Find position of a character not in a string_view. - * @param __sv A string_view containing characters to avoid. + * @param __svt An object convertible to string_view containing + * characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ - size_type - find_first_not_of(__sv_type __sv, size_type __pos = 0) const noexcept - { return this->find_first_not_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_first_not_of(const _Tp& __svt, size_type __pos = 0) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_first_not_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -5442,13 +5611,19 @@ #if __cplusplus > 201402L /** * @brief Find last position of a character not in a string_view. - * @param __sv A string_view containing characters to avoid. + * @param __svt An object convertible to string_view containing + * characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ - size_type - find_last_not_of(__sv_type __sv, size_type __pos = npos) const noexcept - { return this->find_last_not_of(__sv.data(), __pos, __sv.size()); } + template + _If_sv<_Tp, size_type> + find_last_not_of(const _Tp& __svt, size_type __pos = npos) const + noexcept(is_same<_Tp, __sv_type>::value) + { + __sv_type __sv = __svt; + return this->find_last_not_of(__sv.data(), __pos, __sv.size()); + } #endif // C++17 /** @@ -5498,12 +5673,14 @@ #if __cplusplus > 201402L /** * @brief Compare to a string_view. - * @param __sv A string_view to compare against. + * @param __svt An object convertible to string_view to compare against. * @return Integer < 0, 0, or > 0. */ - int - compare(__sv_type __sv) const + template + _If_sv<_Tp, int> + compare(const _Tp& __svt) const noexcept(is_same<_Tp, __sv_type>::value) { + __sv_type __sv = __svt; const size_type __size = this->size(); const size_type __osize = __sv.size(); const size_type __len = std::min(__size, __osize); @@ -5518,18 +5695,24 @@ * @brief Compare to a string_view. * @param __pos A position in the string to start comparing from. * @param __n The number of characters to compare. - * @param __sv A string_view to compare against. + * @param __svt An object convertible to string_view to compare + * against. * @return Integer < 0, 0, or > 0. */ - int - compare(size_type __pos, size_type __n, __sv_type __sv) const - { return __sv_type(*this).substr(__pos, __n).compare(__sv); } + template + _If_sv<_Tp, int> + compare(size_type __pos, size_type __n, const _Tp& __svt) const + { + __sv_type __sv = __svt; + return __sv_type(*this).substr(__pos, __n).compare(__sv); + } /** * @brief Compare to a string_view. * @param __pos1 A position in the string to start comparing from. * @param __n1 The number of characters to compare. - * @param __sv A string_view to compare against. + * @param __svt An object convertible to string_view to compare + * against. * @param __pos2 A position in the string_view to start comparing from. * @param __n2 The number of characters to compare. * @return Integer < 0, 0, or > 0. Index: testsuite/21_strings/basic_string/79162.cc =================================================================== --- testsuite/21_strings/basic_string/79162.cc (nonexistent) +++ testsuite/21_strings/basic_string/79162.cc (working copy) @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +// Copyright (C) 2017 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +template +class opt : public DataType +{ + opt(const opt &) = delete; + opt &operator=(const opt &) = delete; +public: + opt() {} +}; + +int main() +{ + opt PGOTestProfileFile; + std::string ProfileFileName; + ProfileFileName = PGOTestProfileFile; +} Index: testsuite/21_strings/basic_string/lwg2946.cc =================================================================== --- testsuite/21_strings/basic_string/lwg2946.cc (nonexistent) +++ testsuite/21_strings/basic_string/lwg2946.cc (working copy) @@ -0,0 +1,41 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +// Copyright (C) 2017 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +int main() +{ + std::string s({"abc", 1}); + s = {"abc", 1}; + s += {"abc", 1}; + s.append({"abc", 1}); + s.assign({"abc", 1}); + s.insert(0, {"abc", 1}); + s.replace(0, 1, {"abc", 1}); + s.replace(s.cbegin(), s.cbegin(), {"abc", 1}); + s.find({"abc", 1}); + s.rfind({"abc", 1}); + s.find_first_of({"abc", 1}); + s.find_last_of({"abc", 1}); + s.find_first_not_of({"abc", 1}); + s.find_last_not_of({"abc", 1}); + s.compare({"abc", 1}); + s.compare(0, 1, {"abc", 1}); +}