Boost logo

Boost :

From: Martin (adrianm_at_[hidden])
Date: 2004-09-04 09:20:18

Vladimir Prus <ghost <at>> writes:

> > Let the path be a container for all kind of paths that follow the generic
> > syntax explained in the boost::filesystem documentation.
> That's already the case, no?
No, the current implementation only allows you to have a single path "type"
for everything since the handling of root etc is built into the path class
(via #ifdefs for windows and posix).
If you want to add another path type (e.g. url) you would need to keep track
of the type inside the class and then do "if (type==url) ... else ..." in all

> > The benefits would be:
> > 1. The path can be used for other things than filesystems (XPath, Win32
> > registry)
> I think you're XPath example is a bit bogus. How can you represent
> descentant::section[ <at> id=foobar]/title
> with boost::path?

Didn't think about all cases in detail. XPath was a bad example but it might
still be useful to do things like:

  path_base<xpath> foo("descentant::section[ <at> id=foobar]/title")
  xml.find(foo.branch_path() / "author");
  if (foo.has_root()) ...

> > 2. Operations can be implemented selectivly for different types (No need
> > for the current messy #ifdefs)
> > bool exists( const path_base<posixfs<std::string> >& aPath);
> > bool exists( const path_base<win32fs<std::wstring> >& aPath);
> Aren't those two mutually exclusive? You have the first on POSIX systems and
> the second on the win32 systems.

Yes posixfs and win32fs are mutually exclusive but that doesn't mean that all
path types are. There might still be a need to have more than one path type in
a single application.

With the current implementation it would look like this:

bool exists(const path& aPath) {
  if (aPath.type == path::filesystem)
  else if (aPath.type == path::registry)
  else if (aPath.type == ...

It is possible to do it like that but the problem I see is that when you add a
new path type you will need to add another "if (aPath.type ==" to all
operations instead of just adding another overload.

> If so, I don't understand how I can write
> portable code -- I will have to call different function on different
> pratforms, something like:
> if (exists(win32path(p))
> #else
> if (exists(posix_path(p))
> #endif

It is easy to do a conditional typedef in the path.hpp so that you can
use "path" portable on both systems.

#include "win32fs.hpp"
typedef path_base<win32fs> path;
#include "posixfs.hpp"
typedef path_base<posixfs> path;


if (exists(path(p))

> > bool exists( const path_base<win32reg<boost::fixed_string<100> > >&
> > aPath);
> This can be handled by
> class registry {
> bool exists(const fs::path&);
> };
Don't understand what you mean. The current path implementation doesn't allow
you to handle more than one type (i.e. winfs or posixfs). You can't store a
registrypath in a fs::path since it can't handle a hkey.. root.

> Actually, I think it is very desired to have boost::path usable in more
> contexts than the filesystem. For example
> fs::path base("");
> ..... get_file(base / "foo" / "bar") .....
> would be great. But I'm just don't sure this requires all that drastic
> changes.

Why do you think it is a drastic change?
Changing operations will not take much time since it is only to move the
things inside "#ifdef BOOST_POSIX" and "#ifdef BOOST_WINDOWS" into separate
Documentation stays exactly the same (even if I personally would like to
remove the part about "portable paths").
posixfs doesn't have a root so it is basicly an empty implementation class.
win32fs requires some work but all the code is in the current path
implementation so it is mostly copy paste.

creating the path_base probably requires some thinking to make it easy to add
new types but to handle just filesystems it wouldn't take long.

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