30 Input/output library [input.output]

30.10 File systems [filesystems]

30.10.33 Class recursive_­directory_­iterator [fs.class.rec.dir.itr]

Объект типаrecursive_­directory_­iterator предоставляет итератор для последовательностиdirectory_­entry элементов, представляющих файлы в каталоге или в определяемом реализацией типе файла, подобном каталогу, и его подкаталогам.

namespace std::filesystem {
  class recursive_directory_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = directory_entry;
    using difference_type   = ptrdiff_t;
    using pointer           = const directory_entry*;
    using reference         = const directory_entry&;

    // [fs.rec.dir.itr.members], constructors and destructor
    recursive_directory_iterator() noexcept;
    explicit recursive_directory_iterator(const path& p);
    recursive_directory_iterator(const path& p, directory_options options);
    recursive_directory_iterator(const path& p, directory_options options,
                                 error_code& ec) noexcept;
    recursive_directory_iterator(const path& p, error_code& ec) noexcept;
    recursive_directory_iterator(const recursive_directory_iterator& rhs);
    recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
    ~recursive_directory_iterator();

    // [fs.rec.dir.itr.members], observers
    directory_options  options() const;
    int                depth() const;
    bool               recursion_pending() const;

    const directory_entry& operator*() const;
    const directory_entry* operator->() const;

    // [fs.rec.dir.itr.members], modifiers
    recursive_directory_iterator&
      operator=(const recursive_directory_iterator& rhs);
    recursive_directory_iterator&
      operator=(recursive_directory_iterator&& rhs) noexcept;

    recursive_directory_iterator& operator++();
    recursive_directory_iterator& increment(error_code& ec) noexcept;

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

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

Вызовoptions,depth,recursion_­pending, pop илиdisable_­recursion_­pending на итератора , который не разыменовываемое приводит к неопределенному поведению.

Поведение arecursive_­directory_­iterator такое же, как и для a,directory_­iterator если не указано иное.

[ Note: Если структура каталогов, по которой выполняется итерация, содержит циклы, то конечный итератор может быть недоступен. ]end note

30.10.33.1 recursive_­directory_­iterator members [fs.rec.dir.itr.members]

recursive_directory_iterator() noexcept;

Effects: Создает конечный итератор.

explicit recursive_directory_iterator(const path& p); recursive_directory_iterator(const path& p, directory_options options); recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; recursive_directory_iterator(const path& p, error_code& ec) noexcept;

Effects: Создает итератор, представляющий первую запись в каталоге, в которыйp разрешается, если есть; в противном случае - конечный итератор. Однако если

(options & directory_options::skip_permission_denied) != directory_options::none

и конструкция обнаруживает ошибку, указывающую, что в доступеp отказано, создает конечный итератор и не сообщает об ошибке.

Postconditions:options() == options для подписей с directory_­options аргументом, иначеoptions() == directory_­options​::​none.

Throws: Как указано в[fs.err.report].

[ Note: Для перебора текущего каталога используйтеrecursive_­directory_­iterator(".") вместоrecursive_­directory_­iterator(""). ]end note

[ Note: По умолчаниюrecursive_­directory_­iterator не следует символическим ссылкам на каталоги. Чтобы следовать символическим ссылкам каталога, укажитеoptions как ] directory_­options​::​follow_­directory_­symlinkend note

recursive_directory_iterator(const recursive_directory_iterator& rhs);

Effects: Создает объект классаrecursive_­directory_­iterator.

Postconditions:

  • options() == rhs.options()

  • depth() == rhs.depth()

  • recursion_­pending() == rhs.recursion_­pending()

recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;

Effects: Создает объект классаrecursive_­directory_­iterator.

Postconditions:options(),depth()Иrecursion_­pending() имеет значение , которые rhs.options(),rhs.depth()и rhs.recursion_­pending(), соответственно, имели перед вызовом функции.

recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);

Effects: Если*this иrhs являются одним и тем же объектом, член не имеет никакого эффекта.

Postconditions:

  • options() == rhs.options()

  • depth() == rhs.depth()

  • recursion_­pending() == rhs.recursion_­pending()

Returns:*this.

recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept;

Effects: Если*this иrhs являются одним и тем же объектом, член не имеет никакого эффекта.

Postconditions:options(),depth()Иrecursion_­pending() имеет значение , которыеrhs.options(), rhs.depth()иrhs.recursion_­pending(), соответственно, имели перед вызовом функции.

Returns:*this.

directory_options options() const;

Returns: Значение аргумента, переданного конструктору для options параметра, если он присутствует, в противном случае directory_­options​::​none.

Throws: Ничего такого.

int depth() const;

Returns: Текущая глубина просматриваемого дерева каталогов. [ Note: Начальный каталог - это глубина0, его непосредственные подкаталоги - это глубина1и так далее. ]end note

Throws: Ничего такого.

bool recursion_pending() const;

Returns:true ifdisable_­recursion_­pending() не был вызван после предыдущей операции построения или приращения, в противном случаеfalse.

Throws: Ничего такого.

recursive_directory_iterator& operator++(); recursive_directory_iterator& increment(error_code& ec) noexcept;

Effects: Как указано для операции увеличения префикса Input iterators, за исключением того, что:

  • Если на текущей глубине больше нет записей, то еслиdepth() != 0 итерация по родительскому каталогу возобновляется; иначе*this = recursive_­directory_­iterator().

  • В противном случае, если

    recursion_pending() && is_directory((*this)->status()) &&
    (!is_symlink((*this)->symlink_status()) ||
     (options() & directory_options::follow_directory_symlink) != directory_options::none)

    то либо каталог(*this)->path() рекурсивно перебирается, либо, если

    (options() & directory_options::skip_permission_denied) != directory_options::none

    и возникает ошибка, указывающая на то, что в разрешении на доступ к каталогу(*this)->path() отказано, тогда каталог(*this)->path() обрабатывается как пустой каталог и об ошибках не сообщается.

Returns:*this.

Throws: Как указано в[fs.err.report].

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

Effects: Еслиdepth() == 0установите*this вrecursive_­directory_­iterator(). В противном случае прекратите итерацию каталога, по которому в настоящее время выполняется итерация, и продолжите итерацию по родительскому каталогу.

Throws: Как указано в[fs.err.report].

void disable_recursion_pending();

Postconditions:recursion_­pending() == false.

[ Note:disable_­recursion_­pending() используется для предотвращения нежелательной рекурсии в каталог. ] end note

30.10.33.2 recursive_­directory_­iterator non-member functions [fs.rec.dir.itr.nonmembers]

Эти функции позволяют использоватьrecursive_­directory_­iterator операторы for на основе диапазона.

recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;

Returns:iter.

recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;

Returns:recursive_­directory_­iterator().