// Written in the D programming language.

/** This module is used to manipulate path strings.

    All functions, with the exception of $(LREF expandTilde) (and in some
    cases $(LREF absolutePath) and $(LREF relativePath)), are pure
    string manipulation functions; they don't depend on any state outside
    the program, nor do they perform any actual file system actions.
    This has the consequence that the module does not make any distinction
    between a path that points to a directory and a path that points to a
    file, and it does not know whether or not the object pointed to by the
    path actually exists in the file system.
    To differentiate between these cases, use $(REF isDir, std,file) and
    $(REF exists, std,file).

    Note that on Windows, both the backslash ($(D `\`)) and the slash ($(D `/`))
    are in principle valid directory separators.  This module treats them
    both on equal footing, but in cases where a $(I new) separator is
    added, a backslash will be used.  Furthermore, the $(LREF buildNormalizedPath)
    function will replace all slashes with backslashes on that platform.

    In general, the functions in this module assume that the input paths
    are well-formed.  (That is, they should not contain invalid characters,
    they should follow the file system's path format, etc.)  The result
    of calling a function on an ill-formed path is undefined.  When there
    is a chance that a path or a file name is invalid (for instance, when it
    has been input by the user), it may sometimes be desirable to use the
    $(LREF isValidFilename) and $(LREF isValidPath) functions to check
    this.

    Most functions do not perform any memory allocations, and if a string is
    returned, it is usually a slice of an input string.  If a function
    allocates, this is explicitly mentioned in the documentation.

$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE,
$(TR $(TH Category) $(TH Functions))
$(TR $(TD Normalization) $(TD
          $(LREF absolutePath)
          $(LREF asAbsolutePath)
          $(LREF asNormalizedPath)
          $(LREF asRelativePath)
          $(LREF buildNormalizedPath)
          $(LREF buildPath)
          $(LREF chainPath)
          $(LREF expandTilde)
))
$(TR $(TD Partitioning) $(TD
          $(LREF baseName)
          $(LREF dirName)
          $(LREF dirSeparator)
          $(LREF driveName)
          $(LREF pathSeparator)
          $(LREF pathSplitter)
          $(LREF relativePath)
          $(LREF rootName)
          $(LREF stripDrive)
))
$(TR $(TD Validation) $(TD
          $(LREF isAbsolute)
          $(LREF isDirSeparator)
          $(LREF isRooted)
          $(LREF isValidFilename)
          $(LREF isValidPath)
))
$(TR $(TD Extension) $(TD
          $(LREF defaultExtension)
          $(LREF extension)
          $(LREF setExtension)
          $(LREF stripExtension)
          $(LREF withDefaultExtension)
          $(LREF withExtension)
))
$(TR $(TD Other) $(TD
          $(LREF filenameCharCmp)
          $(LREF filenameCmp)
          $(LREF globMatch)
          $(LREF CaseSensitive)
))
))

    Authors:
        Lars Tandle Kyllingstad,
        $(HTTP digitalmars.com, Walter Bright),
        Grzegorz Adam Hankiewicz,
        Thomas K$(UUML)hne,
        $(HTTP erdani.org, Andrei Alexandrescu)
    Copyright:
        Copyright (c) 2000-2014, the authors. All rights reserved.
    License:
        $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
    Source:
        $(PHOBOSSRC std/path.d)
*/
module std.path;


import std.file : getcwd;
static import std.meta;
import std.range;
import std.traits;

version (OSX)
    version = Darwin;
else version (iOS)
    version = Darwin;
else version (TVOS)
    version = Darwin;
else version (WatchOS)
    version = Darwin;

version (StdUnittest)
{
private:
    struct TestAliasedString
    {
        string get() @safe @nogc pure nothrow return scope { return _s; }
        alias get this;
        @disable this(this);
        string _s;
    }

    bool testAliasedString(alias func, Args...)(scope string s, scope Args args)
    {
        return func(TestAliasedString(s), args) == func(s, args);
    }
}

/** String used to separate directory names in a path.  Under
    POSIX this is a slash, under Windows a backslash.
*/
version (Posix)          enum string dirSeparator = "/";
else version (Windows)   enum string dirSeparator = "\\";
else static assert(0, "unsupported platform");




/** Path separator string.  A colon under POSIX, a semicolon
    under Windows.
*/
version (Posix)          enum string pathSeparator = ":";
else version (Windows)   enum string pathSeparator = ";";
else static assert(0, "unsupported platform");




/** Determines whether the given character is a directory separator.

    On Windows, this includes both $(D `\`) and $(D `/`).
    On POSIX, it's just $(D `/`).
*/
bool isDirSeparator(dchar c)  @safe pure nothrow @nogc
{
    if (c == '/') return true;
    version (Windows) if (c == '\\') return true;
    return false;
}

///
@safe pure nothrow @nogc unittest
{
    version (Windows)
    {
        assert( '/'.isDirSeparator);
        assert( '\\'.isDirSeparator);
    }
    else
    {
        assert( '/'.isDirSeparator);
        assert(!'\\'.isDirSeparator);
    }
}


/*  Determines whether the given character is a drive separator.

    On Windows, this is true if c is the ':' character that separates
    the drive letter from the rest of the path.  On POSIX, this always
    returns false.
*/
private bool isDriveSeparator(dchar c)  @safe pure nothrow @nogc
{
    version (Windows) return c == ':';
    else return false;
}


/*  Combines the isDirSeparator and isDriveSeparator tests. */
version (Windows) private bool isSeparator(dchar c)  @safe pure nothrow @nogc
{
    return isDirSeparator(c) || isDriveSeparator(c);
}
version (Posix) private alias isSeparator = isDirSeparator;


/*  Helper function that determines the position of the last
    drive/directory separator in a string.  Returns -1 if none
    is found.
*/
private ptrdiff_t lastSeparator(R)(R path)
if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
    isNarrowString!R)
{
    auto i = (cast(ptrdiff_t) path.length) - 1;
    while (i >= 0 && !isSeparator(path[i])) --i;
    return i;
}


version (Windows)
{
    private bool isUNC(R)(R path)
    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
        isNarrowString!R)
    {
        return path.length >= 3 && isDirSeparator(path[0]) && isDirSeparator(path[1])
            && !isDirSeparator(path[2]);
    }

    private ptrdiff_t uncRootLength(R)(R path)
    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
        isNarrowString!R)
        in { assert(isUNC(path)); }
        do
    {
        ptrdiff_t i = 3;
        while (i < path.length && !isDirSeparator(path[i])) ++i;
        if (i < path.length)
        {
            auto j = i;
            do { ++j; } while (j < path.length && isDirSeparator(path[j]));
            if (j < path.length)
            {
                do { ++j; } while (j < path.length && !isDirSeparator(path[j]));
                i = j;
            }
        }
        return i;
    }

    private bool hasDrive(R)(R path)
    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
        isNarrowString!R)
    {
        return path.length >= 2 && isDriveSeparator(path[1]);
    }

    private bool isDriveRoot(R)(R path)
    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
        isNarrowString!R)
    {
        return path.length >= 3 && isDriveSeparator(path[1])
            && isDirSeparator(path[2]);
    }
}


/*  Helper functions that strip leading/trailing slashes and backslashes
    from a path.
*/
private auto ltrimDirSeparators(R)(R path)
if (isSomeFiniteCharInputRange!R || isNarrowString!R)
{
    static if (isRandomAccessRange!R && hasSlicing!R || isNarrowString!R)
    {
        int i = 0;
        while (i < path.length && isDirSeparator(path[i]))
            ++i;
        return path[i .. path.length];
    }
    else
    {
        while (!path.empty && isDirSeparator(path.front))
            path.popFront();
        return path;
    }
}

@safe unittest
{
    import std.array;
    import std.utf : byDchar;

    assert(ltrimDirSeparators("//abc//").array == "abc//");
    assert(ltrimDirSeparators("//abc//"d).array == "abc//"d);
    assert(ltrimDirSeparators("//abc//".byDchar).array == "abc//"d);
}

private auto rtrimDirSeparators(R)(R path)
if (isBidirectionalRange!R && isSomeChar!(ElementType!R) ||
    isNarrowString!R)
{
    static if (isRandomAccessRange!R && hasSlicing!R && hasLength!R || isNarrowString!R)
    {
        auto i = (cast(ptrdiff_t) path.length) - 1;
        while (i >= 0 && isDirSeparator(path[i]))
            --i;
        return path[0 .. i+1];
    }
    else
    {
        while (!path.empty && isDirSeparator(path.back))
            path.popBack();
        return path;
    }
}

@safe unittest
{
    import std.array;
    import std.utf : byDchar;

    assert(rtrimDirSeparators("//abc//").array == "//abc");
    assert(rtrimDirSeparators("//abc//"d).array == "//abc"d);

    assert(rtrimDirSeparators(MockBiRange!char("//abc//")).array == "//abc");
}

private auto trimDirSeparators(R)(R path)
if (isBidirectionalRange!R && isSomeChar!(ElementType!R) ||
    isNarrowString!R)
{
    return ltrimDirSeparators(rtrimDirSeparators(path));
}

@safe unittest
{
    import std.array;
    import std.utf : byDchar;

    assert(trimDirSeparators("//abc//").array == "abc");
    assert(trimDirSeparators("//abc//"d).array == "abc"d);

    assert(trimDirSeparators(MockBiRange!char("//abc//")).array == "abc");
}

/** This `enum` is used as a template argument to functions which
    compare file names, and determines whether the comparison is
    case sensitive or not.
*/
enum CaseSensitive : bool
{
    /// File names are case insensitive
    no = false,

    /// File names are case sensitive
    yes = true,

    /** The default (or most common) setting for the current platform.
        That is, `no` on Windows and Mac OS X, and `yes` on all
        POSIX systems except Darwin (Linux, *BSD, etc.).
    */
    osDefault = osDefaultCaseSensitivity
}

///
@safe unittest
{
    assert(baseName!(CaseSensitive.no)("dir/file.EXT", ".ext") == "file");
    assert(baseName!(CaseSensitive.yes)("dir/file.EXT", ".ext") != "file");

    version (Posix)
        assert(relativePath!(CaseSensitive.no)("/FOO/bar", "/foo/baz") == "../bar");
    else
        assert(relativePath!(CaseSensitive.no)(`c:\FOO\bar`, `c:\foo\baz`) == `..\bar`);
}

version (Windows)     private enum osDefaultCaseSensitivity = false;
else version (Darwin) private enum osDefaultCaseSensitivity = false;
else version (Posix)  private enum osDefaultCaseSensitivity = true;
else static assert(0);

/**
    Params:
        cs = Whether or not suffix matching is case-sensitive.
        path = A path name. It can be a string, or any random-access range of
            characters.
        suffix = An optional suffix to be removed from the file name.
    Returns: The name of the file in the path name, without any leading
        directory and with an optional suffix chopped off.

    If `suffix` is specified, it will be compared to `path`
    using `filenameCmp!cs`,
    where `cs` is an optional template parameter determining whether
    the comparison is case sensitive or not.  See the
    $(LREF filenameCmp) documentation for details.

    Note:
    This function $(I only) strips away the specified suffix, which
    doesn't necessarily have to represent an extension.
    To remove the extension from a path, regardless of what the extension
    is, use $(LREF stripExtension).
    To obtain the filename without leading directories and without
    an extension, combine the functions like this:
    ---
    assert(baseName(stripExtension("dir/file.ext")) == "file");
    ---

    Standards:
    This function complies with
    $(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/basename.html,
    the POSIX requirements for the 'basename' shell utility)
    (with suitable adaptations for Windows paths).
*/
auto baseName(R)(return scope R path)
if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R)
{
    return _baseName(path);
}

/// ditto
auto baseName(C)(return scope C[] path)
if (isSomeChar!C)
{
    return _baseName(path);
}

/// ditto
inout(C)[] baseName(CaseSensitive cs = CaseSensitive.osDefault, C, C1)
    (return scope inout(C)[] path, in C1[] suffix)
    @safe pure //TODO: nothrow (because of filenameCmp())
if (isSomeChar!C && isSomeChar!C1)
{
    auto p = baseName(path);
    if (p.length > suffix.length
        && filenameCmp!cs(cast(const(C)[])p[$-suffix.length .. $], suffix) == 0)
    {
        return p[0 .. $-suffix.length];
    }
    else return p;
}

///
@safe unittest
{
    assert(baseName("dir/file.ext") == "file.ext");
    assert(baseName("dir/file.ext", ".ext") == "file");
    assert(baseName("dir/file.ext", ".xyz") == "file.ext");
    assert(baseName("dir/filename", "name") == "file");
    assert(baseName("dir/subdir/") == "subdir");

    version (Windows)
    {
        assert(baseName(`d:file.ext`) == "file.ext");
        assert(baseName(`d:\dir\file.ext`) == "file.ext");
    }
}

