// 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 https://issues.dlang.org/show_bug.cgi?id=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;

    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 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 https://issues.dlang.org/show_bug.cgi?id=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(return scope const 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"));
}

// Ensure that we can call absolute path with scope paramaters
@safe unittest
{
    string testAbsPath(scope const string path, scope const string base) {
        return absolutePath(path, base);
    }

    version (Posix)
        assert(testAbsPath("some/file", "/foo/bar")  == "/foo/bar/some/file");
    version (Windows)
        assert(testAbsPath(`some\file`, `c:\foo\bar`)    == `c:\foo\bar\some\file`);
}

/** 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;
    import std.utf : byUTF;

    assert(balancedParens(pattern.byUTF!C, '[', ']', 0));
    assert(balancedParens(pattern.byUTF!C, '{', '}', 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));
    // https://issues.dlang.org/show_bug.cgi?id=6634
    assert(!globMatch("foo.di", "*.d")); // 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(return scope const string inputPath) @safe nothrow
{
    version (Posix)
    {
        import core.exception : onOutOfMemoryError;
        import core.stdc.errno : errno, EBADF, ENOENT, EPERM, ERANGE, ESRCH;
        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;
                loop: 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;
                    }

                    switch (errno)
                    {
                        case ERANGE:
                        // On BSD and OSX, errno can be left at 0 instead of set to ERANGE
                        case 0:
                            break;

                        case ENOENT:
                        case ESRCH:
                        case EBADF:
                        case EPERM:
                            // The given name or uid was not found.
                            break loop;

                        default:
                            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.
    }
}

///
@safe 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");
    }
}

@safe 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");
    }
}

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

        string testPath(scope const string source_path) {
            return source_path.expandTilde;
        }

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

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


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;
}
