On Mon, 14 Apr 2025 at 07:37, Tomasz Kaminski <tkami...@redhat.com> wrote: > > > > On Sat, Apr 12, 2025 at 4:01 PM Jonathan Wakely <jwak...@redhat.com> wrote: >> >> My recent r15-9381-g648d5c26e25497 change assumes that a contiguous >> iterator with the correct value_type can be converted to a const charT* >> but that's not true for volatile charT*. The optimization should only be >> done if it can be converted to the right pointer type. >> >> Additionally, the generic loop for non-contiguous iterators needs an >> explicit cast to deal with iterators that have a reference type that is >> not explicitly convertible to charT. >> >> libstdc++-v3/ChangeLog: >> >> PR libstdc++/119748 >> * include/bits/basic_string.h (_S_copy_chars): Only optimize for >> contiguous iterators that are convertible to const charT*. Use >> explicit conversion to charT after dereferencing iterator. >> (_S_copy_range): Likewise for contiguous ranges. >> * include/bits/cow_string.h (_S_copy_chars): Likewise. >> (basic_string(from_range_t, R&&, const Alloc&)): Likewise. >> * testsuite/21_strings/basic_string/cons/char/119748.cc: New >> test. >> * testsuite/21_strings/basic_string/cons/wchar_t/119748.cc: >> New test. >> --- >> >> Tested x86_64-linux. >> >> The static_cast<_CharT>(*__k1) bit in _S_copy_chars is relevant for the >> branches too. Thinking about it now, I should probably add another >> test with iterators that have a value_type with 'explicit operator char()' >> because volatile char* isn't the only case that fails. > > The range constructor is constrained by container-compatible-range > (https://eel.is/c++draft/containers#concept:container-compatible-range), > that requires conversion to value type to be implicit. > Similar requirement exists for iterator-pair algorithms: > https://eel.is/c++draft/containers#sequence.reqmts-2.5
Ah yes, thanks. So we only have a problem when iter_reference_t<I> or range_reference_t<R> is volatile-qualified. Those are the only cases where const charT& won't bind to the iterator's reference type, or where a contiguous iterator can't be converted to const charT*. The new tests are still incomplete though, as volatile char* only tests the contiguous iterator path. We also need to test forward iterators and input iterators that return volatile references. New patch incoming ...