On Thursday, 6 June 2013 at 17:28:56 UTC, Steven Schveighoffer wrote:
On Thu, 06 Jun 2013 13:25:56 -0400, Lars T. Kyllingstad <[email protected]> wrote:

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.

Great! I'd highly suggest pathEqual which takes two ranges of dchar and does the composition and OS-specific comparison for you.

They don't have to be dchar if all the building blocks are templates (as the existing ones are):

bool pathEqual(CaseSensitive cs = CaseSensitive.osDefault, C1, C2)
              (const(C1)[] p1, const(C2)[] p2)
    if (isSomeChar!C1 && isSomeChar!C2)
{
    return equal!((a, b) => filenameCharCmp!cs(a, b) == 0)
                 (pathNormalizer(pathSplitter(p1)),
                  pathNormalizer(pathSplitter(p2)));
}

Reply via email to