/**
This module implements a generic doubly-linked list container.
It can be used as a queue, dequeue or stack.

This module is a submodule of $(MREF std, container).

Source: $(PHOBOSSRC std/container/dlist.d)

Copyright: 2010- Andrei Alexandrescu. All rights reserved by the respective holders.

License: Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at $(HTTP
boost.org/LICENSE_1_0.txt)).

Authors: $(HTTP erdani.com, Andrei Alexandrescu)

$(SCRIPT inhibitQuickIndex = 1;)
*/
module std.container.dlist;

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

    auto s = DList!int(1, 2, 3);
    assert(equal(s[], [1, 2, 3]));

    s.removeFront();
    assert(equal(s[], [2, 3]));
    s.removeBack();
    assert(equal(s[], [2]));

    s.insertFront([4, 5]);
    assert(equal(s[], [4, 5, 2]));
    s.insertBack([6, 7]);
    assert(equal(s[], [4, 5, 2, 6, 7]));

    // If you want to apply range operations, simply slice it.
    import std.algorithm.searching : countUntil;
    import std.range : popFrontN, popBackN, walkLength;

    auto sl = DList!int([1, 2, 3, 4, 5]);
    assert(countUntil(sl[], 2) == 1);

    auto r = sl[];
    popFrontN(r, 2);
    popBackN(r, 2);
    assert(r.equal([3]));
    assert(walkLength(r) == 1);

    // DList.Range can be used to remove elements from the list it spans
    auto nl = DList!int([1, 2, 3, 4, 5]);
    for (auto rn = nl[]; !rn.empty;)
        if (rn.front % 2 == 0)
            nl.popFirstOf(rn);
        else
            rn.popFront();
    assert(equal(nl[], [1, 3, 5]));
    auto rs = nl[];
    rs.popFront();
    nl.remove(rs);
    assert(equal(nl[], [1]));
}

import std.range.primitives;
import std.traits;

public import std.container.util;

/+
A DList Node without payload. Used to handle the sentinel node (henceforth "sentinode").

Also used for parts of the code that don't depend on the payload type.
 +/
private struct BaseNode
{
    private BaseNode* _prev = null;
    private BaseNode* _next = null;

    /+
    Gets the payload associated with this node.
    This is trusted because all nodes are associated with a payload, even
    the sentinel node.
    It is also not possible to mix Nodes in DLists of different types.
    This function is implemented as a member function here, as UFCS does not
    work with pointers.
    +/
    ref inout(T) getPayload(T)() inout @trusted
    {
        return (cast(inout(DList!T.PayNode)*)&this)._payload;
    }

    // Helper: Given nodes p and n, connects them.
    static void connect(BaseNode* p, BaseNode* n) @safe nothrow pure
    {
        p._next = n;
        n._prev = p;
    }
}

/+
The base DList Range. Contains Range primitives that don't depend on payload type.
 +/
private struct DRange
{
    @safe unittest
    {
        static assert(isBidirectionalRange!DRange);
        static assert(is(ElementType!DRange == BaseNode*));
    }

nothrow @safe @nogc pure:
    private BaseNode* _first;
    private BaseNode* _last;

    private this(BaseNode* first, BaseNode* last)
    {
        assert((first is null) == (last is null), "Dlist.Range.this: Invalid arguments");
        _first = first;
        _last = last;
    }
    private this(BaseNode* n)
    {
        this(n, n);
    }

    @property
    bool empty() const scope
    {
        assert((_first is null) == (_last is null), "DList.Range: Invalidated state");
        return !_first;
    }

    @property BaseNode* front() return scope
    {
        assert(!empty, "DList.Range.front: Range is empty");
        return _first;
    }

    void popFront() scope
    {
        assert(!empty, "DList.Range.popFront: Range is empty");
        if (_first is _last)
        {
            _first = _last = null;
        }
        else
        {
            assert(_first._next && _first is _first._next._prev, "DList.Range: Invalidated state");
            _first = _first._next;
        }
    }

    @property BaseNode* back() return scope
    {
        assert(!empty, "DList.Range.front: Range is empty");
        return _last;
    }

