diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 630ff1af8d3..9c431c765ab 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -473,6 +473,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 traits_type::assign(__d, __n, __c); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template @@ -480,31 +482,44 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { +#if __cplusplus >= 201103L + using _IterBase = decltype(std::__niter_base(__k1)); + if constexpr (__or_, + is_same<_IterBase, const _CharT*>>::value) + _S_copy(__p, std::__niter_base(__k1), __k2 - __k1); +#if __cpp_lib_concepts + else if constexpr (contiguous_iterator<_Iterator> + && is_same_v, _CharT>) + { + const auto __d = __k2 - __k1; + (void) (__k1 + __d); // See P3349R1 + _S_copy(__p, std::to_address(__k1), static_cast(__d)); + } +#endif + else +#endif for (; __k1 != __k2; ++__k1, (void)++__p) traits_type::assign(*__p, *__k1); // These types are off. } +#pragma GCC diagnostic pop - _GLIBCXX20_CONSTEXPR +#if __cplusplus < 201103L || defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS static void - _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } - _GLIBCXX20_CONSTEXPR static void _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) - _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } - _GLIBCXX20_CONSTEXPR static void - _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } - _GLIBCXX20_CONSTEXPR static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) - _GLIBCXX_NOEXCEPT { _S_copy(__p, __k1, __k2 - __k1); } +#endif #if __glibcxx_containers_ranges // C++ >= 23 // pre: __n == ranges::distance(__rg). __p+[0,__n) is a valid range. diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc index c4864794d40..34df909b31a 100644 --- a/libstdc++-v3/src/c++11/string-inst.cc +++ b/libstdc++-v3/src/c++11/string-inst.cc @@ -40,7 +40,8 @@ // replaced by constrained function templates, so that we instantiate the // pre-C++17 definitions. // This also causes the instantiation of the non-standard C++0x-era -// insert(iterator, initializer_list) overload, see PR libstdc++/83328 +// insert(iterator, initializer_list) overload, see PR libstdc++/83328, +// and overloads of _S_copy_chars for string iterators and pointers. #define _GLIBCXX_DEFINING_STRING_INSTANTIATIONS 1 #include