C++ Logo

SG16

Advanced search

Subject: Re: [SG16-Unicode] [isocpp-lib-ext] Proposed design change to P1030 filesystem::path_view
From: Arthur O'Dwyer (arthur.j.odwyer_at_[hidden])
Date: 2019-08-26 14:28:44


On Mon, Aug 26, 2019 at 6:21 AM Niall Douglas via Lib-Ext <
lib-ext_at_[hidden]> wrote:

> On 26/08/2019 02:14, Arthur O'Dwyer wrote:
> > A single path is not conceptually a "range" of /*anything*/ — it's just
> > a single filesystem path.
>
> filesystem::path defines that it is a range of filesystem path
> components. Apart from the native path separator being a valid character
> in a path component on some systems, I find that a reasonable design
> choice.
>

Well, that;
and that you lose the separators *between* components;
and that you can't tell the difference between a drive letter and a path
component;
and that your sample code tries to "std::cout <<" paths, which doesn't work
because every `path` object is implicitly wrapped in `std::quoted`.
https://godbolt.org/z/lpQA61

A path *itself* is not a range of anything — it's just a path.
std::filesystem::path breaks this intuition by giving std::filesystem::path
".begin()" and ".end()" methods, which causes C++ to treat it like a range
type. But that's just an example of "lying to the compiler." Giving
.begin() and .end() methods to a C++ class type that does not itself
*represent* a range of elements was the original sin.

> What it should have done was to give `std::filesystem::path` one or more
> > "range accessor" methods:
> > for (auto&& component : mypath.components()) { ... }
> > for (auto&& character : mypath.str()) { ... }
>
> Or iteration returns a path_component type, as Victor suggested.
>

Unfortunately, that won't fix any of the bugs in your original code sample.
You'll still lose the separators between components, and the drive letter,
and emit many spurious quotation marks. To fix your original code sample,
you need some way to tell your generic code that a std::filesystem::path
should never be treated as a range.

However, your original code sample is broken anyway for things like
`std::vector<int>` — it prints {1,2} and {12} identically.

Disabling path component iteration I don't think is worth the pain,
> personally.
>

I don't see any pain except the pain of people trying to use `for (auto&&
elt : path)` in production. Stopping that erroneous construct from
compiling would be a *good thing*.

–Arthur



SG16 list run by sg16-owner@lists.isocpp.org