    void popBack() scope
    {
        assert(!empty, "DList.Range.popBack: Range is empty");
        if (_first is _last)
        {
            _first = _last = null;
        }
        else
        {
            assert(_last._prev && _last is _last._prev._next, "DList.Range: Invalidated state");
            _last = _last._prev;
        }
    }

    /// Forward range primitive.
    @property DRange save() return scope { return this; }
}

/**
Implements a doubly-linked list.

`DList` uses reference semantics.
 */
struct DList(T)
{
    import std.range : Take;
    import std.traits : isMutable;

    /*
    A Node with a Payload. A PayNode.
     */
    struct PayNode
    {
        BaseNode _base;
        alias _base this;

        T _payload = T.init;

        this (BaseNode _base, T _payload)
        {
            import std.algorithm.mutation : move;

            this._base = _base;
            this._payload = move(_payload);
        }

        inout(BaseNode)* asBaseNode() inout @trusted
        {
            return &_base;
        }
    }

    //The sentinel node
    private BaseNode* _root;

  private
  {
    //Construct as new PayNode, and returns it as a BaseNode.
    static BaseNode* createNode(Stuff)(auto ref Stuff arg, BaseNode* prev = null, BaseNode* next = null)
    {
        import std.algorithm.mutation : move;

        static if (isMutable!Stuff)
            return (new PayNode(BaseNode(prev, next), move(arg))).asBaseNode();
        else
            return (new PayNode(BaseNode(prev, next), arg)).asBaseNode();
    }

    void initialize() nothrow @safe pure
    {
        if (_root) return;
        //Note: We allocate a PayNode for safety reasons.
        _root = (new PayNode()).asBaseNode();
        _root._next = _root._prev = _root;
    }
    ref inout(BaseNode*) _first() @property @safe nothrow pure inout
    {
        assert(_root, "Root pointer must not be null");
        return _root._next;
    }
    ref inout(BaseNode*) _last() @property @safe nothrow pure inout
    {
        assert(_root, "Root pointer must not be null");
        return _root._prev;
    }
  } //end private

/**
Constructor taking a number of nodes
     */
    this(U)(U[] values...)
    if (isImplicitlyConvertible!(U, T))
    {
        insertBack(values);
    }

/**
Constructor taking an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
     */
    this(Stuff)(Stuff stuff)
    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))
    {
        insertBack(stuff);
    }

/**
Comparison for equality.

Complexity: $(BIGOH min(n, n1)) where `n1` is the number of
elements in `rhs`.
     */
    bool opEquals()(ref const DList rhs) const
    if (is(typeof(front == front)))
    {
        const lhs = this;
        const lroot = lhs._root;
        const rroot = rhs._root;

        if (lroot is rroot) return true;
        if (lroot is null) return rroot is rroot._next;
        if (rroot is null) return lroot is lroot._next;

        const(BaseNode)* pl = lhs._first;
        const(BaseNode)* pr = rhs._first;
        while (true)
        {
            if (pl is lroot) return pr is rroot;
            if (pr is rroot) return false;

            // !== because of NaN
            if (!(pl.getPayload!T() == pr.getPayload!T())) return false;

            pl = pl._next;
            pr = pr._next;
        }
    }

    /**
    Defines the container's primary range, which embodies a bidirectional range.
     */
    struct Range
    {
        static assert(isBidirectionalRange!Range);

        DRange _base;
        alias _base this;

        private this(BaseNode* first, BaseNode* last)
        {
            _base = DRange(first, last);
        }
        private this(BaseNode* n)
        {
            this(n, n);
        }

        @property ref T front()
        {
            return _base.front.getPayload!T();
        }

        @property ref T back()
        {
            return _base.back.getPayload!T();
        }

        //Note: shadows base DRange.save.
        //Necessary for static covariance.
        @property Range save() { return this; }
    }

/**
Property returning `true` if and only if the container has no
elements.

Complexity: $(BIGOH 1)
     */
    bool empty() @property const nothrow
    {
        return _root is null || _root is _first;
    }

/**
Removes all contents from the `DList`.

Postcondition: `empty`

Complexity: $(BIGOH 1)
     */
    void clear()
    {
        //remove actual elements.
        remove(this[]);
    }

