Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it not possible to construct a `std::filesystem::path` from `std::filesystem::path` iterators?

The following piece of code aims to strip the first part of a path in case it exists:

#include <filesystem>

std::filesystem::path strip_prefix(std::filesystem::path p)
{      
  if (auto it{p.begin()}; it != p.end())
  {
    ++it;
    return std::filesystem::path(it, p.end());
  }

  return p;
}

(See: https://godbolt.org/z/wkXhcw)

I was surprised to find out this does not work. The code does not compile since the path constructor only takes iterators that iterate over character sequences. I can see the use of that, but why limit construction to only those kind of iterators? In my opinion it is counter intuitive to not support constructing a path from its own iterators. As far as I know most other STL types do support this idiom.

What would be an efficient implementation to achieve the same goal, other than completely reconstructing a new path?

Update: in this context, I found the following discussion relevant/amusing: http://boost.2283326.n4.nabble.com/boost-filesystem-path-frustration-td4641734.html. I agree with Dave here. I think seeing a path as a container of path elements is a very natural way to look at it (from a programmer's perspective).

like image 928
Ton van den Heuvel Avatar asked Dec 12 '18 12:12

Ton van den Heuvel


1 Answers

The simplest solution to the concatenating the segments to make a new path is just std::accumulate().

For your particular use case, I'd do something like this:

std::filesystem::path strip_prefix(std::filesystem::path p)
{
    if(p.empty()) return p;
    return std::accumulate(std::next(p.begin()), p.end(), 
                           std::filesystem::path{}, std::divides{});
}

As for why there isn't a constructor (or maybe a free function) to do this? I don't know. This seems like a need that comes up a fair bit when working with paths, but the committee does tend to be reluctant to add convenience functions to standard classes if the same result can be achieved by a call to a standard algorithm.

like image 195
Parker Coates Avatar answered Nov 18 '22 14:11

Parker Coates