@safe unittest
{
    assert(baseName("").empty);
    assert(baseName("file.ext"w) == "file.ext");
    assert(baseName("file.ext"d, ".ext") == "file");
    assert(baseName("file", "file"w.dup) == "file");
    assert(baseName("dir/file.ext"d.dup) == "file.ext");
    assert(baseName("dir/file.ext", ".ext"d) == "file");
    assert(baseName("dir/file"w, "file"d) == "file");
    assert(baseName("dir///subdir////") == "subdir");
    assert(baseName("dir/subdir.ext/", ".ext") == "subdir");
    assert(baseName("dir/subdir/".dup, "subdir") == "subdir");
    assert(baseName("/"w.dup) == "/");
    assert(baseName("//"d.dup) == "/");
    assert(baseName("///") == "/");

    assert(baseName!(CaseSensitive.yes)("file.ext", ".EXT") == "file.ext");
    assert(baseName!(CaseSensitive.no)("file.ext", ".EXT") == "file");

    {
        auto r = MockRange!(immutable(char))(`dir/file.ext`);
        auto s = r.baseName();
        foreach (i, c; `file`)
            assert(s[i] == c);
    }

    version (Windows)
    {
        assert(baseName(`dir\file.ext`) == `file.ext`);
        assert(baseName(`dir\file.ext`, `.ext`) == `file`);
        assert(baseName(`dir\file`, `file`) == `file`);
        assert(baseName(`d:file.ext`) == `file.ext`);
        assert(baseName(`d:file.ext`, `.ext`) == `file`);
        assert(baseName(`d:file`, `file`) == `file`);
        assert(baseName(`dir\\subdir\\\`) == `subdir`);
        assert(baseName(`dir\subdir.ext\`, `.ext`) == `subdir`);
        assert(baseName(`dir\subdir\`, `subdir`) == `subdir`);
        assert(baseName(`\`) == `\`);
        assert(baseName(`\\`) == `\`);
        assert(baseName(`\\\`) == `\`);
        assert(baseName(`d:\`) == `\`);
        assert(baseName(`d:`).empty);
        assert(baseName(`\\server\share\file`) == `file`);
        assert(baseName(`\\server\share\`) == `\`);
        assert(baseName(`\\server\share`) == `\`);

        auto r = MockRange!(immutable(char))(`\\server\share`);
        auto s = r.baseName();
        foreach (i, c; `\`)
            assert(s[i] == c);
    }

    assert(baseName(stripExtension("dir/file.ext")) == "file");

    static assert(baseName("dir/file.ext") == "file.ext");
    static assert(baseName("dir/file.ext", ".ext") == "file");

    static struct DirEntry { string s; alias s this; }
    assert(baseName(DirEntry("dir/file.ext")) == "file.ext");
}

@safe unittest
{
    assert(testAliasedString!baseName("file"));

    enum S : string { a = "file/path/to/test" }
    assert(S.a.baseName == "test");

    char[S.a.length] sa = S.a[];
    assert(sa.baseName == "test");
}

private R _baseName(R)(return scope R path)
if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) || isNarrowString!R)
{
    auto p1 = stripDrive(path);
    if (p1.empty)
    {
        version (Windows) if (isUNC(path))
            return path[0 .. 1];
        static if (isSomeString!R)
            return null;
        else
            return p1; // which is empty
    }

    auto p2 = rtrimDirSeparators(p1);
    if (p2.empty) return p1[0 .. 1];

    return p2[lastSeparator(p2)+1 .. p2.length];
}

/** Returns the parent directory of `path`. On Windows, this
    includes the drive letter if present. If `path` is a relative path and
    the parent directory is the current working directory, returns `"."`.

    Params:
        path = A path name.

    Returns:
        A slice of `path` or `"."`.

    Standards:
    This function complies with
    $(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html,
    the POSIX requirements for the 'dirname' shell utility)
    (with suitable adaptations for Windows paths).
*/
auto dirName(R)(return scope R path)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)
{
    return _dirName(path);
}

/// ditto
auto dirName(C)(return scope C[] path)
if (isSomeChar!C)
{
    return _dirName(path);
}

///
@safe unittest
{
    assert(dirName("") == ".");
    assert(dirName("file"w) == ".");
    assert(dirName("dir/"d) == ".");
    assert(dirName("dir///") == ".");
    assert(dirName("dir/file"w.dup) == "dir");
    assert(dirName("dir///file"d.dup) == "dir");
    assert(dirName("dir/subdir/") == "dir");
    assert(dirName("/dir/file"w) == "/dir");
    assert(dirName("/file"d) == "/");
    assert(dirName("/") == "/");
    assert(dirName("///") == "/");

    version (Windows)
    {
        assert(dirName(`dir\`) == `.`);
        assert(dirName(`dir\\\`) == `.`);
        assert(dirName(`dir\file`) == `dir`);
        assert(dirName(`dir\\\file`) == `dir`);
        assert(dirName(`dir\subdir\`) == `dir`);
        assert(dirName(`\dir\file`) == `\dir`);
        assert(dirName(`\file`) == `\`);
        assert(dirName(`\`) == `\`);
        assert(dirName(`\\\`) == `\`);
        assert(dirName(`d:`) == `d:`);
        assert(dirName(`d:file`) == `d:`);
        assert(dirName(`d:\`) == `d:\`);
        assert(dirName(`d:\file`) == `d:\`);
        assert(dirName(`d:\dir\file`) == `d:\dir`);
        assert(dirName(`\\server\share\dir\file`) == `\\server\share\dir`);
        assert(dirName(`\\server\share\file`) == `\\server\share`);
        assert(dirName(`\\server\share\`) == `\\server\share`);
        assert(dirName(`\\server\share`) == `\\server\share`);
    }
}

@safe unittest
{
    assert(testAliasedString!dirName("file"));

    enum S : string { a = "file/path/to/test" }
    assert(S.a.dirName == "file/path/to");

    char[S.a.length] sa = S.a[];
    assert(sa.dirName == "file/path/to");
}

@safe unittest
{
    static assert(dirName("dir/file") == "dir");

    import std.array;
    import std.utf : byChar, byWchar, byDchar;

    assert(dirName("".byChar).array == ".");
    assert(dirName("file"w.byWchar).array == "."w);
    assert(dirName("dir/"d.byDchar).array == "."d);
    assert(dirName("dir///".byChar).array == ".");
    assert(dirName("dir/subdir/".byChar).array == "dir");
    assert(dirName("/dir/file"w.byWchar).array == "/dir"w);
    assert(dirName("/file"d.byDchar).array == "/"d);
    assert(dirName("/".byChar).array == "/");
    assert(dirName("///".byChar).array == "/");

    version (Windows)
    {
        assert(dirName(`dir\`.byChar).array == `.`);
        assert(dirName(`dir\\\`.byChar).array == `.`);
        assert(dirName(`dir\file`.byChar).array == `dir`);
        assert(dirName(`dir\\\file`.byChar).array == `dir`);
        assert(dirName(`dir\subdir\`.byChar).array == `dir`);
        assert(dirName(`\dir\file`.byChar).array == `\dir`);
        assert(dirName(`\file`.byChar).array == `\`);
        assert(dirName(`\`.byChar).array == `\`);
        assert(dirName(`\\\`.byChar).array == `\`);
        assert(dirName(`d:`.byChar).array == `d:`);
        assert(dirName(`d:file`.byChar).array == `d:`);
        assert(dirName(`d:\`.byChar).array == `d:\`);
        assert(dirName(`d:\file`.byChar).array == `d:\`);
        assert(dirName(`d:\dir\file`.byChar).array == `d:\dir`);
        assert(dirName(`\\server\share\dir\file`.byChar).array == `\\server\share\dir`);
        assert(dirName(`\\server\share\file`) == `\\server\share`);
        assert(dirName(`\\server\share\`.byChar).array == `\\server\share`);
        assert(dirName(`\\server\share`.byChar).array == `\\server\share`);
    }

    //static assert(dirName("dir/file".byChar).array == "dir");
}

private auto _dirName(R)(return scope R path)
{
    static auto result(bool dot, typeof(path[0 .. 1]) p)
    {
        static if (isSomeString!R)
            return dot ? "." : p;
        else
        {
            import std.range : choose, only;
            return choose(dot, only(cast(ElementEncodingType!R)'.'), p);
        }
    }

    if (path.empty)
        return result(true, path[0 .. 0]);

    auto p = rtrimDirSeparators(path);
    if (p.empty)
        return result(false, path[0 .. 1]);

    version (Windows)
    {
        if (isUNC(p) && uncRootLength(p) == p.length)
            return result(false, p);

        if (p.length == 2 && isDriveSeparator(p[1]) && path.length > 2)
            return result(false, path[0 .. 3]);
    }

    auto i = lastSeparator(p);
    if (i == -1)
        return result(true, p);
    if (i == 0)
        return result(false, p[0 .. 1]);

    version (Windows)
    {
        // If the directory part is either d: or d:\
        // do not chop off the last symbol.
        if (isDriveSeparator(p[i]) || isDriveSeparator(p[i-1]))
            return result(false, p[0 .. i+1]);
    }
    // Remove any remaining trailing (back)slashes.
    return result(false, rtrimDirSeparators(p[0 .. i]));
}

/** Returns the root directory of the specified path, or `null` if the
    path is not rooted.

    Params:
        path = A path name.

    Returns:
        A slice of `path`.
*/
auto rootName(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)
{
    return _rootName(path);
}

/// ditto
auto rootName(C)(C[] path)
if (isSomeChar!C)
{
    return _rootName(path);
}

///
@safe unittest
{
    assert(rootName("") is null);
    assert(rootName("foo") is null);
    assert(rootName("/") == "/");
    assert(rootName("/foo/bar") == "/");

    version (Windows)
    {
        assert(rootName("d:foo") is null);
        assert(rootName(`d:\foo`) == `d:\`);
        assert(rootName(`\\server\share\foo`) == `\\server\share`);
        assert(rootName(`\\server\share`) == `\\server\share`);
    }
}

@safe unittest
{
    assert(testAliasedString!rootName("/foo/bar"));

    enum S : string { a = "/foo/bar" }
    assert(S.a.rootName == "/");

    char[S.a.length] sa = S.a[];
    assert(sa.rootName == "/");
}

@safe unittest
{
    import std.array;
    import std.utf : byChar;

    assert(rootName("".byChar).array == "");
    assert(rootName("foo".byChar).array == "");
    assert(rootName("/".byChar).array == "/");
    assert(rootName("/foo/bar".byChar).array == "/");

    version (Windows)
    {
        assert(rootName("d:foo".byChar).array == "");
        assert(rootName(`d:\foo`.byChar).array == `d:\`);
        assert(rootName(`\\server\share\foo`.byChar).array == `\\server\share`);
        assert(rootName(`\\server\share`.byChar).array == `\\server\share`);
    }
}

private auto _rootName(R)(R path)
{
    if (path.empty)
        goto Lnull;

    version (Posix)
    {
        if (isDirSeparator(path[0])) return path[0 .. 1];
    }
    else version (Windows)
    {
        if (isDirSeparator(path[0]))
        {
            if (isUNC(path)) return path[0 .. uncRootLength(path)];
            else return path[0 .. 1];
        }
        else if (path.length >= 3 && isDriveSeparator(path[1]) &&
            isDirSeparator(path[2]))
        {
            return path[0 .. 3];
        }
    }
    else static assert(0, "unsupported platform");

    assert(!isRooted(path));
Lnull:
    static if (is(StringTypeOf!R))
        return null; // legacy code may rely on null return rather than slice
    else
        return path[0 .. 0];
}

/**
    Get the drive portion of a path.

    Params:
        path = string or range of characters

    Returns:
        A slice of `path` that is the drive, or an empty range if the drive
        is not specified.  In the case of UNC paths, the network share
        is returned.

        Always returns an empty range on POSIX.
*/
auto driveName(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)
{
    return _driveName(path);
}

/// ditto
auto driveName(C)(C[] path)
if (isSomeChar!C)
{
    return _driveName(path);
}

///
@safe unittest
{
    import std.range : empty;
    version (Posix)  assert(driveName("c:/foo").empty);
    version (Windows)
    {
        assert(driveName(`dir\file`).empty);
        assert(driveName(`d:file`) == "d:");
        assert(driveName(`d:\file`) == "d:");
        assert(driveName("d:") == "d:");
        assert(driveName(`\\server\share\file`) == `\\server\share`);
        assert(driveName(`\\server\share\`) == `\\server\share`);
        assert(driveName(`\\server\share`) == `\\server\share`);

        static assert(driveName(`d:\file`) == "d:");
    }
}

@safe unittest
{
    assert(testAliasedString!driveName("d:/file"));

    version (Posix)
        immutable result = "";
    else version (Windows)
        immutable result = "d:";

    enum S : string { a = "d:/file" }
    assert(S.a.driveName == result);

    char[S.a.length] sa = S.a[];
    assert(sa.driveName == result);
}

@safe unittest
{
    import std.array;
    import std.utf : byChar;

    version (Posix)  assert(driveName("c:/foo".byChar).empty);
    version (Windows)
    {
        assert(driveName(`dir\file`.byChar).empty);
        assert(driveName(`d:file`.byChar).array == "d:");
        assert(driveName(`d:\file`.byChar).array == "d:");
        assert(driveName("d:".byChar).array == "d:");
        assert(driveName(`\\server\share\file`.byChar).array == `\\server\share`);
        assert(driveName(`\\server\share\`.byChar).array == `\\server\share`);
        assert(driveName(`\\server\share`.byChar).array == `\\server\share`);

        static assert(driveName(`d:\file`).array == "d:");
    }
}

private auto _driveName(R)(R path)
{
    version (Windows)
    {
        if (hasDrive(path))
            return path[0 .. 2];
        else if (isUNC(path))
            return path[0 .. uncRootLength(path)];
    }
    static if (isSomeString!R)
        return cast(ElementEncodingType!R[]) null; // legacy code may rely on null return rather than slice
    else
        return path[0 .. 0];
}

/** Strips the drive from a Windows path.  On POSIX, the path is returned
    unaltered.

    Params:
        path = A pathname

    Returns: A slice of path without the drive component.
*/
auto stripDrive(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R)
{
    return _stripDrive(path);
}

/// ditto
auto stripDrive(C)(C[] path)
if (isSomeChar!C)
{
    return _stripDrive(path);
}

///
@safe unittest
{
    version (Windows)
    {
        assert(stripDrive(`d:\dir\file`) == `\dir\file`);
        assert(stripDrive(`\\server\share\dir\file`) == `\dir\file`);
    }
}

@safe unittest
{
    assert(testAliasedString!stripDrive("d:/dir/file"));

    version (Posix)
        immutable result = "d:/dir/file";
    else version (Windows)
        immutable result = "/dir/file";

    enum S : string { a = "d:/dir/file" }
    assert(S.a.stripDrive == result);

    char[S.a.length] sa = S.a[];
    assert(sa.stripDrive == result);
}

@safe unittest
{
    version (Windows)
    {
        assert(stripDrive(`d:\dir\file`) == `\dir\file`);
        assert(stripDrive(`\\server\share\dir\file`) == `\dir\file`);
        static assert(stripDrive(`d:\dir\file`) == `\dir\file`);

        auto r = MockRange!(immutable(char))(`d:\dir\file`);
        auto s = r.stripDrive();
        foreach (i, c; `\dir\file`)
            assert(s[i] == c);
    }
    version (Posix)
    {
        assert(stripDrive(`d:\dir\file`) == `d:\dir\file`);

        auto r = MockRange!(immutable(char))(`d:\dir\file`);
        auto s = r.stripDrive();
        foreach (i, c; `d:\dir\file`)
            assert(s[i] == c);
    }
}

private auto _stripDrive(R)(R path)
{
    version (Windows)
    {
        if (hasDrive!(BaseOf!R)(path))      return path[2 .. path.length];
        else if (isUNC!(BaseOf!R)(path))    return path[uncRootLength!(BaseOf!R)(path) .. path.length];
    }
    return path;
}


/*  Helper function that returns the position of the filename/extension
    separator dot in path.

    Params:
        path = file spec as string or indexable range
    Returns:
        index of extension separator (the dot), or -1 if not found
*/
private ptrdiff_t extSeparatorPos(R)(const R path)
if (isRandomAccessRange!R && hasLength!R && isSomeChar!(ElementType!R) ||
    isNarrowString!R)
{
    for (auto i = path.length; i-- > 0 && !isSeparator(path[i]); )
    {
        if (path[i] == '.' && i > 0 && !isSeparator(path[i-1]))
            return i;
    }
    return -1;
}

@safe unittest
{
    assert(extSeparatorPos("file") == -1);
    assert(extSeparatorPos("file.ext"w) == 4);
    assert(extSeparatorPos("file.ext1.ext2"d) == 9);
    assert(extSeparatorPos(".foo".dup) == -1);
    assert(extSeparatorPos(".foo.ext"w.dup) == 4);
}

@safe unittest
{
    assert(extSeparatorPos("dir/file"d.dup) == -1);
    assert(extSeparatorPos("dir/file.ext") == 8);
    assert(extSeparatorPos("dir/file.ext1.ext2"w) == 13);
    assert(extSeparatorPos("dir/.foo"d) == -1);
    assert(extSeparatorPos("dir/.foo.ext".dup) == 8);

    version (Windows)
    {
        assert(extSeparatorPos("dir\\file") == -1);
        assert(extSeparatorPos("dir\\file.ext") == 8);
        assert(extSeparatorPos("dir\\file.ext1.ext2") == 13);
        assert(extSeparatorPos("dir\\.foo") == -1);
        assert(extSeparatorPos("dir\\.foo.ext") == 8);

        assert(extSeparatorPos("d:file") == -1);
        assert(extSeparatorPos("d:file.ext") == 6);
        assert(extSeparatorPos("d:file.ext1.ext2") == 11);
        assert(extSeparatorPos("d:.foo") == -1);
        assert(extSeparatorPos("d:.foo.ext") == 6);
    }

    static assert(extSeparatorPos("file") == -1);
    static assert(extSeparatorPos("file.ext"w) == 4);
}


/**
    Params: path = A path name.
    Returns: The _extension part of a file name, including the dot.

    If there is no _extension, `null` is returned.
*/
auto extension(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) ||
    is(StringTypeOf!R))
{
    auto i = extSeparatorPos!(BaseOf!R)(path);
    if (i == -1)
    {
        static if (is(StringTypeOf!R))
            return StringTypeOf!R.init[];   // which is null
        else
            return path[0 .. 0];
    }
    else return path[i .. path.length];
}

///
@safe unittest
{
    import std.range : empty;
    assert(extension("file").empty);
    assert(extension("file.") == ".");
    assert(extension("file.ext"w) == ".ext");
    assert(extension("file.ext1.ext2"d) == ".ext2");
    assert(extension(".foo".dup).empty);
    assert(extension(".foo.ext"w.dup) == ".ext");

    static assert(extension("file").empty);
    static assert(extension("file.ext") == ".ext");
}

@safe unittest
{
    {
        auto r = MockRange!(immutable(char))(`file.ext1.ext2`);
        auto s = r.extension();
        foreach (i, c; `.ext2`)
            assert(s[i] == c);
    }

    static struct DirEntry { string s; alias s this; }
    assert(extension(DirEntry("file")).empty);
}


/** Remove extension from path.

    Params:
        path = string or range to be sliced

    Returns:
        slice of path with the extension (if any) stripped off
*/
auto stripExtension(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)
{
    return _stripExtension(path);
}

/// Ditto
auto stripExtension(C)(C[] path)
if (isSomeChar!C)
{
    return _stripExtension(path);
}

///
@safe unittest
{
    assert(stripExtension("file")           == "file");
    assert(stripExtension("file.ext")       == "file");
    assert(stripExtension("file.ext1.ext2") == "file.ext1");
    assert(stripExtension("file.")          == "file");
    assert(stripExtension(".file")          == ".file");
    assert(stripExtension(".file.ext")      == ".file");
    assert(stripExtension("dir/file.ext")   == "dir/file");
}

@safe unittest
{
    assert(testAliasedString!stripExtension("file"));

    enum S : string { a = "foo.bar" }
    assert(S.a.stripExtension == "foo");

    char[S.a.length] sa = S.a[];
    assert(sa.stripExtension == "foo");
}

@safe unittest
{
    assert(stripExtension("file.ext"w) == "file");
    assert(stripExtension("file.ext1.ext2"d) == "file.ext1");

    import std.array;
    import std.utf : byChar, byWchar, byDchar;

    assert(stripExtension("file".byChar).array == "file");
    assert(stripExtension("file.ext"w.byWchar).array == "file");
    assert(stripExtension("file.ext1.ext2"d.byDchar).array == "file.ext1");
}

private auto _stripExtension(R)(R path)
{
    immutable i = extSeparatorPos(path);
    return i == -1 ? path : path[0 .. i];
}

/** Sets or replaces an extension.

    If the filename already has an extension, it is replaced. If not, the
    extension is simply appended to the filename. Including a leading dot
    in `ext` is optional.

    If the extension is empty, this function is equivalent to
    $(LREF stripExtension).

    This function normally allocates a new string (the possible exception
    being the case when path is immutable and doesn't already have an
    extension).

    Params:
        path = A path name
        ext = The new extension

    Returns: A string containing the path given by `path`, but where
    the extension has been set to `ext`.

    See_Also:
        $(LREF withExtension) which does not allocate and returns a lazy range.
*/
immutable(C1)[] setExtension(C1, C2)(in C1[] path, in C2[] ext)
if (isSomeChar!C1 && !is(C1 == immutable) && is(immutable C1 == immutable C2))
{
    try
    {
        import std.conv : to;
        return withExtension(path, ext).to!(typeof(return));
    }
    catch (Exception e)
    {
        assert(0);
    }
}

///ditto
immutable(C1)[] setExtension(C1, C2)(immutable(C1)[] path, const(C2)[] ext)
if (isSomeChar!C1 && is(immutable C1 == immutable C2))
{
    if (ext.length == 0)
        return stripExtension(path);

    try
    {
        import std.conv : to;
        return withExtension(path, ext).to!(typeof(return));
    }
    catch (Exception e)
    {
        assert(0);
    }
}

///
@safe unittest
{
    assert(setExtension("file", "ext") == "file.ext");
    assert(setExtension("file"w, ".ext"w) == "file.ext");
    assert(setExtension("file."d, "ext"d) == "file.ext");
    assert(setExtension("file.", ".ext") == "file.ext");
    assert(setExtension("file.old"w, "new"w) == "file.new");
    assert(setExtension("file.old"d, ".new"d) == "file.new");
}

@safe unittest
{
    assert(setExtension("file"w.dup, "ext"w) == "file.ext");
    assert(setExtension("file"w.dup, ".ext"w) == "file.ext");
    assert(setExtension("file."w, "ext"w.dup) == "file.ext");
    assert(setExtension("file."w, ".ext"w.dup) == "file.ext");
    assert(setExtension("file.old"d.dup, "new"d) == "file.new");
    assert(setExtension("file.old"d.dup, ".new"d) == "file.new");

    static assert(setExtension("file", "ext") == "file.ext");
    static assert(setExtension("file.old", "new") == "file.new");

    static assert(setExtension("file"w.dup, "ext"w) == "file.ext");
    static assert(setExtension("file.old"d.dup, "new"d) == "file.new");

    // https://issues.dlang.org/show_bug.cgi?id=10601
    assert(setExtension("file", "") == "file");
    assert(setExtension("file.ext", "") == "file");
}

/************
 * Replace existing extension on filespec with new one.
 *
 * Params:
 *      path = string or random access range representing a filespec
 *      ext = the new extension
 * Returns:
 *      Range with `path`'s extension (if any) replaced with `ext`.
 *      The element encoding type of the returned range will be the same as `path`'s.
 * See_Also:
 *      $(LREF setExtension)
 */
auto withExtension(R, C)(R path, C[] ext)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) &&
    !isSomeString!R && isSomeChar!C)
{
    return _withExtension(path, ext);
}

/// Ditto
auto withExtension(C1, C2)(C1[] path, C2[] ext)
if (isSomeChar!C1 && isSomeChar!C2)
{
    return _withExtension(path, ext);
}

///
@safe unittest
{
    import std.array;
    assert(withExtension("file", "ext").array == "file.ext");
    assert(withExtension("file"w, ".ext"w).array == "file.ext");
    assert(withExtension("file.ext"w, ".").array == "file.");

    import std.utf : byChar, byWchar;
    assert(withExtension("file".byChar, "ext").array == "file.ext");
    assert(withExtension("file"w.byWchar, ".ext"w).array == "file.ext"w);
    assert(withExtension("file.ext"w.byWchar, ".").array == "file."w);
}

@safe unittest
{
    import std.algorithm.comparison : equal;

    assert(testAliasedString!withExtension("file", "ext"));

    enum S : string { a = "foo.bar" }
    assert(equal(S.a.withExtension(".txt"), "foo.txt"));

    char[S.a.length] sa = S.a[];
    assert(equal(sa.withExtension(".txt"), "foo.txt"));
}

private auto _withExtension(R, C)(R path, C[] ext)
{
    import std.range : only, chain;
    import std.utf : byUTF;

    alias CR = Unqual!(ElementEncodingType!R);
    auto dot = only(CR('.'));
    if (ext.length == 0 || ext[0] == '.')
        dot.popFront();                 // so dot is an empty range, too
    return chain(stripExtension(path).byUTF!CR, dot, ext.byUTF!CR);
}

/** Params:
        path = A path name.
        ext = The default extension to use.

    Returns: The path given by `path`, with the extension given by `ext`
    appended if the path doesn't already have one.

    Including the dot in the extension is optional.

    This function always allocates a new string, except in the case when
    path is immutable and already has an extension.
*/
immutable(C1)[] defaultExtension(C1, C2)(in C1[] path, in C2[] ext)
if (isSomeChar!C1 && is(immutable C1 == immutable C2))
{
    import std.conv : to;
    return withDefaultExtension(path, ext).to!(typeof(return));
}

///
@safe unittest
{
    assert(defaultExtension("file", "ext") == "file.ext");
    assert(defaultExtension("file", ".ext") == "file.ext");
    assert(defaultExtension("file.", "ext")     == "file.");
    assert(defaultExtension("file.old", "new") == "file.old");
    assert(defaultExtension("file.old", ".new") == "file.old");
}

@safe unittest
{
    assert(defaultExtension("file"w.dup, "ext"w) == "file.ext");
    assert(defaultExtension("file.old"d.dup, "new"d) == "file.old");

    static assert(defaultExtension("file", "ext") == "file.ext");
    static assert(defaultExtension("file.old", "new") == "file.old");

    static assert(defaultExtension("file"w.dup, "ext"w) == "file.ext");
    static assert(defaultExtension("file.old"d.dup, "new"d) == "file.old");
}


/********************************
 * Set the extension of `path` to `ext` if `path` doesn't have one.
 *
 * Params:
 *      path = filespec as string or range
 *      ext = extension, may have leading '.'
 * Returns:
 *      range with the result
 */
auto withDefaultExtension(R, C)(R path, C[] ext)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) &&
    !isSomeString!R && isSomeChar!C)
{
    return _withDefaultExtension(path, ext);
}

/// Ditto
auto withDefaultExtension(C1, C2)(C1[] path, C2[] ext)
if (isSomeChar!C1 && isSomeChar!C2)
{
    return _withDefaultExtension(path, ext);
}

///
@safe unittest
{
    import std.array;
    assert(withDefaultExtension("file", "ext").array == "file.ext");
    assert(withDefaultExtension("file"w, ".ext").array == "file.ext"w);
    assert(withDefaultExtension("file.", "ext").array == "file.");
    assert(withDefaultExtension("file", "").array == "file.");

    import std.utf : byChar, byWchar;
    assert(withDefaultExtension("file".byChar, "ext").array == "file.ext");
    assert(withDefaultExtension("file"w.byWchar, ".ext").array == "file.ext"w);
    assert(withDefaultExtension("file.".byChar, "ext"d).array == "file.");
    assert(withDefaultExtension("file".byChar, "").array == "file.");
}

@safe unittest
{
    import std.algorithm.comparison : equal;

    assert(testAliasedString!withDefaultExtension("file", "ext"));

    enum S : string { a = "foo" }
    assert(equal(S.a.withDefaultExtension(".txt"), "foo.txt"));

    char[S.a.length] sa = S.a[];
    assert(equal(sa.withDefaultExtension(".txt"), "foo.txt"));
}

private auto _withDefaultExtension(R, C)(R path, C[] ext)
{
    import std.range : only, chain;
    import std.utf : byUTF;

    alias CR = Unqual!(ElementEncodingType!R);
    auto dot = only(CR('.'));
    immutable i = extSeparatorPos(path);
    if (i == -1)
    {
        if (ext.length > 0 && ext[0] == '.')
            ext = ext[1 .. $];              // remove any leading . from ext[]
    }
    else
    {
        // path already has an extension, so make these empty
        ext = ext[0 .. 0];
        dot.popFront();
    }
    return chain(path.byUTF!CR, dot, ext.byUTF!CR);
}

/** Combines one or more path segments.

    This function takes a set of path segments, given as an input
    range of string elements or as a set of string arguments,
    and concatenates them with each other.  Directory separators
    are inserted between segments if necessary.  If any of the
    path segments are absolute (as defined by $(LREF isAbsolute)), the
    preceding segments will be dropped.

    On Windows, if one of the path segments are rooted, but not absolute
    (e.g. $(D `\foo`)), all preceding path segments down to the previous
    root will be dropped.  (See below for an example.)

    This function always allocates memory to hold the resulting path.
    The variadic overload is guaranteed to only perform a single
    allocation, as is the range version if `paths` is a forward
    range.

    Params:
        segments = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
        of segments to assemble the path from.
    Returns: The assembled path.
*/
immutable(ElementEncodingType!(ElementType!Range))[]
    buildPath(Range)(scope Range segments)
    if (isInputRange!Range && !isInfinite!Range && isSomeString!(ElementType!Range))
{
    if (segments.empty) return null;

    // If this is a forward range, we can pre-calculate a maximum length.
    static if (isForwardRange!Range)
    {
        auto segments2 = segments.save;
        size_t precalc = 0;
        foreach (segment; segments2) precalc += segment.length + 1;
    }
    // Otherwise, just venture a guess and resize later if necessary.
    else size_t precalc = 255;

    auto buf = new Unqual!(ElementEncodingType!(ElementType!Range))[](precalc);
    size_t pos = 0;
    foreach (segment; segments)
    {
        if (segment.empty) continue;
        static if (!isForwardRange!Range)
        {
            immutable neededLength = pos + segment.length + 1;
            if (buf.length < neededLength)
                buf.length = reserve(buf, neededLength + buf.length/2);
        }
        auto r = chainPath(buf[0 .. pos], segment);
        size_t i;
        foreach (c; r)
        {
            buf[i] = c;
            ++i;
        }
        pos = i;
    }
    static U trustedCast(U, V)(V v) @trusted pure nothrow { return cast(U) v; }
    return trustedCast!(typeof(return))(buf[0 .. pos]);
}

/// ditto
immutable(C)[] buildPath(C)(const(C)[][] paths...)
    @safe pure nothrow
if (isSomeChar!C)
{
    return buildPath!(typeof(paths))(paths);
}

///
@safe unittest
{
    version (Posix)
    {
        assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
        assert(buildPath("/foo/", "bar/baz")  == "/foo/bar/baz");
        assert(buildPath("/foo", "/bar")      == "/bar");
    }

    version (Windows)
    {
        assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
        assert(buildPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
        assert(buildPath("foo", `d:\bar`)     == `d:\bar`);
        assert(buildPath("foo", `\bar`)       == `\bar`);
        assert(buildPath(`c:\foo`, `\bar`)    == `c:\bar`);
    }
}

@system unittest // non-documented
{
    import std.range;
    // ir() wraps an array in a plain (i.e. non-forward) input range, so that
    // we can test both code paths
    InputRange!(C[]) ir(C)(C[][] p...) { return inputRangeObject(p.dup); }
    version (Posix)
    {
        assert(buildPath("foo") == "foo");
        assert(buildPath("/foo/") == "/foo/");
        assert(buildPath("foo", "bar") == "foo/bar");
        assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
        assert(buildPath("foo/".dup, "bar") == "foo/bar");
        assert(buildPath("foo///", "bar".dup) == "foo///bar");
        assert(buildPath("/foo"w, "bar"w) == "/foo/bar");
        assert(buildPath("foo"w.dup, "/bar"w) == "/bar");
        assert(buildPath("foo"w, "bar/"w.dup) == "foo/bar/");
        assert(buildPath("/"d, "foo"d) == "/foo");
        assert(buildPath(""d.dup, "foo"d) == "foo");
        assert(buildPath("foo"d, ""d.dup) == "foo");
        assert(buildPath("foo", "bar".dup, "baz") == "foo/bar/baz");
        assert(buildPath("foo"w, "/bar"w, "baz"w.dup) == "/bar/baz");

        static assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
        static assert(buildPath("foo", "/bar", "baz") == "/bar/baz");

        // The following are mostly duplicates of the above, except that the
        // range version does not accept mixed constness.
        assert(buildPath(ir("foo")) == "foo");
        assert(buildPath(ir("/foo/")) == "/foo/");
        assert(buildPath(ir("foo", "bar")) == "foo/bar");
        assert(buildPath(ir("foo", "bar", "baz")) == "foo/bar/baz");
        assert(buildPath(ir("foo/".dup, "bar".dup)) == "foo/bar");
        assert(buildPath(ir("foo///".dup, "bar".dup)) == "foo///bar");
        assert(buildPath(ir("/foo"w, "bar"w)) == "/foo/bar");
        assert(buildPath(ir("foo"w.dup, "/bar"w.dup)) == "/bar");
        assert(buildPath(ir("foo"w.dup, "bar/"w.dup)) == "foo/bar/");
        assert(buildPath(ir("/"d, "foo"d)) == "/foo");
        assert(buildPath(ir(""d.dup, "foo"d.dup)) == "foo");
        assert(buildPath(ir("foo"d, ""d)) == "foo");
        assert(buildPath(ir("foo", "bar", "baz")) == "foo/bar/baz");
        assert(buildPath(ir("foo"w.dup, "/bar"w.dup, "baz"w.dup)) == "/bar/baz");
    }
    version (Windows)
    {
        assert(buildPath("foo") == "foo");
        assert(buildPath(`\foo/`) == `\foo/`);
        assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
        assert(buildPath("foo", `\bar`) == `\bar`);
        assert(buildPath(`c:\foo`, "bar") == `c:\foo\bar`);
        assert(buildPath("foo"w, `d:\bar`w.dup) ==  `d:\bar`);
        assert(buildPath(`c:\foo\bar`, `\baz`) == `c:\baz`);
        assert(buildPath(`\\foo\bar\baz`d, `foo`d, `\bar`d) == `\\foo\bar\bar`d);

        static assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
        static assert(buildPath("foo", `c:\bar`, "baz") == `c:\bar\baz`);

        assert(buildPath(ir("foo")) == "foo");
        assert(buildPath(ir(`\foo/`)) == `\foo/`);
        assert(buildPath(ir("foo", "bar", "baz")) == `foo\bar\baz`);
        assert(buildPath(ir("foo", `\bar`)) == `\bar`);
        assert(buildPath(ir(`c:\foo`, "bar")) == `c:\foo\bar`);
        assert(buildPath(ir("foo"w.dup, `d:\bar`w.dup)) ==  `d:\bar`);
        assert(buildPath(ir(`c:\foo\bar`, `\baz`)) == `c:\baz`);
        assert(buildPath(ir(`\\foo\bar\baz`d, `foo`d, `\bar`d)) == `\\foo\bar\bar`d);
    }

    // Test that allocation works as it should.
    auto manyShort = "aaa".repeat(1000).array();
    auto manyShortCombined = join(manyShort, dirSeparator);
    assert(buildPath(manyShort) == manyShortCombined);
    assert(buildPath(ir(manyShort)) == manyShortCombined);

    auto fewLong = 'b'.repeat(500).array().repeat(10).array();
    auto fewLongCombined = join(fewLong, dirSeparator);
    assert(buildPath(fewLong) == fewLongCombined);
    assert(buildPath(ir(fewLong)) == fewLongCombined);
}

@safe unittest
{
    // Test for issue 7397
    string[] ary = ["a", "b"];
    version (Posix)
    {
        assert(buildPath(ary) == "a/b");
    }
    else version (Windows)
    {
        assert(buildPath(ary) == `a\b`);
    }
}


/**
 * Concatenate path segments together to form one path.
 *
 * Params:
 *      r1 = first segment
 *      r2 = second segment
 *      ranges = 0 or more segments
 * Returns:
 *      Lazy range which is the concatenation of r1, r2 and ranges with path separators.
 *      The resulting element type is that of r1.
 * See_Also:
 *      $(LREF buildPath)
 */
auto chainPath(R1, R2, Ranges...)(R1 r1, R2 r2, Ranges ranges)
if ((isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && isSomeChar!(ElementType!R1) ||
    isNarrowString!R1 &&
    !isConvertibleToString!R1) &&
    (isRandomAccessRange!R2 && hasSlicing!R2 && hasLength!R2 && isSomeChar!(ElementType!R2) ||
    isNarrowString!R2 &&
    !isConvertibleToString!R2) &&
    (Ranges.length == 0 || is(typeof(chainPath(r2, ranges))))
    )
{
    static if (Ranges.length)
    {
        return chainPath(chainPath(r1, r2), ranges);
    }
    else
    {
        import std.range : only, chain;
        import std.utf : byUTF;

        alias CR = Unqual!(ElementEncodingType!R1);
        auto sep = only(CR(dirSeparator[0]));
        bool usesep = false;

        auto pos = r1.length;

        if (pos)
        {
            if (isRooted(r2))
            {
                version (Posix)
                {
                    pos = 0;
                }
                else version (Windows)
                {
                    if (isAbsolute(r2))
                        pos = 0;
                    else
                    {
                        pos = rootName(r1).length;
                        if (pos > 0 && isDirSeparator(r1[pos - 1]))
                            --pos;
                    }
                }
                else
                    static assert(0);
            }
            else if (!isDirSeparator(r1[pos - 1]))
                usesep = true;
        }
        if (!usesep)
            sep.popFront();
        // Return r1 ~ '/' ~ r2
        return chain(r1[0 .. pos].byUTF!CR, sep, r2.byUTF!CR);
    }
}

///
@safe unittest
{
    import std.array;
    version (Posix)
    {
        assert(chainPath("foo", "bar", "baz").array == "foo/bar/baz");
        assert(chainPath("/foo/", "bar/baz").array  == "/foo/bar/baz");
        assert(chainPath("/foo", "/bar").array      == "/bar");
    }

    version (Windows)
    {
        assert(chainPath("foo", "bar", "baz").array == `foo\bar\baz`);
        assert(chainPath(`c:\foo`, `bar\baz`).array == `c:\foo\bar\baz`);
        assert(chainPath("foo", `d:\bar`).array     == `d:\bar`);
        assert(chainPath("foo", `\bar`).array       == `\bar`);
        assert(chainPath(`c:\foo`, `\bar`).array    == `c:\bar`);
    }

    import std.utf : byChar;
    version (Posix)
    {
        assert(chainPath("foo", "bar", "baz").array == "foo/bar/baz");
        assert(chainPath("/foo/".byChar, "bar/baz").array  == "/foo/bar/baz");
        assert(chainPath("/foo", "/bar".byChar).array      == "/bar");
    }

    version (Windows)
    {
        assert(chainPath("foo", "bar", "baz").array == `foo\bar\baz`);
        assert(chainPath(`c:\foo`.byChar, `bar\baz`).array == `c:\foo\bar\baz`);
        assert(chainPath("foo", `d:\bar`).array     == `d:\bar`);
        assert(chainPath("foo", `\bar`.byChar).array       == `\bar`);
        assert(chainPath(`c:\foo`, `\bar`w).array    == `c:\bar`);
    }
}

auto chainPath(Ranges...)(auto ref Ranges ranges)
if (Ranges.length >= 2 &&
    std.meta.anySatisfy!(isConvertibleToString, Ranges))
{
    import std.meta : staticMap;
    alias Types = staticMap!(convertToString, Ranges);
    return chainPath!Types(ranges);
}

@safe unittest
{
    assert(chainPath(TestAliasedString(null), TestAliasedString(null), TestAliasedString(null)).empty);
    assert(chainPath(TestAliasedString(null), TestAliasedString(null), "").empty);
    assert(chainPath(TestAliasedString(null), "", TestAliasedString(null)).empty);
    static struct S { string s; }
    static assert(!__traits(compiles, chainPath(TestAliasedString(null), S(""), TestAliasedString(null))));
}

/** Performs the same task as $(LREF buildPath),
    while at the same time resolving current/parent directory
    symbols (`"."` and `".."`) and removing superfluous
    directory separators.
    It will return "." if the path leads to the starting directory.
    On Windows, slashes are replaced with backslashes.

    Using buildNormalizedPath on null paths will always return null.

    Note that this function does not resolve symbolic links.

    This function always allocates memory to hold the resulting path.
    Use $(LREF asNormalizedPath) to not allocate memory.

    Params:
        paths = An array of paths to assemble.

    Returns: The assembled path.
*/
immutable(C)[] buildNormalizedPath(C)(const(C[])[] paths...)
    @safe pure nothrow
if (isSomeChar!C)
{
    import std.array : array;
    import std.exception : assumeUnique;

    const(C)[] chained;
    foreach (path; paths)
    {
        if (chained)
            chained = chainPath(chained, path).array;
        else
            chained = path;
    }
    auto result = asNormalizedPath(chained);
    // .array returns a copy, so it is unique
    return () @trusted { return assumeUnique(result.array); } ();
}

///
@safe unittest
{
    assert(buildNormalizedPath("foo", "..") == ".");

    version (Posix)
    {
        assert(buildNormalizedPath("/foo/./bar/..//baz/") == "/foo/baz");
        assert(buildNormalizedPath("../foo/.") == "../foo");
        assert(buildNormalizedPath("/foo", "bar/baz/") == "/foo/bar/baz");
        assert(buildNormalizedPath("/foo", "/bar/..", "baz") == "/baz");
        assert(buildNormalizedPath("foo/./bar", "../../", "../baz") == "../baz");
        assert(buildNormalizedPath("/foo/./bar", "../../baz") == "/baz");
    }

    version (Windows)
    {
        assert(buildNormalizedPath(`c:\foo\.\bar/..\\baz\`) == `c:\foo\baz`);
        assert(buildNormalizedPath(`..\foo\.`) == `..\foo`);
        assert(buildNormalizedPath(`c:\foo`, `bar\baz\`) == `c:\foo\bar\baz`);
        assert(buildNormalizedPath(`c:\foo`, `bar/..`) == `c:\foo`);
        assert(buildNormalizedPath(`\\server\share\foo`, `..\bar`) ==
                `\\server\share\bar`);
    }
}

@safe unittest
{
    assert(buildNormalizedPath(".", ".") == ".");
    assert(buildNormalizedPath("foo", "..") == ".");
    assert(buildNormalizedPath("", "") is null);
    assert(buildNormalizedPath("", ".") == ".");
    assert(buildNormalizedPath(".", "") == ".");
    assert(buildNormalizedPath(null, "foo") == "foo");
    assert(buildNormalizedPath("", "foo") == "foo");
    assert(buildNormalizedPath("", "") == "");
    assert(buildNormalizedPath("", null) == "");
    assert(buildNormalizedPath(null, "") == "");
    assert(buildNormalizedPath!(char)(null, null) == "");

    version (Posix)
    {
        assert(buildNormalizedPath("/", "foo", "bar") == "/foo/bar");
        assert(buildNormalizedPath("foo", "bar", "baz") == "foo/bar/baz");
        assert(buildNormalizedPath("foo", "bar/baz") == "foo/bar/baz");
        assert(buildNormalizedPath("foo", "bar//baz///") == "foo/bar/baz");
        assert(buildNormalizedPath("/foo", "bar/baz") == "/foo/bar/baz");
        assert(buildNormalizedPath("/foo", "/bar/baz") == "/bar/baz");
        assert(buildNormalizedPath("/foo/..", "/bar/./baz") == "/bar/baz");
        assert(buildNormalizedPath("/foo/..", "bar/baz") == "/bar/baz");
        assert(buildNormalizedPath("/foo/../../", "bar/baz") == "/bar/baz");
        assert(buildNormalizedPath("/foo/bar", "../baz") == "/foo/baz");
        assert(buildNormalizedPath("/foo/bar", "../../baz") == "/baz");
        assert(buildNormalizedPath("/foo/bar", ".././/baz/..", "wee/") == "/foo/wee");
        assert(buildNormalizedPath("//foo/bar", "baz///wee") == "/foo/bar/baz/wee");
        static assert(buildNormalizedPath("/foo/..", "/bar/./baz") == "/bar/baz");
    }
    else version (Windows)
    {
        assert(buildNormalizedPath(`\`, `foo`, `bar`) == `\foo\bar`);
        assert(buildNormalizedPath(`foo`, `bar`, `baz`) == `foo\bar\baz`);
        assert(buildNormalizedPath(`foo`, `bar\baz`) == `foo\bar\baz`);
        assert(buildNormalizedPath(`foo`, `bar\\baz\\\`) == `foo\bar\baz`);
        assert(buildNormalizedPath(`\foo`, `bar\baz`) == `\foo\bar\baz`);
        assert(buildNormalizedPath(`\foo`, `\bar\baz`) == `\bar\baz`);
        assert(buildNormalizedPath(`\foo\..`, `\bar\.\baz`) == `\bar\baz`);
        assert(buildNormalizedPath(`\foo\..`, `bar\baz`) == `\bar\baz`);
        assert(buildNormalizedPath(`\foo\..\..\`, `bar\baz`) == `\bar\baz`);
        assert(buildNormalizedPath(`\foo\bar`, `..\baz`) == `\foo\baz`);
        assert(buildNormalizedPath(`\foo\bar`, `../../baz`) == `\baz`);
        assert(buildNormalizedPath(`\foo\bar`, `..\.\/baz\..`, `wee\`) == `\foo\wee`);

        assert(buildNormalizedPath(`c:\`, `foo`, `bar`) == `c:\foo\bar`);
        assert(buildNormalizedPath(`c:foo`, `bar`, `baz`) == `c:foo\bar\baz`);
        assert(buildNormalizedPath(`c:foo`, `bar\baz`) == `c:foo\bar\baz`);
        assert(buildNormalizedPath(`c:foo`, `bar\\baz\\\`) == `c:foo\bar\baz`);
        assert(buildNormalizedPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
        assert(buildNormalizedPath(`c:\foo`, `\bar\baz`) == `c:\bar\baz`);
        assert(buildNormalizedPath(`c:\foo\..`, `\bar\.\baz`) == `c:\bar\baz`);
        assert(buildNormalizedPath(`c:\foo\..`, `bar\baz`) == `c:\bar\baz`);
        assert(buildNormalizedPath(`c:\foo\..\..\`, `bar\baz`) == `c:\bar\baz`);
        assert(buildNormalizedPath(`c:\foo\bar`, `..\baz`) == `c:\foo\baz`);
        assert(buildNormalizedPath(`c:\foo\bar`, `..\..\baz`) == `c:\baz`);
        assert(buildNormalizedPath(`c:\foo\bar`, `..\.\\baz\..`, `wee\`) == `c:\foo\wee`);

        assert(buildNormalizedPath(`\\server\share`, `foo`, `bar`) == `\\server\share\foo\bar`);
        assert(buildNormalizedPath(`\\server\share\`, `foo`, `bar`) == `\\server\share\foo\bar`);
        assert(buildNormalizedPath(`\\server\share\foo`, `bar\baz`) == `\\server\share\foo\bar\baz`);
        assert(buildNormalizedPath(`\\server\share\foo`, `\bar\baz`) == `\\server\share\bar\baz`);
        assert(buildNormalizedPath(`\\server\share\foo\..`, `\bar\.\baz`) == `\\server\share\bar\baz`);
        assert(buildNormalizedPath(`\\server\share\foo\..`, `bar\baz`) == `\\server\share\bar\baz`);
        assert(buildNormalizedPath(`\\server\share\foo\..\..\`, `bar\baz`) == `\\server\share\bar\baz`);
        assert(buildNormalizedPath(`\\server\share\foo\bar`, `..\baz`) == `\\server\share\foo\baz`);
        assert(buildNormalizedPath(`\\server\share\foo\bar`, `..\..\baz`) == `\\server\share\baz`);
        assert(buildNormalizedPath(`\\server\share\foo\bar`, `..\.\\baz\..`, `wee\`) == `\\server\share\foo\wee`);

        static assert(buildNormalizedPath(`\foo\..\..\`, `bar\baz`) == `\bar\baz`);
    }
    else static assert(0);
}

@safe unittest
{
    // Test for issue 7397
    string[] ary = ["a", "b"];
    version (Posix)
    {
        assert(buildNormalizedPath(ary) == "a/b");
    }
    else version (Windows)
    {
        assert(buildNormalizedPath(ary) == `a\b`);
    }
}


/** Normalize a path by resolving current/parent directory
    symbols (`"."` and `".."`) and removing superfluous
    directory separators.
    It will return "." if the path leads to the starting directory.
    On Windows, slashes are replaced with backslashes.

    Using asNormalizedPath on empty paths will always return an empty path.

    Does not resolve symbolic links.

    This function always allocates memory to hold the resulting path.
    Use $(LREF buildNormalizedPath) to allocate memory and return a string.

    Params:
        path = string or random access range representing the path to normalize

    Returns:
        normalized path as a forward range
*/

auto asNormalizedPath(R)(return scope R path)
if (isSomeChar!(ElementEncodingType!R) &&
    (isRandomAccessRange!R && hasSlicing!R && hasLength!R || isNarrowString!R) &&
    !isConvertibleToString!R)
{
    alias C = Unqual!(ElementEncodingType!R);
    alias S = typeof(path[0 .. 0]);

    static struct Result
    {
        @property bool empty()
        {
            return c == c.init;
        }

        @property C front()
        {
            return c;
        }

        void popFront()
        {
            C lastc = c;
            c = c.init;
            if (!element.empty)
            {
                c = getElement0();
                return;
            }
          L1:
            while (1)
            {
                if (elements.empty)
                {
                    element = element[0 .. 0];
                    return;
                }
                element = elements.front;
                elements.popFront();
                if (isDot(element) || (rooted && isDotDot(element)))
                    continue;

                if (rooted || !isDotDot(element))
                {
                    int n = 1;
                    auto elements2 = elements.save;
                    while (!elements2.empty)
                    {
                        auto e = elements2.front;
                        elements2.popFront();
                        if (isDot(e))
                            continue;
                        if (isDotDot(e))
                        {
                            --n;
                            if (n == 0)
                            {
                                elements = elements2;
                                element = element[0 .. 0];
                                continue L1;
                            }
                        }
                        else
                            ++n;
                    }
                }
                break;
            }

            static assert(dirSeparator.length == 1);
            if (lastc == dirSeparator[0] || lastc == lastc.init)
                c = getElement0();
            else
                c = dirSeparator[0];
        }

        static if (isForwardRange!R)
        {
            @property auto save()
            {
                auto result = this;
                result.element = element.save;
                result.elements = elements.save;
                return result;
            }
        }

      private:
        this(R path)
        {
            element = rootName(path);
            auto i = element.length;
            while (i < path.length && isDirSeparator(path[i]))
                ++i;
            rooted = i > 0;
            elements = pathSplitter(path[i .. $]);
            popFront();
            if (c == c.init && path.length)
                c = C('.');
        }

        C getElement0()
        {
            static if (isNarrowString!S)  // avoid autodecode
            {
                C c = element[0];
                element = element[1 .. $];
            }
            else
            {
                C c = element.front;
                element.popFront();
            }
            version (Windows)
            {
                if (c == '/')   // can appear in root element
                    c = '\\';   // use native Windows directory separator
            }
            return c;
        }

        // See if elem is "."
        static bool isDot(S elem)
        {
            return elem.length == 1 && elem[0] == '.';
        }

        // See if elem is ".."
        static bool isDotDot(S elem)
        {
            return elem.length == 2 && elem[0] == '.' && elem[1] == '.';
        }

        bool rooted;    // the path starts with a root directory
        C c;
        S element;
        typeof(pathSplitter(path[0 .. 0])) elements;
    }

    return Result(path);
}

///
@safe unittest
{
    import std.array;
    assert(asNormalizedPath("foo/..").array == ".");

    version (Posix)
    {
        assert(asNormalizedPath("/foo/./bar/..//baz/").array == "/foo/baz");
        assert(asNormalizedPath("../foo/.").array == "../foo");
        assert(asNormalizedPath("/foo/bar/baz/").array == "/foo/bar/baz");
        assert(asNormalizedPath("/foo/./bar/../../baz").array == "/baz");
    }

    version (Windows)
    {
        assert(asNormalizedPath(`c:\foo\.\bar/..\\baz\`).array == `c:\foo\baz`);
        assert(asNormalizedPath(`..\foo\.`).array == `..\foo`);
        assert(asNormalizedPath(`c:\foo\bar\baz\`).array == `c:\foo\bar\baz`);
        assert(asNormalizedPath(`c:\foo\bar/..`).array == `c:\foo`);
        assert(asNormalizedPath(`\\server\share\foo\..\bar`).array ==
                `\\server\share\bar`);
    }
}

auto asNormalizedPath(R)(return scope auto ref R path)
if (isConvertibleToString!R)
{
    return asNormalizedPath!(StringTypeOf!R)(path);
}

@safe unittest
{
    assert(testAliasedString!asNormalizedPath(null));
}

@safe unittest
{
    import std.array;
    import std.utf : byChar;

    assert(asNormalizedPath("").array is null);
    assert(asNormalizedPath("foo").array == "foo");
    assert(asNormalizedPath(".").array == ".");
    assert(asNormalizedPath("./.").array == ".");
    assert(asNormalizedPath("foo/..").array == ".");

    auto save = asNormalizedPath("fob").save;
    save.popFront();
    assert(save.front == 'o');

    version (Posix)
    {
        assert(asNormalizedPath("/foo/bar").array == "/foo/bar");
        assert(asNormalizedPath("foo/bar/baz").array == "foo/bar/baz");
        assert(asNormalizedPath("foo/bar/baz").array == "foo/bar/baz");
        assert(asNormalizedPath("foo/bar//baz///").array == "foo/bar/baz");
        assert(asNormalizedPath("/foo/bar/baz").array == "/foo/bar/baz");
        assert(asNormalizedPath("/foo/../bar/baz").array == "/bar/baz");
        assert(asNormalizedPath("/foo/../..//bar/baz").array == "/bar/baz");
        assert(asNormalizedPath("/foo/bar/../baz").array == "/foo/baz");
        assert(asNormalizedPath("/foo/bar/../../baz").array == "/baz");
        assert(asNormalizedPath("/foo/bar/.././/baz/../wee/").array == "/foo/wee");
        assert(asNormalizedPath("//foo/bar/baz///wee").array == "/foo/bar/baz/wee");

        assert(asNormalizedPath("foo//bar").array == "foo/bar");
        assert(asNormalizedPath("foo/bar").array == "foo/bar");

        //Curent dir path
        assert(asNormalizedPath("./").array == ".");
        assert(asNormalizedPath("././").array == ".");
        assert(asNormalizedPath("./foo/..").array == ".");
        assert(asNormalizedPath("foo/..").array == ".");
    }
    else version (Windows)
    {
        assert(asNormalizedPath(`\foo\bar`).array == `\foo\bar`);
        assert(asNormalizedPath(`foo\bar\baz`).array == `foo\bar\baz`);
        assert(asNormalizedPath(`foo\bar\baz`).array == `foo\bar\baz`);
        assert(asNormalizedPath(`foo\bar\\baz\\\`).array == `foo\bar\baz`);
        assert(asNormalizedPath(`\foo\bar\baz`).array == `\foo\bar\baz`);
        assert(asNormalizedPath(`\foo\..\\bar\.\baz`).array == `\bar\baz`);
        assert(asNormalizedPath(`\foo\..\bar\baz`).array == `\bar\baz`);
        assert(asNormalizedPath(`\foo\..\..\\bar\baz`).array == `\bar\baz`);

        assert(asNormalizedPath(`\foo\bar\..\baz`).array == `\foo\baz`);
        assert(asNormalizedPath(`\foo\bar\../../baz`).array == `\baz`);
        assert(asNormalizedPath(`\foo\bar\..\.\/baz\..\wee\`).array == `\foo\wee`);

        assert(asNormalizedPath(`c:\foo\bar`).array == `c:\foo\bar`);
        assert(asNormalizedPath(`c:foo\bar\baz`).array == `c:foo\bar\baz`);
        assert(asNormalizedPath(`c:foo\bar\baz`).array == `c:foo\bar\baz`);
        assert(asNormalizedPath(`c:foo\bar\\baz\\\`).array == `c:foo\bar\baz`);
        assert(asNormalizedPath(`c:\foo\bar\baz`).array == `c:\foo\bar\baz`);

        assert(asNormalizedPath(`c:\foo\..\\bar\.\baz`).array == `c:\bar\baz`);
        assert(asNormalizedPath(`c:\foo\..\bar\baz`).array == `c:\bar\baz`);
        assert(asNormalizedPath(`c:\foo\..\..\\bar\baz`).array == `c:\bar\baz`);
        assert(asNormalizedPath(`c:\foo\bar\..\baz`).array == `c:\foo\baz`);
        assert(asNormalizedPath(`c:\foo\bar\..\..\baz`).array == `c:\baz`);
        assert(asNormalizedPath(`c:\foo\bar\..\.\\baz\..\wee\`).array == `c:\foo\wee`);
        assert(asNormalizedPath(`\\server\share\foo\bar`).array == `\\server\share\foo\bar`);
        assert(asNormalizedPath(`\\server\share\\foo\bar`).array == `\\server\share\foo\bar`);
        assert(asNormalizedPath(`\\server\share\foo\bar\baz`).array == `\\server\share\foo\bar\baz`);
        assert(asNormalizedPath(`\\server\share\foo\..\\bar\.\baz`).array == `\\server\share\bar\baz`);
        assert(asNormalizedPath(`\\server\share\foo\..\bar\baz`).array == `\\server\share\bar\baz`);
        assert(asNormalizedPath(`\\server\share\foo\..\..\\bar\baz`).array == `\\server\share\bar\baz`);
        assert(asNormalizedPath(`\\server\share\foo\bar\..\baz`).array == `\\server\share\foo\baz`);
        assert(asNormalizedPath(`\\server\share\foo\bar\..\..\baz`).array == `\\server\share\baz`);
        assert(asNormalizedPath(`\\server\share\foo\bar\..\.\\baz\..\wee\`).array == `\\server\share\foo\wee`);

        static assert(asNormalizedPath(`\foo\..\..\\bar\baz`).array == `\bar\baz`);

        assert(asNormalizedPath("foo//bar").array == `foo\bar`);

        //Curent dir path
        assert(asNormalizedPath(`.\`).array == ".");
        assert(asNormalizedPath(`.\.\`).array == ".");
        assert(asNormalizedPath(`.\foo\..`).array == ".");
        assert(asNormalizedPath(`foo\..`).array == ".");
    }
    else static assert(0);
}

@safe unittest
{
    import std.array;

    version (Posix)
    {
        // Trivial
        assert(asNormalizedPath("").empty);
        assert(asNormalizedPath("foo/bar").array == "foo/bar");

        // Correct handling of leading slashes
        assert(asNormalizedPath("/").array == "/");
        assert(asNormalizedPath("///").array == "/");
        assert(asNormalizedPath("////").array == "/");
        assert(asNormalizedPath("/foo/bar").array == "/foo/bar");
        assert(asNormalizedPath("//foo/bar").array == "/foo/bar");
        assert(asNormalizedPath("///foo/bar").array == "/foo/bar");
        assert(asNormalizedPath("////foo/bar").array == "/foo/bar");

        // Correct handling of single-dot symbol (current directory)
        assert(asNormalizedPath("/./foo").array == "/foo");
        assert(asNormalizedPath("/foo/./bar").array == "/foo/bar");

        assert(asNormalizedPath("./foo").array == "foo");
        assert(asNormalizedPath("././foo").array == "foo");
        assert(asNormalizedPath("foo/././bar").array == "foo/bar");

        // Correct handling of double-dot symbol (previous directory)
        assert(asNormalizedPath("/foo/../bar").array == "/bar");
        assert(asNormalizedPath("/foo/../../bar").array == "/bar");
        assert(asNormalizedPath("/../foo").array == "/foo");
        assert(asNormalizedPath("/../../foo").array == "/foo");
        assert(asNormalizedPath("/foo/..").array == "/");
        assert(asNormalizedPath("/foo/../..").array == "/");

        assert(asNormalizedPath("foo/../bar").array == "bar");
        assert(asNormalizedPath("foo/../../bar").array == "../bar");
        assert(asNormalizedPath("../foo").array == "../foo");
        assert(asNormalizedPath("../../foo").array == "../../foo");
        assert(asNormalizedPath("../foo/../bar").array == "../bar");
        assert(asNormalizedPath(".././../foo").array == "../../foo");
        assert(asNormalizedPath("foo/bar/..").array == "foo");
        assert(asNormalizedPath("/foo/../..").array == "/");

        // The ultimate path
        assert(asNormalizedPath("/foo/../bar//./../...///baz//").array == "/.../baz");
        static assert(asNormalizedPath("/foo/../bar//./../...///baz//").array == "/.../baz");
    }
    else version (Windows)
    {
        // Trivial
        assert(asNormalizedPath("").empty);
        assert(asNormalizedPath(`foo\bar`).array == `foo\bar`);
        assert(asNormalizedPath("foo/bar").array == `foo\bar`);

        // Correct handling of absolute paths
        assert(asNormalizedPath("/").array == `\`);
        assert(asNormalizedPath(`\`).array == `\`);
        assert(asNormalizedPath(`\\\`).array == `\`);
        assert(asNormalizedPath(`\\\\`).array == `\`);
        assert(asNormalizedPath(`\foo\bar`).array == `\foo\bar`);
        assert(asNormalizedPath(`\\foo`).array == `\\foo`);
        assert(asNormalizedPath(`\\foo\\`).array == `\\foo`);
        assert(asNormalizedPath(`\\foo/bar`).array == `\\foo\bar`);
        assert(asNormalizedPath(`\\\foo\bar`).array == `\foo\bar`);
        assert(asNormalizedPath(`\\\\foo\bar`).array == `\foo\bar`);
        assert(asNormalizedPath(`c:\`).array == `c:\`);
        assert(asNormalizedPath(`c:\foo\bar`).array == `c:\foo\bar`);
        assert(asNormalizedPath(`c:\\foo\bar`).array == `c:\foo\bar`);

        // Correct handling of single-dot symbol (current directory)
        assert(asNormalizedPath(`\./foo`).array == `\foo`);
        assert(asNormalizedPath(`\foo/.\bar`).array == `\foo\bar`);

        assert(asNormalizedPath(`.\foo`).array == `foo`);
        assert(asNormalizedPath(`./.\foo`).array == `foo`);
        assert(asNormalizedPath(`foo\.\./bar`).array == `foo\bar`);

        // Correct handling of double-dot symbol (previous directory)
        assert(asNormalizedPath(`\foo\..\bar`).array == `\bar`);
        assert(asNormalizedPath(`\foo\../..\bar`).array == `\bar`);
        assert(asNormalizedPath(`\..\foo`).array == `\foo`);
        assert(asNormalizedPath(`\..\..\foo`).array == `\foo`);
        assert(asNormalizedPath(`\foo\..`).array == `\`);
        assert(asNormalizedPath(`\foo\../..`).array == `\`);

        assert(asNormalizedPath(`foo\..\bar`).array == `bar`);
        assert(asNormalizedPath(`foo\..\../bar`).array == `..\bar`);

        assert(asNormalizedPath(`..\foo`).array == `..\foo`);
        assert(asNormalizedPath(`..\..\foo`).array == `..\..\foo`);
        assert(asNormalizedPath(`..\foo\..\bar`).array == `..\bar`);
        assert(asNormalizedPath(`..\.\..\foo`).array == `..\..\foo`);
        assert(asNormalizedPath(`foo\bar\..`).array == `foo`);
        assert(asNormalizedPath(`\foo\..\..`).array == `\`);
        assert(asNormalizedPath(`c:\foo\..\..`).array == `c:\`);

        // Correct handling of non-root path with drive specifier
        assert(asNormalizedPath(`c:foo`).array == `c:foo`);
        assert(asNormalizedPath(`c:..\foo\.\..\bar`).array == `c:..\bar`);

        // The ultimate path
        assert(asNormalizedPath(`c:\foo\..\bar\\.\..\...\\\baz\\`).array == `c:\...\baz`);
        static assert(asNormalizedPath(`c:\foo\..\bar\\.\..\...\\\baz\\`).array == `c:\...\baz`);
    }
    else static assert(false);
}

/** Slice up a path into its elements.

    Params:
        path = string or slicable random access range

    Returns:
        bidirectional range of slices of `path`
*/
auto pathSplitter(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R ||
    isNarrowString!R) &&
    !isConvertibleToString!R)
{
    static struct PathSplitter
    {
        @property bool empty() const { return pe == 0; }

        @property R front()
        {
            assert(!empty);
            return _path[fs .. fe];
        }

        void popFront()
        {
            assert(!empty);
            if (ps == pe)
            {
                if (fs == bs && fe == be)
                {
                    pe = 0;
                }
                else
                {
                    fs = bs;
                    fe = be;
                }
            }
            else
            {
                fs = ps;
                fe = fs;
                while (fe < pe && !isDirSeparator(_path[fe]))
                    ++fe;
                ps = ltrim(fe, pe);
            }
        }

        @property R back()
        {
            assert(!empty);
            return _path[bs .. be];
        }

        void popBack()
        {
            assert(!empty);
            if (ps == pe)
            {
                if (fs == bs && fe == be)
                {
                    pe = 0;
                }
                else
                {
                    bs = fs;
                    be = fe;
                }
            }
            else
            {
                bs = pe;
                be = bs;
                while (bs > ps && !isDirSeparator(_path[bs - 1]))
                    --bs;
                pe = rtrim(ps, bs);
            }
        }
        @property auto save() { return this; }


    private:
        R _path;
        size_t ps, pe;
        size_t fs, fe;
        size_t bs, be;

        this(R p)
        {
            if (p.empty)
            {
                pe = 0;
                return;
            }
            _path = p;

            ps = 0;
            pe = _path.length;

            // If path is rooted, first element is special
            version (Windows)
            {
                if (isUNC(_path))
                {
                    auto i = uncRootLength(_path);
                    fs = 0;
                    fe = i;
                    ps = ltrim(fe, pe);
                }
                else if (isDriveRoot(_path))
                {
                    fs = 0;
                    fe = 3;
                    ps = ltrim(fe, pe);
                }
                else if (_path.length >= 1 && isDirSeparator(_path[0]))
                {
                    fs = 0;
                    fe = 1;
                    ps = ltrim(fe, pe);
                }
                else
                {
                    assert(!isRooted(_path));
                    popFront();
                }
            }
            else version (Posix)
            {
                if (_path.length >= 1 && isDirSeparator(_path[0]))
                {
                    fs = 0;
                    fe = 1;
                    ps = ltrim(fe, pe);
                }
                else
                {
                    popFront();
                }
            }
            else static assert(0);

            if (ps == pe)
            {
                bs = fs;
                be = fe;
            }
            else
            {
                pe = rtrim(ps, pe);
                popBack();
            }
        }

        size_t ltrim(size_t s, size_t e)
        {
            while (s < e && isDirSeparator(_path[s]))
                ++s;
            return s;
        }

        size_t rtrim(size_t s, size_t e)
        {
            while (s < e && isDirSeparator(_path[e - 1]))
                --e;
            return e;
        }
    }

    return PathSplitter(path);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.conv : to;

    assert(equal(pathSplitter("/"), ["/"]));
    assert(equal(pathSplitter("/foo/bar"), ["/", "foo", "bar"]));
    assert(equal(pathSplitter("foo/../bar//./"), ["foo", "..", "bar", "."]));

    version (Posix)
    {
        assert(equal(pathSplitter("//foo/bar"), ["/", "foo", "bar"]));
    }

    version (Windows)
    {
        assert(equal(pathSplitter(`foo\..\bar\/.\`), ["foo", "..", "bar", "."]));
        assert(equal(pathSplitter("c:"), ["c:"]));
        assert(equal(pathSplitter(`c:\foo\bar`), [`c:\`, "foo", "bar"]));
        assert(equal(pathSplitter(`c:foo\bar`), ["c:foo", "bar"]));
    }
}

auto pathSplitter(R)(auto ref R path)
if (isConvertibleToString!R)
{
    return pathSplitter!(StringTypeOf!R)(path);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    assert(testAliasedString!pathSplitter("/"));
}

@safe unittest
{
    // equal2 verifies that the range is the same both ways, i.e.
    // through front/popFront and back/popBack.
    import std.algorithm;
    import std.range;
    bool equal2(R1, R2)(R1 r1, R2 r2)
    {
        static assert(isBidirectionalRange!R1);
        return equal(r1, r2) && equal(retro(r1), retro(r2));
    }

    assert(pathSplitter("").empty);

    // Root directories
    assert(equal2(pathSplitter("/"), ["/"]));
    assert(equal2(pathSplitter("//"), ["/"]));
    assert(equal2(pathSplitter("///"w), ["/"w]));

    // Absolute paths
    assert(equal2(pathSplitter("/foo/bar".dup), ["/", "foo", "bar"]));

    // General
    assert(equal2(pathSplitter("foo/bar"d.dup), ["foo"d, "bar"d]));
    assert(equal2(pathSplitter("foo//bar"), ["foo", "bar"]));
    assert(equal2(pathSplitter("foo/bar//"w), ["foo"w, "bar"w]));
    assert(equal2(pathSplitter("foo/../bar//./"d), ["foo"d, ".."d, "bar"d, "."d]));

    // save()
    auto ps1 = pathSplitter("foo/bar/baz");
    auto ps2 = ps1.save;
    ps1.popFront();
    assert(equal2(ps1, ["bar", "baz"]));
    assert(equal2(ps2, ["foo", "bar", "baz"]));

    // Platform specific
    version (Posix)
    {
        assert(equal2(pathSplitter("//foo/bar"w.dup), ["/"w, "foo"w, "bar"w]));
    }
    version (Windows)
    {
        assert(equal2(pathSplitter(`\`), [`\`]));
        assert(equal2(pathSplitter(`foo\..\bar\/.\`), ["foo", "..", "bar", "."]));
        assert(equal2(pathSplitter("c:"), ["c:"]));
        assert(equal2(pathSplitter(`c:\foo\bar`), [`c:\`, "foo", "bar"]));
        assert(equal2(pathSplitter(`c:foo\bar`), ["c:foo", "bar"]));
        assert(equal2(pathSplitter(`\\foo\bar`), [`\\foo\bar`]));
        assert(equal2(pathSplitter(`\\foo\bar\\`), [`\\foo\bar`]));
        assert(equal2(pathSplitter(`\\foo\bar\baz`), [`\\foo\bar`, "baz"]));
    }

    import std.exception;
    assertCTFEable!(
    {
        assert(equal(pathSplitter("/foo/bar".dup), ["/", "foo", "bar"]));
    });

    static assert(is(typeof(pathSplitter!(const(char)[])(null).front) == const(char)[]));

    import std.utf : byDchar;
    assert(equal2(pathSplitter("foo/bar"d.byDchar), ["foo"d, "bar"d]));
}




/** Determines whether a path starts at a root directory.

Params:
    path = A path name.
Returns:
    Whether a path starts at a root directory.

    On POSIX, this function returns true if and only if the path starts
    with a slash (/).

    On Windows, this function returns true if the path starts at
    the root directory of the current drive, of some other drive,
    or of a network drive.
*/
bool isRooted(R)(R path)
if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
    is(StringTypeOf!R))
{
    if (path.length >= 1 && isDirSeparator(path[0])) return true;
    version (Posix)         return false;
    else version (Windows)  return isAbsolute!(BaseOf!R)(path);
}

///
@safe unittest
{
    version (Posix)
    {
        assert( isRooted("/"));
        assert( isRooted("/foo"));
        assert(!isRooted("foo"));
        assert(!isRooted("../foo"));
    }

    version (Windows)
    {
        assert( isRooted(`\`));
        assert( isRooted(`\foo`));
        assert( isRooted(`d:\foo`));
        assert( isRooted(`\\foo\bar`));
        assert(!isRooted("foo"));
        assert(!isRooted("d:foo"));
    }
}

@safe unittest
{
    assert(isRooted("/"));
    assert(isRooted("/foo"));
    assert(!isRooted("foo"));
    assert(!isRooted("../foo"));

    version (Windows)
    {
    assert(isRooted(`\`));
    assert(isRooted(`\foo`));
    assert(isRooted(`d:\foo`));
    assert(isRooted(`\\foo\bar`));
    assert(!isRooted("foo"));
    assert(!isRooted("d:foo"));
    }

    static assert(isRooted("/foo"));
    static assert(!isRooted("foo"));

    static struct DirEntry { string s; alias s this; }
    assert(!isRooted(DirEntry("foo")));
}

/** Determines whether a path is absolute or not.

    Params: path = A path name.

    Returns: Whether a path is absolute or not.

    Example:
    On POSIX, an absolute path starts at the root directory.
    (In fact, `_isAbsolute` is just an alias for $(LREF isRooted).)
    ---
    version (Posix)
    {
        assert(isAbsolute("/"));
        assert(isAbsolute("/foo"));
        assert(!isAbsolute("foo"));
        assert(!isAbsolute("../foo"));
    }
    ---

    On Windows, an absolute path starts at the root directory of
    a specific drive.  Hence, it must start with $(D `d:\`) or $(D `d:/`),
    where `d` is the drive letter.  Alternatively, it may be a
    network path, i.e. a path starting with a double (back)slash.
    ---
    version (Windows)
    {
        assert(isAbsolute(`d:\`));
        assert(isAbsolute(`d:\foo`));
        assert(isAbsolute(`\\foo\bar`));
        assert(!isAbsolute(`\`));
        assert(!isAbsolute(`\foo`));
        assert(!isAbsolute("d:foo"));
    }
    ---
*/
version (StdDdoc)
{
    bool isAbsolute(R)(R path) pure nothrow @safe
    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
        is(StringTypeOf!R));
}
else version (Windows)
{
    bool isAbsolute(R)(R path)
    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
        is(StringTypeOf!R))
    {
        return isDriveRoot!(BaseOf!R)(path) || isUNC!(BaseOf!R)(path);
    }
}
else version (Posix)
{
    alias isAbsolute = isRooted;
}


@safe unittest
{
    assert(!isAbsolute("foo"));
    assert(!isAbsolute("../foo"w));
    static assert(!isAbsolute("foo"));

    version (Posix)
    {
    assert(isAbsolute("/"d));
    assert(isAbsolute("/foo".dup));
    static assert(isAbsolute("/foo"));
    }

    version (Windows)
    {
    assert(isAbsolute("d:\\"w));
    assert(isAbsolute("d:\\foo"d));
    assert(isAbsolute("\\\\foo\\bar"));
    assert(!isAbsolute("\\"w.dup));
    assert(!isAbsolute("\\foo"d.dup));
    assert(!isAbsolute("d:"));
    assert(!isAbsolute("d:foo"));
    static assert(isAbsolute(`d:\foo`));
    }

    {
        auto r = MockRange!(immutable(char))(`../foo`);
        assert(!r.isAbsolute());
    }

    static struct DirEntry { string s; alias s this; }
    assert(!isAbsolute(DirEntry("foo")));
}




/** Transforms `path` into an absolute path.

    The following algorithm is used:
    $(OL
        $(LI If `path` is empty, return `null`.)
        $(LI If `path` is already absolute, return it.)
        $(LI Otherwise, append `path` to `base` and return
            the result. If `base` is not specified, the current
            working directory is used.)
    )
    The function allocates memory if and only if it gets to the third stage
    of this algorithm.

    Params:
        path = the relative path to transform
        base = the base directory of the relative path

    Returns:
        string of transformed path

    Throws:
    `Exception` if the specified _base directory is not absolute.

    See_Also:
        $(LREF asAbsolutePath) which does not allocate
*/
string absolutePath(string path, lazy string base = getcwd())
    @safe pure
{
    import std.array : array;
    if (path.empty)  return null;
    if (isAbsolute(path))  return path;
    auto baseVar = base;
    if (!isAbsolute(baseVar)) throw new Exception("Base directory must be absolute");
    return chainPath(baseVar, path).array;
}

///
@safe unittest
{
    version (Posix)
    {
        assert(absolutePath("some/file", "/foo/bar")  == "/foo/bar/some/file");
        assert(absolutePath("../file", "/foo/bar")    == "/foo/bar/../file");
        assert(absolutePath("/some/file", "/foo/bar") == "/some/file");
    }

    version (Windows)
    {
        assert(absolutePath(`some\file`, `c:\foo\bar`)    == `c:\foo\bar\some\file`);
        assert(absolutePath(`..\file`, `c:\foo\bar`)      == `c:\foo\bar\..\file`);
        assert(absolutePath(`c:\some\file`, `c:\foo\bar`) == `c:\some\file`);
        assert(absolutePath(`\`, `c:\`)                   == `c:\`);
        assert(absolutePath(`\some\file`, `c:\foo\bar`)   == `c:\some\file`);
    }
}

@safe unittest
{
    version (Posix)
    {
        static assert(absolutePath("some/file", "/foo/bar") == "/foo/bar/some/file");
    }

    version (Windows)
    {
        static assert(absolutePath(`some\file`, `c:\foo\bar`) == `c:\foo\bar\some\file`);
    }

    import std.exception;
    assertThrown(absolutePath("bar", "foo"));
}

/** Transforms `path` into an absolute path.

    The following algorithm is used:
    $(OL
        $(LI If `path` is empty, return `null`.)
        $(LI If `path` is already absolute, return it.)
        $(LI Otherwise, append `path` to the current working directory,
        which allocates memory.)
    )

    Params:
        path = the relative path to transform

    Returns:
        the transformed path as a lazy range

    See_Also:
        $(LREF absolutePath) which returns an allocated string
*/
auto asAbsolutePath(R)(R path)
if ((isRandomAccessRange!R && isSomeChar!(ElementType!R) ||
    isNarrowString!R) &&
    !isConvertibleToString!R)
{
    import std.file : getcwd;
    string base = null;
    if (!path.empty && !isAbsolute(path))
        base = getcwd();
    return chainPath(base, path);
}

///
@system unittest
{
    import std.array;
    assert(asAbsolutePath(cast(string) null).array == "");
    version (Posix)
    {
        assert(asAbsolutePath("/foo").array == "/foo");
    }
    version (Windows)
    {
        assert(asAbsolutePath("c:/foo").array == "c:/foo");
    }
    asAbsolutePath("foo");
}

auto asAbsolutePath(R)(auto ref R path)
if (isConvertibleToString!R)
{
    return asAbsolutePath!(StringTypeOf!R)(path);
}

@system unittest
{
    assert(testAliasedString!asAbsolutePath(null));
}

/** Translates `path` into a relative path.

    The returned path is relative to `base`, which is by default
    taken to be the current working directory.  If specified,
    `base` must be an absolute path, and it is always assumed
    to refer to a directory.  If `path` and `base` refer to
    the same directory, the function returns $(D `.`).

    The following algorithm is used:
    $(OL
        $(LI If `path` is a relative directory, return it unaltered.)
        $(LI Find a common root between `path` and `base`.
            If there is no common root, return `path` unaltered.)
        $(LI Prepare a string with as many $(D `../`) or $(D `..\`) as
            necessary to reach the common root from base path.)
        $(LI Append the remaining segments of `path` to the string
            and return.)
    )

    In the second step, path components are compared using `filenameCmp!cs`,
    where `cs` is an optional template parameter determining whether
    the comparison is case sensitive or not.  See the
    $(LREF filenameCmp) documentation for details.

    This function allocates memory.

    Params:
        cs = Whether matching path name components against the base path should
            be case-sensitive or not.
        path = A path name.
        base = The base path to construct the relative path from.

    Returns: The relative path.

    See_Also:
        $(LREF asRelativePath) which does not allocate memory

    Throws:
    `Exception` if the specified _base directory is not absolute.
*/
string relativePath(CaseSensitive cs = CaseSensitive.osDefault)
    (string path, lazy string base = getcwd())
{
    if (!isAbsolute(path))
        return path;
    auto baseVar = base;
    if (!isAbsolute(baseVar))
        throw new Exception("Base directory must be absolute");

    import std.conv : to;
    return asRelativePath!cs(path, baseVar).to!string;
}

///
@safe unittest
{
    assert(relativePath("foo") == "foo");

    version (Posix)
    {
        assert(relativePath("foo", "/bar") == "foo");
        assert(relativePath("/foo/bar", "/foo/bar") == ".");
        assert(relativePath("/foo/bar", "/foo/baz") == "../bar");
        assert(relativePath("/foo/bar/baz", "/foo/woo/wee") == "../../bar/baz");
        assert(relativePath("/foo/bar/baz", "/foo/bar") == "baz");
    }
    version (Windows)
    {
        assert(relativePath("foo", `c:\bar`) == "foo");
        assert(relativePath(`c:\foo\bar`, `c:\foo\bar`) == ".");
        assert(relativePath(`c:\foo\bar`, `c:\foo\baz`) == `..\bar`);
        assert(relativePath(`c:\foo\bar\baz`, `c:\foo\woo\wee`) == `..\..\bar\baz`);
        assert(relativePath(`c:\foo\bar\baz`, `c:\foo\bar`) == "baz");
        assert(relativePath(`c:\foo\bar`, `d:\foo`) == `c:\foo\bar`);
    }
}

@safe unittest
{
    import std.exception;
    assert(relativePath("foo") == "foo");
    version (Posix)
    {
        relativePath("/foo");
        assert(relativePath("/foo/bar", "/foo/baz") == "../bar");
        assertThrown(relativePath("/foo", "bar"));
    }
    else version (Windows)
    {
        relativePath(`\foo`);
        assert(relativePath(`c:\foo\bar\baz`, `c:\foo\bar`) == "baz");
        assertThrown(relativePath(`c:\foo`, "bar"));
    }
    else static assert(0);
}

/** Transforms `path` into a path relative to `base`.

    The returned path is relative to `base`, which is usually
    the current working directory.
    `base` must be an absolute path, and it is always assumed
    to refer to a directory.  If `path` and `base` refer to
    the same directory, the function returns `'.'`.

    The following algorithm is used:
    $(OL
        $(LI If `path` is a relative directory, return it unaltered.)
        $(LI Find a common root between `path` and `base`.
            If there is no common root, return `path` unaltered.)
        $(LI Prepare a string with as many `../` or `..\` as
            necessary to reach the common root from base path.)
        $(LI Append the remaining segments of `path` to the string
            and return.)
    )

    In the second step, path components are compared using `filenameCmp!cs`,
    where `cs` is an optional template parameter determining whether
    the comparison is case sensitive or not.  See the
    $(LREF filenameCmp) documentation for details.

    Params:
        path = path to transform
        base = absolute path
        cs = whether filespec comparisons are sensitive or not; defaults to
         `CaseSensitive.osDefault`

    Returns:
        a random access range of the transformed path

    See_Also:
        $(LREF relativePath)
*/
auto asRelativePath(CaseSensitive cs = CaseSensitive.osDefault, R1, R2)
    (R1 path, R2 base)
if ((isNarrowString!R1 ||
    (isRandomAccessRange!R1 && hasSlicing!R1 && isSomeChar!(ElementType!R1)) &&
    !isConvertibleToString!R1) &&
    (isNarrowString!R2 ||
    (isRandomAccessRange!R2 && hasSlicing!R2 && isSomeChar!(ElementType!R2)) &&
    !isConvertibleToString!R2))
{
    bool choosePath = !isAbsolute(path);

    // Find common root with current working directory

    auto basePS = pathSplitter(base);
    auto pathPS = pathSplitter(path);
    choosePath |= filenameCmp!cs(basePS.front, pathPS.front) != 0;

    basePS.popFront();
    pathPS.popFront();

    import std.algorithm.comparison : mismatch;
    import std.algorithm.iteration : joiner;
    import std.array : array;
    import std.range.primitives : walkLength;
    import std.range : repeat, chain, choose;
    import std.utf : byCodeUnit, byChar;

    // Remove matching prefix from basePS and pathPS
    auto tup = mismatch!((a, b) => filenameCmp!cs(a, b) == 0)(basePS, pathPS);
    basePS = tup[0];
    pathPS = tup[1];

    string sep;
    if (basePS.empty && pathPS.empty)
        sep = ".";              // if base == path, this is the return
    else if (!basePS.empty && !pathPS.empty)
        sep = dirSeparator;

    // Append as many "../" as necessary to reach common base from path
    auto r1 = ".."
        .byChar
        .repeat(basePS.walkLength())
        .joiner(dirSeparator.byChar);

    auto r2 = pathPS
        .joiner(dirSeparator.byChar)
        .byChar;

    // Return (r1 ~ sep ~ r2)
    return choose(choosePath, path.byCodeUnit, chain(r1, sep.byChar, r2));
}

///
@safe unittest
{
    import std.array;
    version (Posix)
    {
        assert(asRelativePath("foo", "/bar").array == "foo");
        assert(asRelativePath("/foo/bar", "/foo/bar").array == ".");
        assert(asRelativePath("/foo/bar", "/foo/baz").array == "../bar");
        assert(asRelativePath("/foo/bar/baz", "/foo/woo/wee").array == "../../bar/baz");
        assert(asRelativePath("/foo/bar/baz", "/foo/bar").array == "baz");
    }
    else version (Windows)
    {
        assert(asRelativePath("foo", `c:\bar`).array == "foo");
        assert(asRelativePath(`c:\foo\bar`, `c:\foo\bar`).array == ".");
        assert(asRelativePath(`c:\foo\bar`, `c:\foo\baz`).array == `..\bar`);
        assert(asRelativePath(`c:\foo\bar\baz`, `c:\foo\woo\wee`).array == `..\..\bar\baz`);
        assert(asRelativePath(`c:/foo/bar/baz`, `c:\foo\woo\wee`).array == `..\..\bar\baz`);
        assert(asRelativePath(`c:\foo\bar\baz`, `c:\foo\bar`).array == "baz");
        assert(asRelativePath(`c:\foo\bar`, `d:\foo`).array == `c:\foo\bar`);
        assert(asRelativePath(`\\foo\bar`, `c:\foo`).array == `\\foo\bar`);
    }
    else
        static assert(0);
}

@safe unittest
{
    version (Posix)
    {
        assert(isBidirectionalRange!(typeof(asRelativePath("foo/bar/baz", "/foo/woo/wee"))));
    }

    version (Windows)
    {
        assert(isBidirectionalRange!(typeof(asRelativePath(`c:\foo\bar`, `c:\foo\baz`))));
    }
}

auto asRelativePath(CaseSensitive cs = CaseSensitive.osDefault, R1, R2)
    (auto ref R1 path, auto ref R2 base)
if (isConvertibleToString!R1 || isConvertibleToString!R2)
{
    import std.meta : staticMap;
    alias Types = staticMap!(convertToString, R1, R2);
    return asRelativePath!(cs, Types)(path, base);
}

@safe unittest
{
    import std.array;
    version (Posix)
        assert(asRelativePath(TestAliasedString("foo"), TestAliasedString("/bar")).array == "foo");
    else version (Windows)
        assert(asRelativePath(TestAliasedString("foo"), TestAliasedString(`c:\bar`)).array == "foo");
    assert(asRelativePath(TestAliasedString("foo"), "bar").array == "foo");
    assert(asRelativePath("foo", TestAliasedString("bar")).array == "foo");
    assert(asRelativePath(TestAliasedString("foo"), TestAliasedString("bar")).array == "foo");
    import std.utf : byDchar;
    assert(asRelativePath("foo"d.byDchar, TestAliasedString("bar")).array == "foo");
}

@safe unittest
{
    import std.array, std.utf : bCU=byCodeUnit;
    version (Posix)
    {
        assert(asRelativePath("/foo/bar/baz".bCU, "/foo/bar".bCU).array == "baz");
        assert(asRelativePath("/foo/bar/baz"w.bCU, "/foo/bar"w.bCU).array == "baz"w);
        assert(asRelativePath("/foo/bar/baz"d.bCU, "/foo/bar"d.bCU).array == "baz"d);
    }
    else version (Windows)
    {
        assert(asRelativePath(`\\foo\bar`.bCU, `c:\foo`.bCU).array == `\\foo\bar`);
        assert(asRelativePath(`\\foo\bar`w.bCU, `c:\foo`w.bCU).array == `\\foo\bar`w);
        assert(asRelativePath(`\\foo\bar`d.bCU, `c:\foo`d.bCU).array == `\\foo\bar`d);
    }
}

/** Compares filename characters.

    This function can perform a case-sensitive or a case-insensitive
    comparison.  This is controlled through the `cs` template parameter
    which, if not specified, is given by $(LREF CaseSensitive)`.osDefault`.

    On Windows, the backslash and slash characters ($(D `\`) and $(D `/`))
    are considered equal.

    Params:
        cs = Case-sensitivity of the comparison.
        a = A filename character.
        b = A filename character.

    Returns:
        $(D < 0) if $(D a < b),
        `0` if $(D a == b), and
        $(D > 0) if $(D a > b).
*/
int filenameCharCmp(CaseSensitive cs = CaseSensitive.osDefault)(dchar a, dchar b)
    @safe pure nothrow
{
    if (isDirSeparator(a) && isDirSeparator(b)) return 0;
    static if (!cs)
    {
        import std.uni : toLower;
        a = toLower(a);
        b = toLower(b);
    }
    return cast(int)(a - b);
}

///
@safe unittest
{
    assert(filenameCharCmp('a', 'a') == 0);
    assert(filenameCharCmp('a', 'b') < 0);
    assert(filenameCharCmp('b', 'a') > 0);

    version (linux)
    {
        // Same as calling filenameCharCmp!(CaseSensitive.yes)(a, b)
        assert(filenameCharCmp('A', 'a') < 0);
        assert(filenameCharCmp('a', 'A') > 0);
    }
    version (Windows)
    {
        // Same as calling filenameCharCmp!(CaseSensitive.no)(a, b)
        assert(filenameCharCmp('a', 'A') == 0);
        assert(filenameCharCmp('a', 'B') < 0);
        assert(filenameCharCmp('A', 'b') < 0);
    }
}

@safe unittest
{
    assert(filenameCharCmp!(CaseSensitive.yes)('A', 'a') < 0);
    assert(filenameCharCmp!(CaseSensitive.yes)('a', 'A') > 0);

    assert(filenameCharCmp!(CaseSensitive.no)('a', 'a') == 0);
    assert(filenameCharCmp!(CaseSensitive.no)('a', 'b') < 0);
    assert(filenameCharCmp!(CaseSensitive.no)('b', 'a') > 0);
    assert(filenameCharCmp!(CaseSensitive.no)('A', 'a') == 0);
    assert(filenameCharCmp!(CaseSensitive.no)('a', 'A') == 0);
    assert(filenameCharCmp!(CaseSensitive.no)('a', 'B') < 0);
    assert(filenameCharCmp!(CaseSensitive.no)('B', 'a') > 0);
    assert(filenameCharCmp!(CaseSensitive.no)('A', 'b') < 0);
    assert(filenameCharCmp!(CaseSensitive.no)('b', 'A') > 0);

    version (Posix)   assert(filenameCharCmp('\\', '/') != 0);
    version (Windows) assert(filenameCharCmp('\\', '/') == 0);
}


/** Compares file names and returns

    Individual characters are compared using `filenameCharCmp!cs`,
    where `cs` is an optional template parameter determining whether
    the comparison is case sensitive or not.

    Treatment of invalid UTF encodings is implementation defined.

    Params:
        cs = case sensitivity
        filename1 = range for first file name
        filename2 = range for second file name

    Returns:
        $(D < 0) if $(D filename1 < filename2),
        `0` if $(D filename1 == filename2) and
        $(D > 0) if $(D filename1 > filename2).

    See_Also:
        $(LREF filenameCharCmp)
*/
int filenameCmp(CaseSensitive cs = CaseSensitive.osDefault, Range1, Range2)
    (Range1 filename1, Range2 filename2)
if (isSomeFiniteCharInputRange!Range1 && !isConvertibleToString!Range1 &&
    isSomeFiniteCharInputRange!Range2 && !isConvertibleToString!Range2)
{
    alias C1 = Unqual!(ElementEncodingType!Range1);
    alias C2 = Unqual!(ElementEncodingType!Range2);

    static if (!cs && (C1.sizeof < 4 || C2.sizeof < 4) ||
               C1.sizeof != C2.sizeof)
    {
        // Case insensitive - decode so case is checkable
        // Different char sizes - decode to bring to common type
        import std.utf : byDchar;
        return filenameCmp!cs(filename1.byDchar, filename2.byDchar);
    }
    else static if (isSomeString!Range1 && C1.sizeof < 4 ||
                    isSomeString!Range2 && C2.sizeof < 4)
    {
        // Avoid autodecoding
        import std.utf : byCodeUnit;
        return filenameCmp!cs(filename1.byCodeUnit, filename2.byCodeUnit);
    }
    else
    {
        for (;;)
        {
            if (filename1.empty) return -(cast(int) !filename2.empty);
            if (filename2.empty) return  1;
            const c = filenameCharCmp!cs(filename1.front, filename2.front);
            if (c != 0) return c;
            filename1.popFront();
            filename2.popFront();
        }
    }
}

///
@safe unittest
{
    assert(filenameCmp("abc", "abc") == 0);
    assert(filenameCmp("abc", "abd") < 0);
    assert(filenameCmp("abc", "abb") > 0);
    assert(filenameCmp("abc", "abcd") < 0);
    assert(filenameCmp("abcd", "abc") > 0);

    version (linux)
    {
        // Same as calling filenameCmp!(CaseSensitive.yes)(filename1, filename2)
        assert(filenameCmp("Abc", "abc") < 0);
        assert(filenameCmp("abc", "Abc") > 0);
    }
    version (Windows)
    {
        // Same as calling filenameCmp!(CaseSensitive.no)(filename1, filename2)
        assert(filenameCmp("Abc", "abc") == 0);
        assert(filenameCmp("abc", "Abc") == 0);
        assert(filenameCmp("Abc", "abD") < 0);
        assert(filenameCmp("abc", "AbB") > 0);
    }
}

int filenameCmp(CaseSensitive cs = CaseSensitive.osDefault, Range1, Range2)
    (auto ref Range1 filename1, auto ref Range2 filename2)
if (isConvertibleToString!Range1 || isConvertibleToString!Range2)
{
    import std.meta : staticMap;
    alias Types = staticMap!(convertToString, Range1, Range2);
    return filenameCmp!(cs, Types)(filename1, filename2);
}

@safe unittest
{
    assert(filenameCmp!(CaseSensitive.yes)(TestAliasedString("Abc"), "abc") < 0);
    assert(filenameCmp!(CaseSensitive.yes)("Abc", TestAliasedString("abc")) < 0);
    assert(filenameCmp!(CaseSensitive.yes)(TestAliasedString("Abc"), TestAliasedString("abc")) < 0);
}

@safe unittest
{
    assert(filenameCmp!(CaseSensitive.yes)("Abc", "abc") < 0);
    assert(filenameCmp!(CaseSensitive.yes)("abc", "Abc") > 0);

    assert(filenameCmp!(CaseSensitive.no)("abc", "abc") == 0);
    assert(filenameCmp!(CaseSensitive.no)("abc", "abd") < 0);
    assert(filenameCmp!(CaseSensitive.no)("abc", "abb") > 0);
    assert(filenameCmp!(CaseSensitive.no)("abc", "abcd") < 0);
    assert(filenameCmp!(CaseSensitive.no)("abcd", "abc") > 0);
    assert(filenameCmp!(CaseSensitive.no)("Abc", "abc") == 0);
    assert(filenameCmp!(CaseSensitive.no)("abc", "Abc") == 0);
    assert(filenameCmp!(CaseSensitive.no)("Abc", "abD") < 0);
    assert(filenameCmp!(CaseSensitive.no)("abc", "AbB") > 0);

    version (Posix)   assert(filenameCmp(`abc\def`, `abc/def`) != 0);
    version (Windows) assert(filenameCmp(`abc\def`, `abc/def`) == 0);
}

/** Matches a pattern against a path.

    Some characters of pattern have a special meaning (they are
    $(I meta-characters)) and can't be escaped. These are:

    $(BOOKTABLE,
    $(TR $(TD `*`)
         $(TD Matches 0 or more instances of any character.))
    $(TR $(TD `?`)
         $(TD Matches exactly one instance of any character.))
    $(TR $(TD `[`$(I chars)`]`)
         $(TD Matches one instance of any character that appears
              between the brackets.))
    $(TR $(TD `[!`$(I chars)`]`)
         $(TD Matches one instance of any character that does not
              appear between the brackets after the exclamation mark.))
    $(TR $(TD `{`$(I string1)`,`$(I string2)`,`&hellip;`}`)
         $(TD Matches either of the specified strings.))
    )

    Individual characters are compared using `filenameCharCmp!cs`,
    where `cs` is an optional template parameter determining whether
    the comparison is case sensitive or not.  See the
    $(LREF filenameCharCmp) documentation for details.

    Note that directory
    separators and dots don't stop a meta-character from matching
    further portions of the path.

    Params:
        cs = Whether the matching should be case-sensitive
        path = The path to be matched against
        pattern = The glob pattern

    Returns:
    `true` if pattern matches path, `false` otherwise.

    See_also:
    $(LINK2 http://en.wikipedia.org/wiki/Glob_%28programming%29,Wikipedia: _glob (programming))
 */
bool globMatch(CaseSensitive cs = CaseSensitive.osDefault, C, Range)
    (Range path, const(C)[] pattern)
    @safe pure nothrow
if (isForwardRange!Range && !isInfinite!Range &&
    isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range &&
    isSomeChar!C && is(immutable C == immutable ElementEncodingType!Range))
in
{
    // Verify that pattern[] is valid
    import std.algorithm.searching : balancedParens;
    assert(balancedParens(pattern, '[', ']', 0));
    assert(balancedParens(pattern, '{', '}', 0));
}
do
{
    alias RC = Unqual!(ElementEncodingType!Range);

    static if (RC.sizeof == 1 && isSomeString!Range)
    {
        import std.utf : byChar;
        return globMatch!cs(path.byChar, pattern);
    }
    else static if (RC.sizeof == 2 && isSomeString!Range)
    {
        import std.utf : byWchar;
        return globMatch!cs(path.byWchar, pattern);
    }
    else
    {
        C[] pattmp;
        foreach (ref pi; 0 .. pattern.length)
        {
            const pc = pattern[pi];
            switch (pc)
            {
                case '*':
                    if (pi + 1 == pattern.length)
                        return true;
                    for (; !path.empty; path.popFront())
                    {
                        auto p = path.save;
                        if (globMatch!(cs, C)(p,
                                        pattern[pi + 1 .. pattern.length]))
                            return true;
                    }
                    return false;

                case '?':
                    if (path.empty)
                        return false;
                    path.popFront();
                    break;

                case '[':
                    if (path.empty)
                        return false;
                    auto nc = path.front;
                    path.popFront();
                    auto not = false;
                    ++pi;
                    if (pattern[pi] == '!')
                    {
                        not = true;
                        ++pi;
                    }
                    auto anymatch = false;
                    while (1)
                    {
                        const pc2 = pattern[pi];
                        if (pc2 == ']')
                            break;
                        if (!anymatch && (filenameCharCmp!cs(nc, pc2) == 0))
                            anymatch = true;
                        ++pi;
                    }
                    if (anymatch == not)
                        return false;
                    break;

                case '{':
                    // find end of {} section
                    auto piRemain = pi;
                    for (; piRemain < pattern.length
                             && pattern[piRemain] != '}'; ++piRemain)
                    {   }

                    if (piRemain < pattern.length)
                        ++piRemain;
                    ++pi;

                    while (pi < pattern.length)
                    {
                        const pi0 = pi;
                        C pc3 = pattern[pi];
                        // find end of current alternative
                        for (; pi < pattern.length && pc3 != '}' && pc3 != ','; ++pi)
                        {
                            pc3 = pattern[pi];
                        }

                        auto p = path.save;
                        if (pi0 == pi)
                        {
                            if (globMatch!(cs, C)(p, pattern[piRemain..$]))
                            {
                                return true;
                            }
                            ++pi;
                        }
                        else
                        {
                            /* Match for:
                             *   pattern[pi0 .. pi-1] ~ pattern[piRemain..$]
                             */
                            if (pattmp is null)
                                // Allocate this only once per function invocation.
                                // Should do it with malloc/free, but that would make it impure.
                                pattmp = new C[pattern.length];

                            const len1 = pi - 1 - pi0;
                            pattmp[0 .. len1] = pattern[pi0 .. pi - 1];

                            const len2 = pattern.length - piRemain;
                            pattmp[len1 .. len1 + len2] = pattern[piRemain .. $];

                            if (globMatch!(cs, C)(p, pattmp[0 .. len1 + len2]))
                            {
                                return true;
                            }
                        }
                        if (pc3 == '}')
                        {
                            break;
                        }
                    }
                    return false;

                default:
                    if (path.empty)
                        return false;
                    if (filenameCharCmp!cs(pc, path.front) != 0)
                        return false;
                    path.popFront();
                    break;
            }
        }
        return path.empty;
    }
}

///
@safe unittest
{
    assert(globMatch("foo.bar", "*"));
    assert(globMatch("foo.bar", "*.*"));
    assert(globMatch(`foo/foo\bar`, "f*b*r"));
    assert(globMatch("foo.bar", "f???bar"));
    assert(globMatch("foo.bar", "[fg]???bar"));
    assert(globMatch("foo.bar", "[!gh]*bar"));
    assert(globMatch("bar.fooz", "bar.{foo,bif}z"));
    assert(globMatch("bar.bifz", "bar.{foo,bif}z"));

    version (Windows)
    {
        // Same as calling globMatch!(CaseSensitive.no)(path, pattern)
        assert(globMatch("foo", "Foo"));
        assert(globMatch("Goo.bar", "[fg]???bar"));
    }
    version (linux)
    {
        // Same as calling globMatch!(CaseSensitive.yes)(path, pattern)
        assert(!globMatch("foo", "Foo"));
        assert(!globMatch("Goo.bar", "[fg]???bar"));
    }
}

bool globMatch(CaseSensitive cs = CaseSensitive.osDefault, C, Range)
    (auto ref Range path, const(C)[] pattern)
    @safe pure nothrow
if (isConvertibleToString!Range)
{
    return globMatch!(cs, C, StringTypeOf!Range)(path, pattern);
}

@safe unittest
{
    assert(testAliasedString!globMatch("foo.bar", "*"));
}

@safe unittest
{
    assert(globMatch!(CaseSensitive.no)("foo", "Foo"));
    assert(!globMatch!(CaseSensitive.yes)("foo", "Foo"));

    assert(globMatch("foo", "*"));
    assert(globMatch("foo.bar"w, "*"w));
    assert(globMatch("foo.bar"d, "*.*"d));
    assert(globMatch("foo.bar", "foo*"));
    assert(globMatch("foo.bar"w, "f*bar"w));
    assert(globMatch("foo.bar"d, "f*b*r"d));
    assert(globMatch("foo.bar", "f???bar"));
    assert(globMatch("foo.bar"w, "[fg]???bar"w));
    assert(globMatch("foo.bar"d, "[!gh]*bar"d));

    assert(!globMatch("foo", "bar"));
    assert(!globMatch("foo"w, "*.*"w));
    assert(!globMatch("foo.bar"d, "f*baz"d));
    assert(!globMatch("foo.bar", "f*b*x"));
    assert(!globMatch("foo.bar", "[gh]???bar"));
    assert(!globMatch("foo.bar"w, "[!fg]*bar"w));
    assert(!globMatch("foo.bar"d, "[fg]???baz"d));
    assert(!globMatch("foo.di", "*.d")); // test issue 6634: triggered bad assertion

    assert(globMatch("foo.bar", "{foo,bif}.bar"));
    assert(globMatch("bif.bar"w, "{foo,bif}.bar"w));

    assert(globMatch("bar.foo"d, "bar.{foo,bif}"d));
    assert(globMatch("bar.bif", "bar.{foo,bif}"));

    assert(globMatch("bar.fooz"w, "bar.{foo,bif}z"w));
    assert(globMatch("bar.bifz"d, "bar.{foo,bif}z"d));

    assert(globMatch("bar.foo", "bar.{biz,,baz}foo"));
    assert(globMatch("bar.foo"w, "bar.{biz,}foo"w));
    assert(globMatch("bar.foo"d, "bar.{,biz}foo"d));
    assert(globMatch("bar.foo", "bar.{}foo"));

    assert(globMatch("bar.foo"w, "bar.{ar,,fo}o"w));
    assert(globMatch("bar.foo"d, "bar.{,ar,fo}o"d));
    assert(globMatch("bar.o", "bar.{,ar,fo}o"));

    assert(!globMatch("foo", "foo?"));
    assert(!globMatch("foo", "foo[]"));
    assert(!globMatch("foo", "foob"));
    assert(!globMatch("foo", "foo{b}"));


    static assert(globMatch("foo.bar", "[!gh]*bar"));
}




/** Checks that the given file or directory name is valid.

    The maximum length of `filename` is given by the constant
    `core.stdc.stdio.FILENAME_MAX`.  (On Windows, this number is
    defined as the maximum number of UTF-16 code points, and the
    test will therefore only yield strictly correct results when
    `filename` is a string of `wchar`s.)

    On Windows, the following criteria must be satisfied
    ($(LINK2 http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx,source)):
    $(UL
        $(LI `filename` must not contain any characters whose integer
            representation is in the range 0-31.)
        $(LI `filename` must not contain any of the following $(I reserved
            characters): `<>:"/\|?*`)
        $(LI `filename` may not end with a space ($(D ' ')) or a period
            (`'.'`).)
    )

    On POSIX, `filename` may not contain a forward slash (`'/'`) or
    the null character (`'\0'`).

    Params:
        filename = string to check

    Returns:
        `true` if and only if `filename` is not
        empty, not too long, and does not contain invalid characters.

*/
bool isValidFilename(Range)(Range filename)
if ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) ||
    isNarrowString!Range) &&
    !isConvertibleToString!Range)
{
    import core.stdc.stdio : FILENAME_MAX;
    if (filename.length == 0 || filename.length >= FILENAME_MAX) return false;
    foreach (c; filename)
    {
        version (Windows)
        {
            switch (c)
            {
                case 0:
                ..
                case 31:
                case '<':
                case '>':
                case ':':
                case '"':
                case '/':
                case '\\':
                case '|':
                case '?':
                case '*':
                    return false;

                default:
                    break;
            }
        }
        else version (Posix)
        {
            if (c == 0 || c == '/') return false;
        }
        else static assert(0);
    }
    version (Windows)
    {
        auto last = filename[filename.length - 1];
        if (last == '.' || last == ' ') return false;
    }

    // All criteria passed
    return true;
}