/**
Duplicates the container. The elements themselves are not transitively
duplicated.

Complexity: $(BIGOH n).
     */
    @property DList dup()
    {
        return DList(this[]);
    }

/**
Returns a range that iterates over all elements of the container, in
forward order.

Complexity: $(BIGOH 1)
     */
    Range opSlice()
    {
        if (empty)
            return Range(null, null);
        else
            return Range(_first, _last);
    }

/**
Forward to `opSlice().front`.

Complexity: $(BIGOH 1)
     */
    @property ref inout(T) front() inout
    {
        assert(!empty, "DList.front: List is empty");
        return _first.getPayload!T();
    }

/**
Forward to `opSlice().back`.

Complexity: $(BIGOH 1)
     */
    @property ref inout(T) back() inout
    {
        assert(!empty, "DList.back: List is empty");
        return _last.getPayload!T();
    }

/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/
/+                        BEGIN CONCAT FUNCTIONS HERE                         +/
/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/

/**
Returns a new `DList` that's the concatenation of `this` and its
argument `rhs`.
     */
    DList opBinary(string op, Stuff)(Stuff rhs)
    if (op == "~" && is(typeof(insertBack(rhs))))
    {
        auto ret = this.dup;
        ret.insertBack(rhs);
        return ret;
    }

/**
Returns a new `DList` that's the concatenation of the argument `lhs`
and `this`.
     */
    DList opBinaryRight(string op, Stuff)(Stuff lhs)
    if (op == "~" && is(typeof(insertFront(lhs))))
    {
        auto ret = this.dup;
        ret.insertFront(lhs);
        return ret;
    }

/**
Appends the contents of the argument `rhs` into `this`.
     */
    DList opOpAssign(string op, Stuff)(Stuff rhs)
    if (op == "~" && is(typeof(insertBack(rhs))))
    {
        insertBack(rhs);
        return this;
    }

/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/
/+                        BEGIN INSERT FUNCTIONS HERE                         +/
/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/

/**
Inserts `stuff` to the front/back of the container. `stuff` can be a
value convertible to `T` or a range of objects convertible to $(D
T). The stable version behaves the same, but guarantees that ranges
iterating over the container are never invalidated.

Returns: The number of elements inserted

Complexity: $(BIGOH m), where `m` is the length of `stuff`
     */
    size_t insertFront(Stuff)(Stuff stuff)
    {
        initialize();
        return insertAfterNode(_root, stuff);
    }

    /// ditto
    size_t insertBack(Stuff)(Stuff stuff)
    {
        initialize();
        return insertBeforeNode(_root, stuff);
    }

    /// ditto
    alias insert = insertBack;

    /// ditto
    alias stableInsert = insert;

    /// ditto
    alias stableInsertFront = insertFront;

    /// ditto
    alias stableInsertBack = insertBack;

/**
Inserts `stuff` after range `r`, which must be a non-empty range
previously extracted from this container.

`stuff` can be a value convertible to `T` or a range of objects
convertible to `T`. The stable version behaves the same, but
guarantees that ranges iterating over the container are never
invalidated.

Returns: The number of values inserted.

Complexity: $(BIGOH k + m), where `k` is the number of elements in
`r` and `m` is the length of `stuff`.
     */
    size_t insertBefore(Stuff)(Range r, Stuff stuff)
    {
        if (r._first)
            return insertBeforeNode(r._first, stuff);
        else
        {
            initialize();
            return insertAfterNode(_root, stuff);
        }
    }

    /// ditto
    alias stableInsertBefore = insertBefore;

    /// ditto
    size_t insertAfter(Stuff)(Range r, Stuff stuff)
    {
        if (r._last)
            return insertAfterNode(r._last, stuff);
        else
        {
            initialize();
            return insertBeforeNode(_root, stuff);
        }
    }

    /// ditto
    alias stableInsertAfter = insertAfter;

/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/
/+                        BEGIN REMOVE FUNCTIONS HERE                         +/
/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/

