This simplifies the logic of converting Source arguments and pairs of InputIterator arguments into the native string format. For any input that is a contiguous range of path::value_type (or char8_t for POSIX) a string view can be created and the conversion can be done directly, with no intermediate allocation. Previously some cases created a basic_string unnecessarily, for example construction from a pair of path::string_type::iterators, or a pair of non-const value_type* pointers. * include/bits/fs_path.h (__detail::_S_range_begin) (__detail::_S_range_end, path::_S_string_from_iter): Replace with overloaded function template __detail::__effective_range. (__detail::__effective_range): New overloaded function template to create a basic_string or basic_string_view for an effective range. (__detail::__value_type_is_char): Use __detail::__effective_range. Do not use remove_const on value type. (__detail::__value_type_is_char_or_char8_t): Likewise. (path::path(const Source&, format)) (path::path(const Source&, const locale&)) (path::operator/=(const Source&), path::append(const Source&)) (path::concat(const Source&)): Use __detail::__effective_range. (path::_S_to_string(InputIterator, InputIterator)): New function template to create a string view if possible, or string otherwise. (path::_S_convert): Add overloads that convert a string returned by __detail::__effective_range. Use if-constexpr to inline conversion logic from all overloads of _Cvt::_S_convert. (path::_S_convert_loc): Add overload that converts a string. Use _S_to_string to avoid allocation when possible. (path::_Cvt): Remove. (path::operator+=(CharT)): Remove indirection through path::concat. * include/experimental/bits/fs_path.h (path::_S_convert_loc): Add overload for non-const pointers, to avoid constructing a std::string. * src/c++17/fs_path.cc (path::_S_convert_loc): Replace conditional compilation with call to _S_convert. Tested powerpc64le-linux, committed to master.