Path as an object in std.path
Lars T. Kyllingstad
public at kyllingen.net
Thu Jun 6 10:40:37 PDT 2013
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
> <public at kyllingen.net> 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
>>> <tcdknutson at gmail.com> 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)));
}
More information about the Digitalmars-d
mailing list