digitalmars.D - / single linked homogenous list template
- Bjoern (71/71) May 03 2008 OR : Lisp like List in D Take 2
- Koroskin Denis (65/137) May 04 2008 Now that we have opDot() and other features, you can implement Ref!(T)
- Bjoern (15/15) May 05 2008 Thanks!
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 ?
May 03 2008
On Sun, 04 May 2008 03:16:04 +0400, Bjoern <nanali 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!
May 04 2008
Thanks! Have no D2 on board... Probabely this works ??? struct Ref(T) { public opDot!(T) { static if(is(typeof(T.opDot)) { return value; } } private T* value; } Bjoern PS hope Walter will spend us ref return values soon
May 05 2008