This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3719. Directory iterators should be usable with default sentinel

Section: 31.12.11.1 [fs.class.directory.iterator.general], 31.12.12.1 [fs.class.rec.dir.itr.general] Status: WP Submitter: Jonathan Wakely Opened: 2022-06-17 Last modified: 2022-07-25

Priority: Not Prioritized

View all issues with WP status.

Discussion:

We added comparisons with `default_sentinel_t` to the stream and streambuf iterators, because their past-the-end iterator is just a default-constructed iterator. We didn't do the same for filesystem directory iterators, but they also use a default-constructed value as the sentinel.

The proposed resolution addresses this oversight.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4910.

> 1. Modify 31.12.11.1 [fs.class.directory.iterator.general], class `directory_iterator` synopsis, as indicated:

>    >     namespace std::filesystem {
>    >       class directory_iterator {
>    >         […]

>    >         const directory_entry& operator*() const;
>    >         const directory_entry* operator->() const;
>    >         directory_iterator& operator++();
>    >         directory_iterator& increment(error_code& ec);

>    >         friend bool operator==(const directory_iterator& lhs, default_sentinel_t) noexcept
>    >         { return lhs == end(lhs); }

>    >         // other members as required by 25.3.5.3 [input.iterators], input iterators
>    >       };
>    >     }

> 2. Modify 31.12.12.1 [fs.class.rec.dir.itr.general], class `recursive_directory_iterator` synopsis, as indicated:

>    >     namespace std::filesystem {
>    >       class recursive_directory_iterator {
>    >         […]

>    >         void pop();
>    >         void pop(error_code& ec);
>    >         void disable_recursion_pending();

>    >         friend bool operator==(const recursive_directory_iterator& lhs, default_sentinel_t) noexcept
>    >         { return lhs == end(lhs); }

>    >         // other members as required by 25.3.5.3 [input.iterators], input iterators
>    >       };
>    >     }

[2022-07-06; Jonathan Wakely revises proposed resolution and adds regex iterators as suggested on the reflector.]

[2022-07-11; Reflector poll]

Set status to Tentatively Ready after six votes in favour during reflector poll.

[2022-07-15; LWG telecon: move to Ready]

[2022-07-25 Approved at July 2022 virtual plenary. Status changed: Ready → WP.]

Proposed resolution:

This wording is relative to N4910.

1. Modify 31.12.11.1 [fs.class.directory.iterator.general], class `directory_iterator` synopsis, as indicated:

   >     namespace std::filesystem {
   >       class directory_iterator {
   >         […]

   >         const directory_entry& operator*() const;
   >         const directory_entry* operator->() const;
   >         directory_iterator& operator++();
   >         directory_iterator& increment(error_code& ec);

   >         bool operator==(default_sentinel_t) const noexcept
   >         { return *this == directory_iterator(); }

   >         // other members as required by 25.3.5.3 [input.iterators], input iterators
   >       };
   >     }

2. Modify 31.12.12.1 [fs.class.rec.dir.itr.general], class `recursive_directory_iterator` synopsis, as indicated:

   >     namespace std::filesystem {
   >       class recursive_directory_iterator {
   >         […]

   >         void pop();
   >         void pop(error_code& ec);
   >         void disable_recursion_pending();

   >         bool operator==(default_sentinel_t) const noexcept
   >         { return *this == recursive_directory_iterator(); }

   >         // other members as required by 25.3.5.3 [input.iterators], input iterators
   >       };
   >     }

3. Modify 32.11.1.1 [re.regiter.general], `regex_iterator` synopsis, as indicated:

   >     namespace std {
   >       template<class BidirectionalIterator,
   >                 class charT = typename iterator_traits<BidirectionalIterator>::value_type,
   >                 class traits = regex_traits<charT>>
   >         class regex_iterator {
   >           […]
   >           regex_iterator& operator=(const regex_iterator&);
   >           bool operator==(const regex_iterator&) const;
   >           bool operator==(default_sentinel_t) const { return *this == regex_iterator(); }
   >           const value_type& operator*() const;
   >           const value_type* operator->() const;

4. Modify 32.11.2.1 [re.tokiter.general], `regex_token_iterator` synopsis, as indicated:

   >     namespace std {
   >       template<class BidirectionalIterator,
   >                 class charT = typename iterator_traits<BidirectionalIterator>::value_type,
   >                 class traits = regex_traits<charT>>
   >         class regex_token_iterator {
   >           […]
   >           regex_iterator& operator=(const regex_token_iterator&);
   >           bool operator==(const regex_token_iterator&) const;
   >           bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); }
   >           const value_type& operator*() const;
   >           const value_type* operator->() const;