///
@safe pure @nogc nothrow
unittest
{
    import std.utf : byCodeUnit;

    assert(isValidFilename("hello.exe".byCodeUnit));
}

bool isValidFilename(Range)(auto ref Range filename)
if (isConvertibleToString!Range)
{
    return isValidFilename!(StringTypeOf!Range)(filename);
}

@safe unittest
{
    assert(testAliasedString!isValidFilename("hello.exe"));
}

@safe pure
unittest
{
    import std.conv;
    auto valid = ["foo"];
    auto invalid = ["", "foo\0bar", "foo/bar"];
    auto pfdep = [`foo\bar`, "*.txt"];
    version (Windows) invalid ~= pfdep;
    else version (Posix) valid ~= pfdep;
    else static assert(0);

    import std.meta : AliasSeq;
    static foreach (T; AliasSeq!(char[], const(char)[], string, wchar[],
        const(wchar)[], wstring, dchar[], const(dchar)[], dstring))
    {
        foreach (fn; valid)
            assert(isValidFilename(to!T(fn)));
        foreach (fn; invalid)
            assert(!isValidFilename(to!T(fn)));
    }

    {
        auto r = MockRange!(immutable(char))(`dir/file.d`);
        assert(!isValidFilename(r));
    }

    static struct DirEntry { string s; alias s this; }
    assert(isValidFilename(DirEntry("file.ext")));

    version (Windows)
    {
        immutable string cases = "<>:\"/\\|?*";
        foreach (i; 0 .. 31 + cases.length)
        {
            char[3] buf;
            buf[0] = 'a';
            buf[1] = i <= 31 ? cast(char) i : cases[i - 32];
            buf[2] = 'b';
            assert(!isValidFilename(buf[]));
        }
    }
}



