[Prototype] GC.add/remove Root/Range using treap instead of unsorted array.

Creating this PR for testing, comments, feedback, etc.
This is a rought first prototype which hasn't been polished yet (PRs to this PR are welcome though)
Note:
- Users of core.memory which depended on unspecified behaviour (such as calling addRange/addRoot with the same p parameter multiple times) may suffer breakage.
- Currently iterating over root/ranges uses the stack, it would be possible to use threaded nodes or parent pointers but I'm not convinced the trade off would be worth it.
- If traversing the tree each time we need to scan impacts performance, we could always create a cached array version of the tree (with a dirty flag) which updates the cache if dirty at scan time.
The thing is though, the destructor causes an `opAssign` and a struct destructor to be generated for `gc.gc.Gcx`. The generated `opAssign` will never be able to do anything useful with that destructor implementation. I would say it would be better to require removeAll to be called manually as well...


Actually, as Treap is non-copyable, `gc.gc.Gcx` shouldn't be getting an `opAssign` generated in the first place.