Boost logo

Boost :

From: Carlo Wood (carlo_at_[hidden])
Date: 2004-08-30 12:53:02


On Mon, Aug 30, 2004 at 12:12:58PM -0400, Beman Dawes wrote:
> >My idea is therefore that there should be two types:
> >- An absolute/native path type
> >and
> >- A relative/portable path type
>
> We looked at that approach during initial design, and it just didn't work.
> The added complexity was really messy, yet the benefits were few.
>
> For example, what does the signature of the exists() function look like if
> there are two path types? Do we now need two exists() functions? What about
> functions that take two path arguments? Do those now need four versions?
> That might just barely be acceptable in the filesystem library itself, but
> you couldn't inflict that sort of argument explosion on user code. Instead,
> you would need a base class. That adds complexity. It just gets too messy,
> and tests to break use cases we really want to work. We really want the
> user to be able to write:
>
> if fs::exists("foo") ...
>
> rather than:
>
> if fs::exists(fs::relative_path("foo")) ...
>
> --Beman

My idea on this was (and still is) that it is possible to convert
a relative path to an absolute path (automatically) by adding an
absolute path object reference to the relative path object.
This should make sense in every application imho.

As a result, you can simply use absolute path types for all those
functions that will pass that parameter to a system call.

In the case of fs::exists, you would have only fs::exists(fs::native_path const&)
and when calling that with a fs::relative_path - it would get expanded
to the absolute path even before entering fs::exists (this expanding is
necessary anyway - so why not before you do the actual call?). That way
there is always only one function needed.

Calling fs::exists("foo") would cause the constructor fs::native_path(char const*)
to be called, in which case fs::exists would do the expansion internally
after seeing that it is not a complete path, using the fs::initial_directory()
(or whatever it was called.. the pwd). Same thing for relative_path objects
not associated with an absolute fs::native_path object already.

Recall that my proposal was that you can do either

fs::native_path np("foo%$#@!"); // A relative path using weird chars.
if (exists(np)) // Will expand `np' by prepending fs::initial_directory().

or

fs::native_path absolute_node;
fs::relative_path rp(absolute_node); // Tie `rp' to `absolute_node'.

absolute_node = "C:\Program Files";
if (exists(rp)) // Throws if absolute_node is not complete.

for the same reason, this should _throw_ and not, like
it currently does - just return false because the path doesn't exist:

fs::native_path np("/usr/src"); // Note, not possible to use fs::relative_path here (would throw).

if (exists(np)) // Should throw on cygwin (with BOOST_WINDOWS)
                                        // because the path is not complete!

Correct would be for example:

#ifdef BOOST_WINDOWS
fs::native_path root("C:/cygwin");
#else
// ...
#endif

fs::native_path np = root / "usr/src";

if (exists(np)) // Ok

-- 
Carlo Wood <carlo_at_[hidden]>

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