Boost logo

Boost :

Subject: Re: [boost] boost::filesystem::path frustration
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2013-01-25 18:18:26

On Friday 25 January 2013 23:55:19 Yakov Galka wrote:
> On Fri, Jan 25, 2013 at 6:49 PM, Andrey Semashev
> <andrey.semashev_at_[hidden]>wrote:
> > [...]
> >
> > IMHO, path should not pretend to be a container. Things like push_back,
> > insert, erase don't make sense with respect to it. It could provide
> > begin/end
> > iterators over underlying characters but just to implement other
> > algorithms.
> > Iterating over path elements (i.e. what is currently achieved with
> > begin/end)
> > should probably be an external tool, like an iterator adaptor or a view on
> > top
> > of the path object. In the end it should become just a thin wrapper over a
> > string, with a few path-related functions.
> What are those path-related functions that you will leave there?
> extension()? has_root()? Maybe these are also better to be free standing
> functions working on arbitrary strings?

Which functions to leave as members and which to extract as free functions is
a design choice. I would probably leave operations that have meaning of
accessing parts of the path (like filename, extension, parent path, etc.) as
members and extract everything else.

> You are left with operator/, which
> also can be declared as
> string operator/(const string&, const string&);
> and be brought to scope with a using directive, for those who want to use
> it.

operator/ doesn't make sense for strings, it should never be defined like
that. Whether it is defined as a member function or a free function is not
essential, but it should be specific for paths.

> Essentially you are left with a plain old string of a platform
> dependent encoding. This is what I said in my first post—thinking that "a
> path as a string" is applicable where you don't care for what is inside the
> path (in which case just use a string as a cookie), but in other cases it
> is nonsense.

Well, most of the time all I want is a wrapper around a string that conceals
platform-specific filesystem differences, nothing more. So yes, a path is a
plain old string with a few helpers to compose and interpret it in a portable
way. And I don't need anything more sophisticated from it.

Another part of the library is a set of algorithms to operate on the actual
filesystem (like, copying the files and testing for path equivalence); this
part is also required and very useful. These algorithms abstract away another
aspect of the filesystem (namely, the underlying OS API) and they don't need
anything sophisticated from the path either. Interestingly, most of these
algorithms can operate with plain strings instead of paths.

So basically, the path does not need to be a high-level beast to be useful.
That does not mean that such high-level tools are useless, but they can be
implemented externally, without cluttering the path interface.

> So please explain why "path should not pretend to be a container".

I think I've answered this partially above. I'll add that a container is
supposed to contain elements and I'm not sure what is supposed to be an
element of a path. A path is basically an identifier for a file, which is a
more or less indivisible entity. Surely you can introspect its contents, but
these parts either won't be a path (e.g. extension) or will be a path
identifying another file (e.g. parent path).

> I agree in general that implementing a view for iterating over path
> elements is an acceptable strategy, though. But in this case it is better
> to scrap the path class completely.

I disagree. Path type is very useful, if not for its operations then for type
clarity at the very least.

Boost list run by bdawes at, gregod at, cpdaniel at, john at