Split DList Node into DNode and PayNode.

This splits the "Nodes" in DList into two types of node:
- The "base" DNode that has no payload.
- The "derived" PayLoad: A DNode with a payload.

Doing this helps avoid allocating a T for no reason in the sentinel node. It should also remove some template bloat, as a few functions actually had no dependency on the type carried by the payload.

@DmitryOlshansky : What do you think?
Legacy I guess :) . That said, it can be simplified to a single `!`, since we just want to compare binary states. Which do you prefer:
```D
assert(!first == !last, "Dlist.Range.this: Invalid arguments");
or
assert(first is null == last is null, "Dlist.Range.this: Invalid arguments");
```