Date: Tue, 3 Feb 2026 16:17:55 -0500
On Thu, Jan 29, 2026 at 8:48 PM 梁家铭 via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> 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
> <https://cplusplus.github.io/LWG/issue2674>. 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]
> <https://eel.is/c++draft/fs.class.path#fs.path.itr-2>). 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.
> <https://eel.is/c++draft/fs.class.path#fs.path.itr-2.sentence-1>
>
> Its value_type is path.
> <https://eel.is/c++draft/fs.class.path#fs.path.itr-2.sentence-2> *Therefore,
> it should fulfill concept *
> bidirectional_iterator
> <https://eel.is/c++draft/iterator.concept.bidir#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 <https://cplusplus.github.io/LWG/issue2674> 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 <https://eel.is/c++draft/temp.constr>*
`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
<https://eel.is/c++draft/res.on.requirements#def:model,concept>*
`bidirectional_iterator`?
Doesn't that make lots of usages IFNDR
<https://eel.is/c++draft/res.on.requirements#2>, 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
std-proposals_at_[hidden]> wrote:
> 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
> <https://cplusplus.github.io/LWG/issue2674>. 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]
> <https://eel.is/c++draft/fs.class.path#fs.path.itr-2>). 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.
> <https://eel.is/c++draft/fs.class.path#fs.path.itr-2.sentence-1>
>
> Its value_type is path.
> <https://eel.is/c++draft/fs.class.path#fs.path.itr-2.sentence-2> *Therefore,
> it should fulfill concept *
> bidirectional_iterator
> <https://eel.is/c++draft/iterator.concept.bidir#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 <https://cplusplus.github.io/LWG/issue2674> 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 <https://eel.is/c++draft/temp.constr>*
`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
<https://eel.is/c++draft/res.on.requirements#def:model,concept>*
`bidirectional_iterator`?
Doesn't that make lots of usages IFNDR
<https://eel.is/c++draft/res.on.requirements#2>, 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
Received on 2026-02-03 21:18:11