/**
Picks one value in an unspecified position in the container, removes
it from the container, and returns it. The stable version behaves the same,
but guarantees that ranges iterating over the container are never invalidated.

Precondition: `!empty`

Returns: The element removed.

Complexity: $(BIGOH 1).
     */
    T removeAny()
    {
        import std.algorithm.mutation : move;

        assert(!empty, "DList.removeAny: List is empty");
        auto result = move(back);
        removeBack();
        return result;
    }
    /// ditto
    alias stableRemoveAny = removeAny;

/**
Removes the value at the front/back of the container. The stable version
behaves the same, but guarantees that ranges iterating over the
container are never invalidated.

Precondition: `!empty`

Complexity: $(BIGOH 1).
     */
    void removeFront()
    {
        assert(!empty, "DList.removeFront: List is empty");
        assert(_root is _first._prev, "DList: Inconsistent state");
        BaseNode.connect(_root, _first._next);
    }

    /// ditto
    alias stableRemoveFront = removeFront;

    /// ditto
    void removeBack()
    {
        assert(!empty, "DList.removeBack: List is empty");
        assert(_last._next is _root, "DList: Inconsistent state");
        BaseNode.connect(_last._prev, _root);
    }

    /// ditto
    alias stableRemoveBack = removeBack;

/**
Removes `howMany` values at the front or back of the
container. Unlike the unparameterized versions above, these functions
do not throw if they could not remove `howMany` elements. Instead,
if $(D howMany > n), all elements are removed. The returned value is
the effective number of elements removed. The stable version behaves
the same, but guarantees that ranges iterating over the container are
never invalidated.

Returns: The number of elements removed

Complexity: $(BIGOH howMany).
     */
    size_t removeFront(size_t howMany)
    {
        if (!_root) return 0;
        size_t result;
        auto p = _first;
        while (p !is _root && result < howMany)
        {
            p = p._next;
            ++result;
        }
        BaseNode.connect(_root, p);
        return result;
    }

    /// ditto
    alias stableRemoveFront = removeFront;

    /// ditto
    size_t removeBack(size_t howMany)
    {
        if (!_root) return 0;
        size_t result;
        auto p = _last;
        while (p !is _root && result < howMany)
        {
            p = p._prev;
            ++result;
        }
        BaseNode.connect(p, _root);
        return result;
    }

    /// ditto
    alias stableRemoveBack = removeBack;

/**
Removes all elements belonging to `r`, which must be a range
obtained originally from this container.

Returns: A range spanning the remaining elements in the container that
initially were right after `r`.

Complexity: $(BIGOH 1)
     */
    Range remove(Range r)
    {
        if (r.empty)
            return r;

        assert(_root !is null, "Cannot remove from an un-initialized List");
        assert(r._first, "Remove: Range is empty");

        BaseNode.connect(r._first._prev, r._last._next);
        auto after = r._last._next;
        if (after is _root)
            return Range(null, null);
        else
            return Range(after, _last);
    }

    /// ditto
    Range linearRemove(Range r)
    {
        return remove(r);
    }

    /// ditto
    alias stableRemove = remove;

/**
Removes first element of `r`, wich must be a range obtained originally
from this container, from both DList instance and range `r`.

Compexity: $(BIGOH 1)
     */
    void popFirstOf(ref Range r)
    {
        assert(_root !is null, "Cannot remove from an un-initialized List");
        assert(r._first, "popFirstOf: Range is empty");
        auto prev = r._first._prev;
        auto next = r._first._next;
        r.popFront();
        BaseNode.connect(prev, next);
    }

/**
Removes last element of `r`, wich must be a range obtained originally
from this container, from both DList instance and range `r`.

Compexity: $(BIGOH 1)
     */
    void popLastOf(ref Range r)
    {
        assert(_root !is null, "Cannot remove from an un-initialized List");
        assert(r._first, "popLastOf: Range is empty");
        auto prev = r._last._prev;
        auto next = r._last._next;
        r.popBack();
        BaseNode.connect(prev, next);
    }

