www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - / single linked homogenous list template

reply Bjoern <nanali nospam-wanadoo.fr> writes:
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

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
parent reply "Koroskin Denis" <2korden gmail.com> writes:
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
parent Bjoern <nanali nospam-wanadoo.fr> writes:
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