On 13/10/21 20:41 +0100, Jonathan Wakely wrote:
Adjust the __detail::__effective_range overloads so they always return a
string or string view using std::char_traits, because we don't care
about the traits of an incoming string.

Use std::contiguous_iterator in the __effective_range(const Source&)
overload, to allow returning a basic_string_view in more cases. For the
non-contiguous cases in both __effective_range and __string_from_range,
return a std::string instead of std::u8string when the value type of the
range is char8_t.  These changes avoid unnecessary basic_string
temporaries.

[...]

  template<typename _InputIterator>
    inline auto
    __string_from_range(_InputIterator __first, _InputIterator __last)
    {
      using _EcharT
        = typename std::iterator_traits<_InputIterator>::value_type;
-      static_assert(__is_encoded_char<_EcharT>);
+      static_assert(__is_encoded_char<_EcharT>); // C++17 [fs.req]/3

-#if __cpp_lib_concepts
-      constexpr bool __contiguous = std::contiguous_iterator<_InputIterator>;
-#else
-      constexpr bool __contiguous
-       = is_pointer_v<decltype(std::__niter_base(__first))>;
-#endif
-      if constexpr (__contiguous)
+      if constexpr (__is_contiguous<_InputIterator>)

Oops, this pessimiszes construction from string::iterator and
vector::iterator in C++17 mode, because the new __is_contiguous
variable template just uses is_pointer_v, without the __niter_base
call that unwraps a __normal_iterator.

That means that we now create a basic_string<C> temporary where we
previously jsut returned a basic_string_view<C>.

I am testing a fix.


Reply via email to