Boost logo

Boost :

From: Thomas Witt (witt_at_[hidden])
Date: 2002-09-20 16:19:56


Beman,

On Friday 20 September 2002 02:26, Beman Dawes wrote:
>
> Also, a rooted path can be either absolute or relative.

I never said anything different. One of the key ideas of my proposal is to
seperate the notion of being rooted and being absolute.

>, as can be a
> non-rooted path.

No, a non rooted path is by my definition always a non-absolute path. In a
later posting somebody mentioned the name self_contained that's exactly what
my definition of absolute was trying to say.

Next try:
A path is absolute if it does not refer to some explicit or implicit state of
the program or operating system.

By this definition a path must have an non-empty root. This still applies to
single rooted filesytems(POSIX).

>
> We also need to be very sure of each element in the path model for the
> following cases (assume Windows). Assume leading "/" gets added to the
> grammar as "root directory".
>
> p.generic_path() has_root() has_root_dir() Elements
> ---------------- ---------- -------------- --------
> "c:" true false c:
> "/" false true /
> * "c:/" true true c:,/
> "foo" false false foo
> "/foo" false true /,foo
> "c:foo" true false c:,foo
> * "c:/foo" true true c:,/,foo
> ** "//share" true true //share
> * "//share/" true true //share,/
> * "//share/foo" true true //share,/,foo
>
> Note that the definition of is_absolute() is has_root() && has_root_dir(),
> but this may be too complicated. Maybe better to replace has_root_dir()
> above with is_absolute.
>
> I'm not 100% sure (**) is a valid case, but that isn't important.
>

I gave it some more thought. I think using has_root and has_root_dir is not
the best way to characterize paths.

Let's try something different.

A path consists of an optional root and a the real path component that
describes the way from the root to the referenced entity. For lack of a
better name I will call the real path component relative_path. Given this
definition the relative_path of a path is always non-absolute. So the
question whether a path is absolute boils down to the question whether its
root is absolute.

     p.generic_path() !p.root().empty() p.root().is_absolute() Elements
     ---------------- ---------- -------------- --------
     "c:" true false
     "/" true true(POSIX) false(WINDOWS)
    "c:/" true true
     "foo" false false foo
     "/foo" true true(POSIX) false(WINDOWS) foo
     "c:foo" true false foo
    "c:/foo" true true foo
 ** "//share" true false
    "//share/" true true
    "//share/foo" true true foo

** I am not sure about this one either.

To me this definition has another nice sideeffect. The really filesystem
specific part of the path belongs to root whereas the interpretation of the
relative_path is filesystem independent. The relative_path basically consists
of a list of names that reference edges in a tree. The interpretation of the
root string is highly system dependent (see / on Windows/Posix).

> Sometimes users will want iteration to include the root, sometimes they
> won't. Ditto root_directory(). Rather than exclude the root and/or
> root_directory from iteration, I'd say provide bool functions to say if
> they are present (has_root(), has_root_directory()), and extraction
> functions.

I really believe roots are a different thing and thus should not be part of
the iterator range. But I am not religous with regard to this. Adding a
method path const path::relative_path() to path would make this a non-issue.

>
> The case of "/" on POSIX, which is both, would need to be handled
> carefully.

See the table above for my ideas.

>
> Doesn't work. For many file systems there is not way to tell if two roots
> are equal, because of aliases.

Sure it does ;-). Seriously I think the strategy should be not to try to be
smarter than the underlying filesystem. These operators should just mirror
the semantics of the filesystem.

>
> It really seems to me that Root reduces down to a std::string, just like
> any other element in a path.

It is not about the string its about the interpretation. I agree most
implementations will most likely work with strings. The point is that in
order to effectively work with paths the user needs some portable information
about how this string is interpreted. That's the problem the root type tries
to solve.

>
> Why is_absolute() rather than is_relative()? Which would be clearer in the
> corner cases like Windows "c:foo", "/foo"?

I don't understand you here. To me is_relative is actually more confusing. On
Windows is_relative would return true for both!

>
> With composition functions like those below, the <<= and << preconditions
> can probably be tightened. You were smart to realize that:-)
>

There is another benefit the user actually can check a priori whether the
operations are meaningful for two given paths. IIUC this is not true for the
current interface.

There is another thing that is important to me. I firmly believe that the name
[make_]absolute is a bad choice for the two argument version. Merge is the
more general operation and so has the advantage of less runtime error
conditions.

>
> Notice that none of the above makes any substantial change to the current
> library. It is all additional functionality to make dealing with roots and
> relative/absolute issues much easier.

Believe me or not, this is by design.

--Thomas

-- 
Dipl.-Ing. Thomas Witt
Institut fuer Verkehrswesen, Eisenbahnbau und -betrieb, Universitaet Hannover
voice: +49(0) 511 762 - 4273, fax: +49(0) 511 762-3001
http://www.ive.uni-hannover.de

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