/** Checks whether `path` is a valid path.

    Generally, this function checks that `path` is not empty, and that
    each component of the path either satisfies $(LREF isValidFilename)
    or is equal to `"."` or `".."`.

    $(B It does $(I not) check whether the path points to an existing file
    or directory; use $(REF exists, std,file) for this purpose.)

    On Windows, some special rules apply:
    $(UL
        $(LI If the second character of `path` is a colon (`':'`),
            the first character is interpreted as a drive letter, and
            must be in the range A-Z (case insensitive).)
        $(LI If `path` is on the form $(D `\\$(I server)\$(I share)\...`)
            (UNC path), $(LREF isValidFilename) is applied to $(I server)
            and $(I share) as well.)
        $(LI If `path` starts with $(D `\\?\`) (long UNC path), the
            only requirement for the rest of the string is that it does
            not contain the null character.)
        $(LI If `path` starts with $(D `\\.\`) (Win32 device namespace)
            this function returns `false`; such paths are beyond the scope
            of this module.)
    )

    Params:
        path = string or Range of characters to check

    Returns:
        true if `path` is a valid path.
*/
bool isValidPath(Range)(Range path)
if ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) ||
    isNarrowString!Range) &&
    !isConvertibleToString!Range)
{
    alias C = Unqual!(ElementEncodingType!Range);

    if (path.empty) return false;

    // Check whether component is "." or "..", or whether it satisfies
    // isValidFilename.
    bool isValidComponent(Range component)
    {
        assert(component.length > 0);
        if (component[0] == '.')
        {
            if (component.length == 1) return true;
            else if (component.length == 2 && component[1] == '.') return true;
        }
        return isValidFilename(component);
    }

    if (path.length == 1)
        return isDirSeparator(path[0]) || isValidComponent(path);

    Range remainder;
    version (Windows)
    {
        if (isDirSeparator(path[0]) && isDirSeparator(path[1]))
        {
            // Some kind of UNC path
            if (path.length < 5)
            {
                // All valid UNC paths must have at least 5 characters
                return false;
            }
            else if (path[2] == '?')
            {
                // Long UNC path
                if (!isDirSeparator(path[3])) return false;
                foreach (c; path[4 .. $])
                {
                    if (c == '\0') return false;
                }
                return true;
            }
            else if (path[2] == '.')
            {
                // Win32 device namespace not supported
                return false;
            }
            else
            {
                // Normal UNC path, i.e. \\server\share\...
                size_t i = 2;
                while (i < path.length && !isDirSeparator(path[i])) ++i;
                if (i == path.length || !isValidFilename(path[2 .. i]))
                    return false;
                ++i; // Skip a single dir separator
                size_t j = i;
                while (j < path.length && !isDirSeparator(path[j])) ++j;
                if (!isValidFilename(path[i .. j])) return false;
                remainder = path[j .. $];
            }
        }
        else if (isDriveSeparator(path[1]))
        {
            import std.ascii : isAlpha;
            if (!isAlpha(path[0])) return false;
            remainder = path[2 .. $];
        }
        else
        {
            remainder = path;
        }
    }
    else version (Posix)
    {
        remainder = path;
    }
    else static assert(0);
    remainder = ltrimDirSeparators(remainder);

    // Check that each component satisfies isValidComponent.
    while (!remainder.empty)
    {
        size_t i = 0;
        while (i < remainder.length && !isDirSeparator(remainder[i])) ++i;
        assert(i > 0);
        if (!isValidComponent(remainder[0 .. i])) return false;
        remainder = ltrimDirSeparators(remainder[i .. $]);
    }

    // All criteria passed
    return true;
}

