2707. path construction and assignment should have "string_type&&" overloads

Section: 30.11.7 [fs.class.path] Status: C++17 Submitter: Eric Fiselier Opened: 2016-05-09 Last modified: 2017-07-30

Priority: 0

View all other issues in [fs.class.path].

View all issues with C++17 status.

Discussion:

Currently construction of a path from the native string_type always performs a copy, even when that string is passed as a rvalue. This is a large pessimization as paths are commonly constructed from temporary strings.

One pattern I frequently see is:

path foo(path const& p) {
  auto s = p.native();
  mutateString(s);
  return s;
}

Implementations should be allowed to move from s and avoid an unnecessary allocation. I believe string_type&& constructor and assignment operator overloads should be added to support this.

Proposed resolution:

This wording is relative to N4582.

  1. Change 30.11.7 [fs.class.path], class path synopsis, as indicated:

    [Drafting note: Making the string_type&& constructors and assignment operators noexcept would over-constrain implementations which may need to perform construct additional state]

    namespace std::filesystem {
      class path {
      public:
        […]
        // 27.10.8.4.1, constructors and destructor
        path() noexcept;
        path(const path& p);
        path(path&& p) noexcept;
        path(string_type&& source);
        template <class Source>
        path(const Source& source);
        […]
        
        // 27.10.8.4.2, assignments
        path& operator=(const path& p);
        path& operator=(path&& p) noexcept;
        path& operator=(string_type&& source);
        path& assign(string_type&& source);
        template <class Source>
        path& operator=(const Source& source);
        template <class Source>
        path& assign(const Source& source)
        template <class InputIterator>
        path& assign(InputIterator first, InputIterator last);    
        […]
      };
    }
    
  2. Add a new paragraph following 30.11.7.4.1 [fs.path.construct]/3:

    path(string_type&& source);
    

    -?- Effects: Constructs an object of class path with pathname having the original value of source. source is left in a valid but unspecified state.

  3. Add a new paragraph following 30.11.7.4.2 [fs.path.assign]/4:

    path& operator=(string_type&& source);
    path& assign(string_type&& source);
    

    -?- Effects: Modifies pathname to have the original value of source. source is left in a valid but unspecified state.

    -?- Returns:*this