/**
`linearRemove` functions as `remove`, but also accepts ranges that are
result the of a `take` operation. This is a convenient way to remove a
fixed amount of elements from the range.

Complexity: $(BIGOH r.walkLength)
     */
    Range linearRemove(Take!Range r)
    {
        assert(_root !is null, "Cannot remove from an un-initialized List");
        assert(r.source._first, "Remove: Range is empty");

        BaseNode* first = r.source._first;
        BaseNode* last = null;
        do
        {
            last = r.source._first;
            r.popFront();
        } while ( !r.empty );

        return remove(Range(first, last));
    }

    /// ditto
    alias stableLinearRemove = linearRemove;

/**
Removes the first occurence of an element from the list in linear time.

Returns: True if the element existed and was successfully removed, false otherwise.

Params:
    value = value of the node to be removed

Complexity: $(BIGOH n)
     */
    bool linearRemoveElement(T value)
    {
        import std.algorithm.mutation : move;

        auto n1 = findNodeByValue(_root, move(value));
        if (n1)
        {
            auto n2 = n1._next._next;
            BaseNode.connect(n1, n2);
            return true;
        }

        return false;
    }


private:

    BaseNode* findNodeByValue(BaseNode* n, T value)
    {
        if (!n) return null;
        auto ahead = n._next;
        while (ahead && ahead.getPayload!T() != value)
        {
            n = ahead;
            ahead = n._next;
            if (ahead == _last._next) return null;
        }
        return n;
    }

    // Helper: Inserts stuff before the node n.
    size_t insertBeforeNode(Stuff)(BaseNode* n, ref Stuff stuff)
    if (isImplicitlyConvertible!(Stuff, T))
    {
        auto p = createNode(stuff, n._prev, n);
        n._prev._next = p;
        n._prev = p;
        return 1;
    }
    // ditto
    size_t insertBeforeNode(Stuff)(BaseNode* n, ref Stuff stuff)
    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))
    {
        if (stuff.empty) return 0;
        size_t result;
        Range r = createRange(stuff, result);
        BaseNode.connect(n._prev, r._first);
        BaseNode.connect(r._last, n);
        return result;
    }

    // Helper: Inserts stuff after the node n.
    size_t insertAfterNode(Stuff)(BaseNode* n, ref Stuff stuff)
    if (isImplicitlyConvertible!(Stuff, T))
    {
        auto p = createNode(stuff, n, n._next);
        n._next._prev = p;
        n._next = p;
        return 1;
    }
    // ditto
    size_t insertAfterNode(Stuff)(BaseNode* n, ref Stuff stuff)
    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))
    {
        if (stuff.empty) return 0;
        size_t result;
        Range r = createRange(stuff, result);
        BaseNode.connect(r._last, n._next);
        BaseNode.connect(n, r._first);
        return result;
    }

    // Helper: Creates a chain of nodes from the range stuff.
    Range createRange(Stuff)(ref Stuff stuff, ref size_t result)
    {
        BaseNode* first = createNode(stuff.front);
        BaseNode* last = first;
        ++result;
        for ( stuff.popFront() ; !stuff.empty ; stuff.popFront() )
        {
            auto p = createNode(stuff.front, last);
            last = last._next = p;
            ++result;
        }
        return Range(first, last);
    }
}

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

    auto e = DList!int();
    auto b = e.linearRemoveElement(1);
    assert(b == false);
    assert(e.empty());
    auto a = DList!int(-1, 1, 2, 1, 3, 4);
    b = a.linearRemoveElement(1);
    assert(equal(a[], [-1, 2, 1, 3, 4]));
    assert(b == true);
    b = a.linearRemoveElement(-1);
    assert(b == true);
    assert(equal(a[], [2, 1, 3, 4]));
    b = a.linearRemoveElement(1);
    assert(b == true);
    assert(equal(a[], [2, 3, 4]));
    b = a.linearRemoveElement(2);
    assert(b == true);
    b = a.linearRemoveElement(20);
    assert(b == false);
    assert(equal(a[], [3, 4]));
    b = a.linearRemoveElement(4);
    assert(b == true);
    assert(equal(a[], [3]));
    b = a.linearRemoveElement(3);
    assert(b == true);
    assert(a.empty());
    a.linearRemoveElement(3);
}

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

    //Tests construction signatures
    alias IntList = DList!int;
    auto a0 = IntList();
    auto a1 = IntList(0);
    auto a2 = IntList(0, 1);
    auto a3 = IntList([0]);
    auto a4 = IntList([0, 1]);

    assert(a0[].empty);
    assert(equal(a1[], [0]));
    assert(equal(a2[], [0, 1]));
    assert(equal(a3[], [0]));
    assert(equal(a4[], [0, 1]));
}

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

    alias IntList = DList!int;
    IntList list = IntList([0,1,2,3]);
    assert(equal(list[],[0,1,2,3]));
    list.insertBack([4,5,6,7]);
    assert(equal(list[],[0,1,2,3,4,5,6,7]));

    list = IntList();
    list.insertFront([0,1,2,3]);
    assert(equal(list[],[0,1,2,3]));
    list.insertFront([4,5,6,7]);
    assert(equal(list[],[4,5,6,7,0,1,2,3]));
}

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

    alias IntList = DList!int;
    IntList list = IntList([0,1,2,3]);
    auto range = list[];
    for ( ; !range.empty; range.popFront())
    {
        int item = range.front;
        if (item == 2)
        {
            list.stableLinearRemove(take(range, 1));
            break;
        }
    }
    assert(equal(list[],[0,1,3]));

    list = IntList([0,1,2,3]);
    range = list[];
    for ( ; !range.empty; range.popFront())
    {
        int item = range.front;
        if (item == 2)
        {
            list.stableLinearRemove(take(range,2));
            break;
        }
    }
    assert(equal(list[],[0,1]));

    list = IntList([0,1,2,3]);
    range = list[];
    for ( ; !range.empty; range.popFront())
    {
        int item = range.front;
        if (item == 0)
        {
            list.stableLinearRemove(take(range,2));
            break;
        }
    }
    assert(equal(list[],[2,3]));

    list = IntList([0,1,2,3]);
    range = list[];
    for ( ; !range.empty; range.popFront())
    {
        int item = range.front;
        if (item == 1)
        {
            list.stableLinearRemove(take(range,2));
            break;
        }
    }
    assert(equal(list[],[0,3]));
}

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

    auto dl = DList!int([1, 2, 3, 4, 5]);
    auto r = dl[];
    r.popFront();
    dl.popFirstOf(r);
    assert(equal(dl[], [1, 3, 4, 5]));
    assert(equal(r, [3, 4, 5]));
    r.popBack();
    dl.popLastOf(r);
    assert(equal(dl[], [1, 3, 5]));
    assert(equal(r, [3]));
    dl = DList!int([0]);
    r = dl[];
    dl.popFirstOf(r);
    assert(dl.empty);
    dl = DList!int([0]);
    r = dl[];
    dl.popLastOf(r);
    assert(dl.empty);
}

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

    auto dl = DList!string(["a", "b", "d"]);
    dl.insertAfter(dl[], "e"); // insert at the end
    assert(equal(dl[], ["a", "b", "d", "e"]));
    auto dlr = dl[];
    dlr.popBack(); dlr.popBack();
    dl.insertAfter(dlr, "c"); // insert after "b"
    assert(equal(dl[], ["a", "b", "c", "d", "e"]));
}

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

    auto dl = DList!string(["a", "b", "d"]);
    dl.insertBefore(dl[], "e"); // insert at the front
    assert(equal(dl[], ["e", "a", "b", "d"]));
    auto dlr = dl[];
    dlr.popFront(); dlr.popFront();
    dl.insertBefore(dlr, "c"); // insert before "b"
    assert(equal(dl[], ["e", "a", "c", "b", "d"]));
}