///
@safe pure @nogc nothrow
unittest
{
    assert(isValidPath("/foo/bar"));
    assert(!isValidPath("/foo\0/bar"));
    assert(isValidPath("/"));
    assert(isValidPath("a"));

    version (Windows)
    {
        assert(isValidPath(`c:\`));
        assert(isValidPath(`c:\foo`));
        assert(isValidPath(`c:\foo\.\bar\\\..\`));
        assert(!isValidPath(`!:\foo`));
        assert(!isValidPath(`c::\foo`));
        assert(!isValidPath(`c:\foo?`));
        assert(!isValidPath(`c:\foo.`));

        assert(isValidPath(`\\server\share`));
        assert(isValidPath(`\\server\share\foo`));
        assert(isValidPath(`\\server\share\\foo`));
        assert(!isValidPath(`\\\server\share\foo`));
        assert(!isValidPath(`\\server\\share\foo`));
        assert(!isValidPath(`\\ser*er\share\foo`));
        assert(!isValidPath(`\\server\sha?e\foo`));
        assert(!isValidPath(`\\server\share\|oo`));

        assert(isValidPath(`\\?\<>:"?*|/\..\.`));
        assert(!isValidPath("\\\\?\\foo\0bar"));

        assert(!isValidPath(`\\.\PhysicalDisk1`));
        assert(!isValidPath(`\\`));
    }

    import std.utf : byCodeUnit;
    assert(isValidPath("/foo/bar".byCodeUnit));
}

bool isValidPath(Range)(auto ref Range path)
if (isConvertibleToString!Range)
{
    return isValidPath!(StringTypeOf!Range)(path);
}

@safe unittest
{
    assert(testAliasedString!isValidPath("/foo/bar"));
}

/** Performs tilde expansion in paths on POSIX systems.
    On Windows, this function does nothing.

    There are two ways of using tilde expansion in a path. One
    involves using the tilde alone or followed by a path separator. In
    this case, the tilde will be expanded with the value of the
    environment variable `HOME`.  The second way is putting
    a username after the tilde (i.e. `~john/Mail`). Here,
    the username will be searched for in the user database
    (i.e. `/etc/passwd` on Unix systems) and will expand to
    whatever path is stored there.  The username is considered the
    string after the tilde ending at the first instance of a path
    separator.

    Note that using the `~user` syntax may give different
    values from just `~` if the environment variable doesn't
    match the value stored in the user database.

    When the environment variable version is used, the path won't
    be modified if the environment variable doesn't exist or it
    is empty. When the database version is used, the path won't be
    modified if the user doesn't exist in the database or there is
    not enough memory to perform the query.

    This function performs several memory allocations.

    Params:
        inputPath = The path name to expand.

    Returns:
    `inputPath` with the tilde expanded, or just `inputPath`
    if it could not be expanded.
    For Windows, `expandTilde` merely returns its argument `inputPath`.

    Example:
    -----
    void processFile(string path)
    {
        // Allow calling this function with paths such as ~/foo
        auto fullPath = expandTilde(path);
        ...
    }
    -----
*/
string expandTilde(string inputPath) @safe nothrow
{
    version (Posix)
    {
        import core.exception : onOutOfMemoryError;
        import core.stdc.errno : errno, ERANGE;
        import core.stdc.stdlib : malloc, free, realloc;

        /*  Joins a path from a C string to the remainder of path.

            The last path separator from c_path is discarded. The result
            is joined to path[char_pos .. length] if char_pos is smaller
            than length, otherwise path is not appended to c_path.
        */
        static string combineCPathWithDPath(char* c_path, string path, size_t char_pos) @trusted nothrow
        {
            import core.stdc.string : strlen;
            import std.exception : assumeUnique;

            assert(c_path != null);
            assert(path.length > 0);
            assert(char_pos >= 0);

            // Search end of C string
            size_t end = strlen(c_path);

            const cPathEndsWithDirSep = end && isDirSeparator(c_path[end - 1]);

            string cp;
            if (char_pos < path.length)
            {
                // Remove trailing path separator, if any (with special care for root /)
                if (cPathEndsWithDirSep && (end > 1 || isDirSeparator(path[char_pos])))
                    end--;

                // Append something from path
                cp = assumeUnique(c_path[0 .. end] ~ path[char_pos .. $]);
            }
            else
            {
                // Remove trailing path separator, if any (except for root /)
                if (cPathEndsWithDirSep && end > 1)
                    end--;

                // Create our own copy, as lifetime of c_path is undocumented
                cp = c_path[0 .. end].idup;
            }

            return cp;
        }

        // Replaces the tilde from path with the environment variable HOME.
        static string expandFromEnvironment(string path) @safe nothrow
        {
            import core.stdc.stdlib : getenv;

            assert(path.length >= 1);
            assert(path[0] == '~');

            // Get HOME and use that to replace the tilde.
            auto home = () @trusted { return getenv("HOME"); } ();
            if (home == null)
                return path;

            return combineCPathWithDPath(home, path, 1);
        }

        // Replaces the tilde from path with the path from the user database.
        static string expandFromDatabase(string path) @safe nothrow
        {
            // bionic doesn't really support this, as getpwnam_r
            // isn't provided and getpwnam is basically just a stub
            version (CRuntime_Bionic)
            {
                return path;
            }
            else
            {
                import core.sys.posix.pwd : passwd, getpwnam_r;
                import std.string : indexOf;

                assert(path.length > 2 || (path.length == 2 && !isDirSeparator(path[1])));
                assert(path[0] == '~');

                // Extract username, searching for path separator.
                auto last_char = indexOf(path, dirSeparator[0]);

                size_t username_len = (last_char == -1) ? path.length : last_char;
                char[] username = new char[username_len * char.sizeof];

                if (last_char == -1)
                {
                    username[0 .. username_len - 1] = path[1 .. $];
                    last_char = path.length + 1;
                }
                else
                {
                    username[0 .. username_len - 1] = path[1 .. last_char];
                }
                username[username_len - 1] = 0;

                assert(last_char > 1);

                // Reserve C memory for the getpwnam_r() function.
                version (StdUnittest)
                    uint extra_memory_size = 2;
                else
                    uint extra_memory_size = 5 * 1024;
                char[] extra_memory;

                passwd result;
                while (1)
                {
                    extra_memory.length += extra_memory_size;

                    // Obtain info from database.
                    passwd *verify;
                    errno = 0;
                    auto passResult = () @trusted { return getpwnam_r(
                        &username[0],
                        &result,
                        &extra_memory[0],
                        extra_memory.length,
                        &verify
                    ); } ();
                    if (passResult == 0)
                    {
                        // Succeeded if verify points at result
                        if (verify == () @trusted { return &result; } ())
                            // username is found
                            path = combineCPathWithDPath(result.pw_dir, path, last_char);
                        break;
                    }

                    if (errno != ERANGE &&
                        // On BSD and OSX, errno can be left at 0 instead of set to ERANGE
                        errno != 0)
                        onOutOfMemoryError();

                    // extra_memory isn't large enough
                    import core.checkedint : mulu;
                    bool overflow;
                    extra_memory_size = mulu(extra_memory_size, 2, overflow);
                    if (overflow) assert(0);
                }
                return path;
            }
        }

        // Return early if there is no tilde in path.
        if (inputPath.length < 1 || inputPath[0] != '~')
            return inputPath;

        if (inputPath.length == 1 || isDirSeparator(inputPath[1]))
            return expandFromEnvironment(inputPath);
        else
            return expandFromDatabase(inputPath);
    }
    else version (Windows)
    {
        // Put here real windows implementation.
        return inputPath;
    }
    else
    {
        static assert(0); // Guard. Implement on other platforms.
    }
}

///
@system unittest
{
    version (Posix)
    {
        import std.process : environment;

        auto oldHome = environment["HOME"];
        scope(exit) environment["HOME"] = oldHome;

        environment["HOME"] = "dmd/test";
        assert(expandTilde("~/") == "dmd/test/");
        assert(expandTilde("~") == "dmd/test");
    }
}

@system unittest
{
    version (Posix)
    {
        static if (__traits(compiles, { import std.process : executeShell; }))
            import std.process : executeShell;

        import std.process : environment;
        import std.string : strip;

        // Retrieve the current home variable.
        auto oldHome = environment.get("HOME");

        // Testing when there is no environment variable.
        environment.remove("HOME");
        assert(expandTilde("~/") == "~/");
        assert(expandTilde("~") == "~");

        // Testing when an environment variable is set.
        environment["HOME"] = "dmd/test";
        assert(expandTilde("~/") == "dmd/test/");
        assert(expandTilde("~") == "dmd/test");

        // The same, but with a variable ending in a slash.
        environment["HOME"] = "dmd/test/";
        assert(expandTilde("~/") == "dmd/test/");
        assert(expandTilde("~") == "dmd/test");

        // The same, but with a variable set to root.
        environment["HOME"] = "/";
        assert(expandTilde("~/") == "/");
        assert(expandTilde("~") == "/");

        // Recover original HOME variable before continuing.
        if (oldHome !is null) environment["HOME"] = oldHome;
        else environment.remove("HOME");

        static if (is(typeof(executeShell)))
        {
            immutable tildeUser = "~" ~ environment.get("USER");
            immutable path = executeShell("echo " ~ tildeUser).output.strip();
            immutable expTildeUser = expandTilde(tildeUser);
            assert(expTildeUser == path, expTildeUser);
            immutable expTildeUserSlash = expandTilde(tildeUser ~ "/");
            immutable pathSlash = path[$-1] == '/' ? path : path ~ "/";
            assert(expTildeUserSlash == pathSlash, expTildeUserSlash);
        }

        assert(expandTilde("~Idontexist/hey") == "~Idontexist/hey");
    }
}

version (StdUnittest)
{
private:
    /* Define a mock RandomAccessRange to use for unittesting.
     */

    struct MockRange(C)
    {
        this(C[] array) { this.array = array; }
      const
      {
        @property size_t length() { return array.length; }
        @property bool empty() { return array.length == 0; }
        @property C front() { return array[0]; }
        @property C back()  { return array[$ - 1]; }
        alias opDollar = length;
        C opIndex(size_t i) { return array[i]; }
      }
        void popFront() { array = array[1 .. $]; }
        void popBack()  { array = array[0 .. $-1]; }
        MockRange!C opSlice( size_t lwr, size_t upr) const
        {
            return MockRange!C(array[lwr .. upr]);
        }
        @property MockRange save() { return this; }
      private:
        C[] array;
    }

    /* Define a mock BidirectionalRange to use for unittesting.
     */

    struct MockBiRange(C)
    {
        this(const(C)[] array) { this.array = array; }
        const
        {
            @property bool empty() { return array.length == 0; }
            @property C front() { return array[0]; }
            @property C back()  { return array[$ - 1]; }
            @property size_t opDollar() { return array.length; }
        }
        void popFront() { array = array[1 .. $]; }
        void popBack()  { array = array[0 .. $-1]; }
        @property MockBiRange save() { return this; }
      private:
        const(C)[] array;
    }

}

@safe unittest
{
    static assert( isRandomAccessRange!(MockRange!(const(char))) );
    static assert( isBidirectionalRange!(MockBiRange!(const(char))) );
}

private template BaseOf(R)
{
    static if (isRandomAccessRange!R && isSomeChar!(ElementType!R))
        alias BaseOf = R;
    else
        alias BaseOf = StringTypeOf!R;
}
