On Sun, Sep 2, 2012 at 12:39 AM, Philippe Sigaud <philippe.sigaud@gmail.com> wrote:
> To make a type "double linkable" the developer needs to mixin the following mixin template:
>
>> mixin template DoubleLinkable()
>> {
>> typeof(this) next;
>> typeof(this) prev;
>> }
>
>
> The next and prev pointer can be access with the help of mixin by using the following templates:
>
>> T* next(T, string name)(T node) pure nothrow const
>>
>> {
>>
>> mixin("return &(node." ~ name ~ ".next);");
>>
>> }These are free functions? Why not put them in the mixin templates?
> To use the above abstraction the developer just needs to do the following:
>
>> class Person
>> {
>> int age;
>> int weight;
>> mixin DoubleLinkable people;
>> }Oh, named mixins! Yet another D feature I totally forgot. Hey, those reading this, who here knew you could do 'mixin someTemplate someName;' to refer to the template scope by the given name?
> I am not a big fan of the template signature 'class DoubleLinkedList(T, string name)' but I couldn't figure out a better way of allowing one object to be embedded in multiple containers. Thoughts? Any idea how this can be improved so that it is easier to use and read?
I didn't read the blog post, but any reason why you do not put all the list machinery in a mixin template and refer directly to next/prev?
I'm on a pad, so typing is not so easy, but like this:
mixin template NodeImplementation()
{
// should detect if typeof(this) is a reference type or a value type.
// for a reference type, we should not use pointers.
typeof(this) next() @property { return *_next;}
typeof(this) prev() @property { return *_prev;}
/// + setters also
private *typeof(this) _next,_prev;
}struct Person()
{
mixin NodeImplementation;
string name;
int age;
}And DoublyLinkedList(Node) if (isNode!Node)
with
/**
A node is a type T that has .next and .prev fields
that return another T.
*/
isNode(T)
{
enum isNode = __traits(compiles, { T p = T.init.prev; T n = T.init.next;});
}