2641. [filesys.ts] [PDTS] directory_iterator, recursive_directory_iterator, move construct/assign should be noexcept

Section: 13 [filesys.ts::class.directory_iterator], 14 [filesys.ts::class.rec.dir.itr] Status: TS Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2017-07-30

Priority: Not Prioritized

View all other issues in [filesys.ts::class.directory_iterator].

View all issues with TS status.

Discussion:

Addresses: filesys.ts

class directory_iterator move construct/assign should be noexcept.
class recursive_directory_iterator move construct/assign should be noexcept.

[Beman Dawes 2014-02-27]

Issues 2637, 2638, 2641, and 2649 are concerned with signatures which should or should not be noexcept. I will provide unified proposed wording for these issues, possibly in a separate paper.

[Daniel Krügler 2014-02-28]

directory_iterator begin(directory_iterator iter) noexcept;
directory_iterator end(const directory_iterator&) noexcept;

are noexcept, but we have no guarantee that at least the move-constructor is noexcept:

directory_iterator(const directory_iterator&) = default;
directory_iterator(directory_iterator&&) = default;

This means that either the above noexcept specifications are not warranted or that at least the move-constructor of directory_iterator is required to be noexcept.

The same applies to recursive_directory_iterator.

[21 May 2014 Beman Dawes provided proposed resolution wording.]

[18 Jun 2014 "= default" removed per LWG discussion]

Proposed resolution:

Change 13 Class directory_iterator [class.directory_iterator]:

directory_iterator(const directory_iterator& rhs) = default;
directory_iterator(directory_iterator&& rhs) noexcept = default;
...
directory_iterator& operator=(const directory_iterator& rhs) = default;
directory_iterator& operator=(directory_iterator&& rhs) noexcept = default;

To 13.1 directory_iterator members [directory_iterator.members] add:

directory_iterator(const directory_iterator& rhs);
directory_iterator(directory_iterator&& rhs) noexcept;

Effects: Constructs an object of class directory_iterator.

Postconditions: *this has the original value of rhs.

directory_iterator& operator=(const directory_iterator& rhs);
directory_iterator& operator=(directory_iterator&& rhs) noexcept;

Effects: If *this and rhs are the same object, the member has no effect.

Postconditions: *this has the original value of rhs.

Returns: *this.

Change 14 Class recursive_directory_iterator [class.rec.dir.itr]:

recursive_directory_iterator(const recursive_directory_iterator& rhs) = default;
recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept = default;
...
recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs) = default;
recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept = default;

To 14.1 recursive_directory_iterator members [rec.dir.itr.members] add:

recursive_directory_iterator(const recursive_directory_iterator& rhs);

Effects: Constructs an object of class recursive_directory_iterator.

Postconditions: this->options() == rhs.options() && this->depth() == rhs.depth() && this->recursion_pending() == rhs.recursion_pending().

recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;

Effects: Constructs an object of class recursive_directory_iterator.

Postconditions: this->options(), this->depth(), and this->recursion_pending() return the values that rhs.options(), rhs.depth(), and rhs.recursion_pending(), respectively, had before the function call.

recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);

Effects: If *this and rhs are the same object, the member has no effect.

Postconditions: this->options() == rhs.options() && this->depth() == rhs.depth() && this->recursion_pending() == rhs.recursion_pending() .

Returns: *this.

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

Effects: If *this and rhs are the same object, the member has no effect.

Postconditions: this->options(), this->depth(), and this->recursion_pending() return the values that rhs.options(), rhs.depth(), and rhs.recursion_pending(), respectively, had before the function call.

Returns: *this.