@safe unittest
{
    auto d = DList!int([1, 2, 3]);
    d.front = 5; //test frontAssign
    assert(d.front == 5);
    auto r = d[];
    r.back = 1;
    assert(r.back == 1);
}

// https://issues.dlang.org/show_bug.cgi?id=8895
@safe unittest
{
    auto a = make!(DList!int)(1,2,3,4);
    auto b = make!(DList!int)(1,2,3,4);
    auto c = make!(DList!int)(1,2,3,5);
    auto d = make!(DList!int)(1,2,3,4,5);
    assert(a == b); // this better terminate!
    assert(!(a == c));
    assert(!(a == d));
}

@safe unittest
{
    auto d = DList!int([1, 2, 3]);
    d.front = 5; //test frontAssign
    assert(d.front == 5);
    auto r = d[];
    r.back = 1;
    assert(r.back == 1);
}

@safe unittest
{
    auto a = DList!int();
    assert(a.removeFront(10) == 0);
    a.insert([1, 2, 3]);
    assert(a.removeFront(10) == 3);
    assert(a[].empty);
}

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

    //Verify all flavors of ~
    auto a = DList!int();
    auto b = DList!int();
    auto c = DList!int([1, 2, 3]);
    auto d = DList!int([4, 5, 6]);

    assert((a ~ b[])[].empty);
    assert((c ~ d[])[].equal([1, 2, 3, 4, 5, 6]));
    assert(c[].equal([1, 2, 3]));
    assert(d[].equal([4, 5, 6]));

    assert((c[] ~ d)[].equal([1, 2, 3, 4, 5, 6]));
    assert(c[].equal([1, 2, 3]));
    assert(d[].equal([4, 5, 6]));

    a~=c[];
    assert(a[].equal([1, 2, 3]));
    assert(c[].equal([1, 2, 3]));

    a~=d[];
    assert(a[].equal([1, 2, 3, 4, 5, 6]));
    assert(d[].equal([4, 5, 6]));

    a~=[7, 8, 9];
    assert(a[].equal([1, 2, 3, 4, 5, 6, 7, 8, 9]));

    //trick test:
    auto r = c[];
    c.removeFront();
    c.removeBack();
}

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

    // https://issues.dlang.org/show_bug.cgi?id=8905
    auto a = DList!int([1, 2, 3, 4]);
    auto r = a[];
    a.stableRemoveBack();
    a.stableInsertBack(7);
    assert(a[].equal([1, 2, 3, 7]));
}

