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-30

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;