Hi,
Recently I find that `filesystem::path::iterator` is not bidirectional iterator, as specified in
Issue 2674: Bidirectional iterator requirement on path::iterator is very expensive. It fulfills all requirements of Cpp17BidirectionalIterator except that there is no requirement that two equal iterators be bound to the same object (See
[fs.class.path]). The reason is that it allows the iterator to cache filename component (as libc++ and MS-STL do) instead of storing a container of components in filesystem::path (as libstdc++ does, unfortunately). However, it also degrades path::iterator from Cpp17BidirectionalIterator to Cpp17InputIterator (well only libstdc++ can and indeed mark it with bidirectional_iterator_tag). Such degradation is also counter-intuitive and makes many components in `<algorithm>` inapplicable (e.g. libc++ issue:
https://github.com/llvm/llvm-project/issues/55683).
However, such simplification is very like `std::views::split`, which makes it fulfill bidirectional_iterator since C++20 if we examine all concepts one by one except the iterator tag. And C++20 allows us to define `iterator_concept` instead of examining `iterator_tag`. So I think we should make a fix DR (bold means wording change):
A
path::iterator is a constant iterator meeting all the requirements of a
Cpp17BidirectionalIterator except that, for dereferenceable iterators
a and
b of type
path::iterator with
a == b, there is no requirement that
*a and
*b are bound to the same object
. Its
value_type is
path. Therefore, it should fulfill concept bidirectional_iterator.
And implementations can utilize `iterator_concept` to support it.
This sounds to me like a reasonable topic for a paper. I mean, this seems 100% like LEWG design territory — although I admit I'm confused by the existence of
LWG 2674 and the implementation divergence between libc++/libstdc++ and Microsoft.
I haven't investigated this area myself, so I don't have a concrete suggestion for wording. But the stuff you wrote in green above is not good wording. Don't say something "should" do something; just show the actual diff you're proposing. Find the words in the Standard that are currently as-they-should-not-be, and show how to replace them with something better.
You say path::iterator should [sic] "fulfill" concept `bidirectional_iterator`. But that's not a thing. We can say that path::iterator
satisfies `bidirectional_iterator`; this is already true on libc++ and libstdc++, but false on MS STL. However, I'm confused by your phrasing — are you saying you want path::iterator to
satisfy `bidirectional_iterator` without
modeling `bidirectional_iterator`? Doesn't that make lots of usages
IFNDR, technically? Obviously such IFNDR-ness would be harmless in practice; but how could WG21 possibly standardize anything along those lines with a straight face — "we provide a library type that satisfies a library concept but doesn't model it"? That way lies madness, it seems to me.
Maybe I'm just missing something basic; again, I haven't looked deeply at this at all. But you could help by providing the exact wording you think ought to change, and how to change it.
HTH,
Arthur