// https://issues.dlang.org/show_bug.cgi?id=12566
@safe unittest
{
    auto dl2 = DList!int([2,7]);
    dl2.removeFront();
    assert(dl2[].walkLength == 1);
    dl2.removeBack();
    assert(dl2.empty, "not empty?!");
}

// https://issues.dlang.org/show_bug.cgi?id=13076
@safe unittest
{
    DList!int list;
    assert(list.empty);
    list.clear();
}

// https://issues.dlang.org/show_bug.cgi?id=13425
@safe unittest
{
    import std.range : drop, take;
    auto list = DList!int([1,2,3,4,5]);
    auto r = list[].drop(4); // r is a view of the last element of list
    assert(r.front == 5 && r.walkLength == 1);
    r = list.linearRemove(r.take(1));
    assert(r.empty); // fails
}

// https://issues.dlang.org/show_bug.cgi?id=14300
@safe unittest
{
    interface ITest {}
    static class Test : ITest {}

    DList!ITest().insertBack(new Test());
}

// https://issues.dlang.org/show_bug.cgi?id=15263
@safe unittest
{
    import std.range : iota;
    auto a = DList!int();
    a.insertFront(iota(0, 5)); // can insert range with non-ref front
    assert(a.front == 0 && a.back == 4);
}

// https://issues.dlang.org/show_bug.cgi?id=22147
@safe unittest
{
    import std.algorithm.mutation : move;

    static struct Item
    {
        @disable this(this);

        int x;
    }

    auto list = DList!Item();
    list.insertFront(Item(1));
    assert(list[].walkLength == 1);
    assert(list.front.x == 1);
    auto item = list.moveFront;
    item.x = 2;
    list.front = move(item);
    assert(list.front.x == 2);
    list.removeFront();
    assert(list[].walkLength == 0);
}

//  https://issues.dlang.org/show_bug.cgi?id=24637
@safe unittest
{
    import std.algorithm.comparison : equal;

    struct A
    {
        int c;
    }

    DList!A B;
    B.insert(A(1));
    assert(B[].equal([A(1)]));

    const a = A(3);
    B.insert(a);
    assert(B[].equal([A(1), A(3)]));
}
