On Thursday, 6 June 2013 at 17:13:10 UTC, Steven Schveighoffer wrote:
On Thu, 06 Jun 2013 12:14:30 -0400, Dylan Knutson <[email protected]> wrote:

It doesn't do any allocations that the user won't have to do anyways. Paths have to be normalized before comparison; not doing so isn't correct behavior. Eg, the strings `foo../bar` != `bar`, yet they're equivalent paths. Path encapsulates the behavior. So it's the difference between

buildNormalizedPath(s1) == buildNormalizedPath(s2);

and

p1 == p2;

This can be done without allocations.

I know. There are a few additions that I've been planning to make for std.path for the longest time, I just haven't found the time to do so yet. Specifically, I want to add a couple of functions that deal with ranges of path segments rather than full path strings.

The first one is a lazy "path normaliser":

  assert (equal(pathNormalizer(["foo", "bar", "..", "baz"]),
                ["foo", "bar", "baz"]));

With this, non-allocating path comparison is easy. The verbose version of p1 == p2, which could be wrapped for convenience, is then:

  equal(pathNormalizer(pathSplitter(p1)),
        pathNormalizer(pathSplitter(p2)))

You can also use filenameCmp() as a predicate to equal() to make the comparison case-insensitive on OSes where this is expected. Very general and composable, and easily wrappable.

The second thing I'd like to add is an overload of buildPath() that takes a range of path segments. (Then buildNormalizedPath(p) can also be implemented as buildPath(pathNormalizer(p)).)

Maybe now is a good time to get this done. :)

Reply via email to