Boost logo

Boost :

Subject: Re: [boost] [Filesystem] Proposal: make filesystem generic-programming friendly
From: Alexander Lamaison (awl03_at_[hidden])
Date: 2014-05-23 16:49:01


Klaim - Joël Lamotte <mjklaim_at_[hidden]> writes:

> I've hit issues similar to the pointed ones, so I'm interested in such a
> solution.
> As a user I agree that being able to use the whole path/aglorithms on
> different kinds of filesystems would simplify greatly my current work.
>
> My use case is to be able to easily choose between real file system and
> archive file system at runtime.
> To implement archie file work I currently use PhysFS [1].
>
> However I have several totally different projects with this need of runtime
> choice of filesystem and currently
> I have to add project-domain-specific file manipulation layers to each
> project which
> is therefore implemented twice, once with boost::filesystem and the other
> with PhysFS.
> That's a lot of time spent on making sure they do the same things and it is
> easily error prone.
> A solution to help me write my project-specific algorithms once would be
> very helpful.

If my proposal goes ahead, you should be able to write a thin layer
around the PhysFS API that implements the FilesystemConcept. Then the
same code could use it, generically, with Boost.Filesystem.

> If the proposal is really applicable without any backward incompatibility,
> I'm open to test it ASAP in my current projects (if an implementation
> exists).
> Also, it seems that it would the solve the same problems for
> std::filesystem? It was a concern I had recently when thinking about
> it.

That's what's pushed me to publish the draft now. I would like to see
the same changes in std::filesystem before it's set in stone.

> Question: it is not totally clear to me what the proposal wants to do with
> the boost::filesystem::path class exactly.
> The example suggests that boost::filesystem::path would be usable for any
> filesystem implementation.

Yes. The idea is to allow particular filesystem implementations to use
boost::filesystem::path if they want to, or to use something else that
implements the FilesystemPathConcept API, if they need it. Generic code
can refer to the path type using its typedef in the filesystem object
so that it works with either.

> In which case, do you suggest to remove absolute() and cannonical() from
> boost::filesystem::path so that it would only be possible to get these
> versions
> using one of the namespace functions overload of the same name, one for
> local_filesystem(), the other taking a filesystem as parametter?

The functions `canonical` and `absolute` are already free functions,
but, yes, I would expect to overload them/make them a method of the
filesystem object (depending which API option we go ahead with) just
like the others. As for methods of `boost::filesystem::path` like
`make_absolute`, ideally these should be removed from `path` because
they need to consult the filesystem. However, for
backward-compatibility it is better to leave them in place, at least for
the time being. std::filesystem represents a good opportunity to remove
them because there is no existing code to remain backward-compatible
with.

As you can see from the Path decomposition table [1],
many methods in `boost::filesystem::path` do have
platform-specific behaviour and each filesystem implementor
would have to look carefully at whether that is appropriate for their
filesystem or not, before deciding whether to use
`boost::filesystem::path` as their path class or whether to use their
own.

It may be that for the ZIP archives filesystem, it is desireable for
paths within that filesystem to use back-slashes on Windows and
forward-slashes everywhere else, whereas an FTP filesystem should always
use forward-slashed regardless of platform.

I am purposely distinguishing between filesystem-specific behaviour and
platforms-specific behaviour. The latter just adapts to the local
operating-system's display conventions while the former uses the
filesystem to obtain information. Models of FilesystemPathConcept (be
that `boost::filesystem::path` or otherwise) should be able to exhibit
platform-specific behaviour to allow things like the ZIP path behaviour
above. However, they should not have filesystem-specific behaviour,
like `canonical()` as that may need filesystem instance data to
implement, and so should be part of the filesystem object.

Some examples of platform-specific behaviour in
`boost::filesystem::path`:

(constructor)
make_preferred
native
c_str
string
wstring
u16string
u32string

Some examples of filesystem-specific behaviour in
`boost::filesystem::path` that, ideally, would not be there:
make_absolute
is_absolute
is_relative

[1] http://www.boost.org/doc/libs/1_55_0/libs/filesystem/doc/reference.html#Path-decomposition-table

Alex

-- 
Swish - Easy SFTP for Windows Explorer (http://www.swish-sftp.org)

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk