On Friday, 4 September 2015 at 23:15:54 UTC, Andrei Alexandrescu wrote:
My thinking is that significant work in this(this) is poor D style. Eager copying for containers doesn't seem like the best way to go. -- Andrei

I would still prefer classes to the embedded RefCounted approach. It's more flexible. If a class is used, a user can wrap it in a RefCounted if they want, and eventually, if http://wiki.dlang.org/DIP74 works out, an extra template parameter could be provided to to enable the ref counting for the container without changing any of the caller's syntax.

Example:
class List(T, bool refCounted = false) {
    static if(refCounted) {
        // opAddRef(), opRelease(), etc..
    }
}

I think my solution is still the base of something more robust, however.
In the following example, all three storage types are allowed:

struct ListBase(T) { } // represents my List(T) as currently implemented

enum ListType {
        Stack,
        RefCounted,
        Heap
}

// defaults to RefCounted to avoid eager copying
template List(T, ListType mode = ListType.RefCounted)
{
        static if(mode == ListType.Stack) {
                alias List = ListBase!T;
        }
        else static if(mode == ListType.RefCounted) {
                alias List = RefCounted!(ListBase!T);
        }
        else {
                final class List {
                        ListBase!T _list;
                        alias _list this;
                        
                        this(Args...)(Args args) {
                                _list = ListBase!T(args);
                        }
                }
        }
}

void main(string[] args)
{
List!int a = [1, 2, 3]; // ref counted by default List!(int, ListType.Stack) b = [1, 2, 3]; // stack allocated auto c = new List!(int, ListType.Heap)([1, 2, 3]); // GC heap allocated
}

Reply via email to