/ single linked homogenous list template

Koroskin Denis 2korden at gmail.com
Sun May 4 01:38:15 PDT 2008


On Sun, 04 May 2008 03:16:04 +0400, Bjoern <nanali at nospam-wanadoo.fr>  
wrote:

> OR : Lisp like List in D Take 2
>
> Andrew McKinley from Axxon / Suneido Software was gentle enough to allow
> me to show his C++ code to discuss what is (or what is actually not)
> possible in D2.
>
> I'll attach his source as reference however the most interesting parts  
> are :
> How you work around for reference return values ?
> Copy constructor ...
> Some C++ specific operator overloads
>
> ...I am not asking you to to my homework... it is just that I can't find
> a satisfying solution regarding a D port of this specific software.
>
> --
> Okay a Lisp list is based on a CONS CELL
> a CONS CELL defined in C  will look like :
> typedef void   *POINTER;      /* General purpose pointer */
>
>
> typedef struct                /* A CONS is two pointers  */
>     {
>     POINTER  car;
>     POINTER  cdr;
>     } CONS;
> typedef CONS    *LIST;        /* A LIST is a pointer to  */
>                                /* a CONS
> // which becomes in D
>
> alias void*  POINTER;
> struct CONS
> {
>     POINTER  car;
>     POINTER  cdr;
> }
> alias CONS* LIST;
>
> which is nonsense (sorry reg. the mess I've published before Bearophile)
>
> So :
> struct CONS(T)
> {
>     T value;
>     CONS* next;
> }
> //makes a bit more sense
>
> A Q and Dirty implementation of LispList is :
>
> class Lisp(T)
> {
>    this(T) {}
>
>
>    scope class Cons(T) //erm
>    {
>       this(T)
>        {}
>    }
>
>
> }
>
> Well we have to look at the attached source now :
> You'll find a lot of stuff -< which is not doable in D. Workarounds ?
> just have a look at
> T& operator[](int i)
> { return nth(i); }
>
> const T& operator[](int i) const
> 	{ return nth(i); }
>
>
> Yummie
>
> Back to the cons cell. I really wonder if array slicing is an option
> here . Let's say :
> //INSTEAD OF
> struct CONS(T)
> {
>     T value;
>     CONS* next;
> }
>
>
> struct CONS(T)
> {
>     T value;
>     CONS*[] cons;
> }
>
> ???????
> Just for me it seems that porting C++ is not a stringent task.
>
> What do yopu think ?
>
>
>
>

Now that we have opDot() and other features, you can implement Ref!(T)  
template that would behave just like T&.
Quick and Dirty implementation is as follows (code amount could be reduced  
by using string mixins):

// helper templates
template OpNegRes(T)
{
     static if (is(T t)) {
         alias typeof(-t) OpNegRes;
     } else {
         static assert(false);
     }
}

template OpPosRes(T)
{
     static if (is(T t)) {
         alias typeof(+t) OpPosRes;
     } else {
         static assert(false);
     }
}

template OpComRes(T)
{
     static if (is(T t)) {
         alias typeof(~t) OpComRes;
     } else {
         static assert(false);
     }
}

struct Ref(T)
{
     public OpNegRes!(T) opNeg()
     {
         return -(*value);
     }

     public OpPosRes!(T) opPos()
     {
         return +(*value);
     }

     public OpComRes!(T) opCom()
     {
         return ~(*value);
     }

     public T* opDot()
     {
         return value;
     }

     private T* value;
}

// small test
int main()
{
     int i = 1;
     auto reference = Ref!(int)(&i);
     assert(-reference == -i);
     assert(+reference == +i);
     assert(~reference == ~i);

     return 0;
}


Other operators are implementable in a similar way.
Note that opDot() is D2.0 only (as of now).

If you know of other ways to achieve the same goal, please share your  
knowledge!



More information about the Digitalmars-d mailing list