www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - TList

reply lurker <lurker lurker.com> writes:
hi all,
with borland c++ one does have with the VCL the TList.
is there anything like TList in D that one can use instead?

thanks
Mar 17 2008
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"lurker" <lurker lurker.com> wrote in message 
news:frmfko$1rg6$1 digitalmars.com...
 hi all,
 with borland c++ one does have with the VCL the TList.
 is there anything like TList in D that one can use instead?

 thanks
For those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 17 2008
parent reply lurker <lurker lurker.com> writes:
the best i can do is to offer a link. one will better understand that then my
english:

http://www.functionx.com/bcb/classes/tlist.htm

thanks


Jarrett Billingsley Wrote:

 "lurker" <lurker lurker.com> wrote in message 
 news:frmfko$1rg6$1 digitalmars.com...
 hi all,
 with borland c++ one does have with the VCL the TList.
 is there anything like TList in D that one can use instead?

 thanks
For those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 17 2008
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
It seems TList is just a list of anything. In that case, you can use 
this code:

---
import std.stdio;

// Starts definition of TList
alias void*[] TList;

void add(T)(ref TList list, T elem) {
	list ~= cast(void*) elem;
}

void* get(ref TList list, int index) {
	return list[index];
}
// Ends definition of TList

class Foo {
}

class Bar {
}

void main()
{
     TList list;
     list.add(new Foo());
     list.add(new Bar());
     list.add(3);

     Foo foo = cast(Foo) list.get(0);
     writefln("At 0: %s", foo.stringof);

     Bar bar = cast(Bar) list.get(1);
     writefln("At 1: %s", bar.stringof);

     int val = cast(int) list.get(2);
     writefln("At 2: %s", val);

     writefln("Length: %s", list.length);
}
---

However, if you need a list of a specific type, you can use dynamic 
arrays: http://digitalmars.com/d/1.0/arrays.html

lurker wrote:
 the best i can do is to offer a link. one will better understand that then my
english:
 
 http://www.functionx.com/bcb/classes/tlist.htm
 
 thanks
 
 
 Jarrett Billingsley Wrote:
 
 "lurker" <lurker lurker.com> wrote in message 
 news:frmfko$1rg6$1 digitalmars.com...
 hi all,
 with borland c++ one does have with the VCL the TList.
 is there anything like TList in D that one can use instead?

 thanks
For those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 18 2008
next sibling parent reply Sclytrack <Sclytrack pi.be> writes:
I believe TList from Borland keeps an array that doubles in size.

8 16 32 64

and that the list.Count value that you get is always smaller than
the actual size of the array. This doubling requires usually more
memory for each array.
It uses pointers because it wants to be as general as possible,
No generics back then.

I was told that adding an array in D uses realloc (Haven't verified this),

Disclaimer:
My Borland is a bit rusty, so I might be wrong, currently no windows installed.
Mar 18 2008
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Sclytrack wrote:
 I was told that adding an array in D uses realloc (Haven't verified this),
It doesn't use C realloc(). In fact, it can't for several reasons: 1) realloc only works on memory allocated by the normal C allocation functions (malloc, calloc), which D doesn't use because they don't[*] support GC. 2) realloc is supposed[*] to free the original if reallocation succeeds but the array was moved, which isn't what's supposed to happen when a D array grows (the old one is left for anyone who still has references to it; the GC cleans it up if that's not the case). [*]: Of course, a GC such as Boehm's might fix these issues. IIRC it provides its own malloc subsystem with a no-op free(). If that includes the implicit one in realloc() it could work. However, the internal routine that is in fact called by the '~=' operator is called realloc (but it's a member function) and is exposed as std.gc.realloc (Phobos) / tango.core.Memory.gc_realloc (Tango, declared extern(C)). The name is the same, but it has slightly different semantics than the standard C version.
Mar 18 2008
parent reply Jesse Phillips <jessekphillips gmail.com> writes:
On Wed, 19 Mar 2008 00:15:43 +0100, Frits van Bommel wrote:

 Sclytrack wrote:
 I was told that adding an array in D uses realloc (Haven't verified
 this),
It doesn't use C realloc(). In fact, it can't for several reasons: 1) realloc only works on memory allocated by the normal C allocation functions (malloc, calloc), which D doesn't use because they don't[*] support GC. 2) realloc is supposed[*] to free the original if reallocation succeeds but the array was moved, which isn't what's supposed to happen when a D array grows (the old one is left for anyone who still has references to it; the GC cleans it up if that's not the case).
This is something I've wondered about, so D will grow the array in-place on the ram?
Mar 18 2008
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Jesse Phillips wrote:
 On Wed, 19 Mar 2008 00:15:43 +0100, Frits van Bommel wrote:
 
 Sclytrack wrote:
 I was told that adding an array in D uses realloc (Haven't verified
 this),
It doesn't use C realloc(). In fact, it can't for several reasons: 1) realloc only works on memory allocated by the normal C allocation functions (malloc, calloc), which D doesn't use because they don't[*] support GC. 2) realloc is supposed[*] to free the original if reallocation succeeds but the array was moved, which isn't what's supposed to happen when a D array grows (the old one is left for anyone who still has references to it; the GC cleans it up if that's not the case).
This is something I've wondered about, so D will grow the array in-place on the ram?
(Imagine this post liberally sprinkeled with "IIRC"s :) ) The GC allocates memory in pools[1], with all blocks of memory in a pool having the same size[2]. If an array is appended to using ~=[3] it will be done in-place if these conditions hold: 1) The array is GC-allocated. 2) The array starts at the first byte of the block it's allocated in. 3) The resulting array will still fit into the block (i.e. there's still room) If one of them doesn't hold, the append routine allocates a new block of memory to hold the result in an appropriate pool for its size, as if it had just been 'new'ed[4]. [1]: Large objects are allocate separately. [2]: I don't know which sizes it uses, but powers of two are usual for this sort of thing. [3]: Not with ~, which allocates unconditionally (even if one of the operands is empty). [4]: Except perhaps uninitialized, since the append routine has access to internal GC functions and it can guarantee it'll always overwrite the whole block (the start with the result of concatenating the input arrays, and the rest with 0).
Mar 18 2008
parent Jesse Phillips <jessekphillips gmail.com> writes:
On Wed, 19 Mar 2008 03:18:58 +0100, Frits van Bommel wrote:

 Jesse Phillips wrote:
 On Wed, 19 Mar 2008 00:15:43 +0100, Frits van Bommel wrote:
 
 Sclytrack wrote:
 I was told that adding an array in D uses realloc (Haven't verified
 this),
It doesn't use C realloc(). In fact, it can't for several reasons: 1) realloc only works on memory allocated by the normal C allocation functions (malloc, calloc), which D doesn't use because they don't[*] support GC. 2) realloc is supposed[*] to free the original if reallocation succeeds but the array was moved, which isn't what's supposed to happen when a D array grows (the old one is left for anyone who still has references to it; the GC cleans it up if that's not the case).
This is something I've wondered about, so D will grow the array in-place on the ram?
(Imagine this post liberally sprinkeled with "IIRC"s :) ) The GC allocates memory in pools[1], with all blocks of memory in a pool having the same size[2]. If an array is appended to using ~=[3] it will be done in-place if these conditions hold: 1) The array is GC-allocated. 2) The array starts at the first byte of the block it's allocated in. 3) The resulting array will still fit into the block (i.e. there's still room) If one of them doesn't hold, the append routine allocates a new block of memory to hold the result in an appropriate pool for its size, as if it had just been 'new'ed[4]. [1]: Large objects are allocate separately. [2]: I don't know which sizes it uses, but powers of two are usual for this sort of thing. [3]: Not with ~, which allocates unconditionally (even if one of the operands is empty). [4]: Except perhaps uninitialized, since the append routine has access to internal GC functions and it can guarantee it'll always overwrite the whole block (the start with the result of concatenating the input arrays, and the rest with 0).
Thanks, lots of good stuff :)
Mar 18 2008
prev sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Sclytrack wrote:
 I believe TList from Borland keeps an array that doubles in size.
 
 8 16 32 64
 
 and that the list.
Tango's Seq does this AFAIK.
Mar 18 2008
prev sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Writing that code without "ref" in "add" and "get" didn't work well the 
first time. I got array index out of bounds. Aren't dynamic arrays 
always passed by reference?

Ary Borenszweig escribió:
 It seems TList is just a list of anything. In that case, you can use 
 this code:
 
 ---
 import std.stdio;
 
 // Starts definition of TList
 alias void*[] TList;
 
 void add(T)(ref TList list, T elem) {
     list ~= cast(void*) elem;
 }
 
 void* get(ref TList list, int index) {
     return list[index];
 }
 // Ends definition of TList
 
 class Foo {
 }
 
 class Bar {
 }
 
 void main()
 {
     TList list;
     list.add(new Foo());
     list.add(new Bar());
     list.add(3);
 
     Foo foo = cast(Foo) list.get(0);
     writefln("At 0: %s", foo.stringof);
 
     Bar bar = cast(Bar) list.get(1);
     writefln("At 1: %s", bar.stringof);
 
     int val = cast(int) list.get(2);
     writefln("At 2: %s", val);
 
     writefln("Length: %s", list.length);
 }
 ---
 
 However, if you need a list of a specific type, you can use dynamic 
 arrays: http://digitalmars.com/d/1.0/arrays.html
 
 lurker wrote:
 the best i can do is to offer a link. one will better understand that 
 then my english:

 http://www.functionx.com/bcb/classes/tlist.htm

 thanks


 Jarrett Billingsley Wrote:

 "lurker" <lurker lurker.com> wrote in message 
 news:frmfko$1rg6$1 digitalmars.com...
 hi all,
 with borland c++ one does have with the VCL the TList.
 is there anything like TList in D that one can use instead?

 thanks
For those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 18 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Ary Borenszweig" <ary esperanto.org.ar> wrote in message 
news:frqsik$1ngj$1 digitalmars.com...
 Writing that code without "ref" in "add" and "get" didn't work well the 
 first time. I got array index out of bounds. Aren't dynamic arrays always 
 passed by reference?
Yes, but the reference isn't passed by reference ;) It's the same as something like: void foo(char* s) { ... s = realloc(s, 20); } Now s points to a new place in memory. Yes, the contents pointed to by s were passed by reference, but the caller doesn't see the update to s. In the same way: void foo(char[] s) { ... s ~= "hi!"; } The local variable 's' is updated in the function, but the caller may not see those changes.
Mar 19 2008
prev sibling parent lurker <lurker lurker.com> writes:
thank you all for the help and the enlightenment.

Jarrett Billingsley Wrote:

 "lurker" <lurker lurker.com> wrote in message 
 news:frmfko$1rg6$1 digitalmars.com...
 hi all,
 with borland c++ one does have with the VCL the TList.
 is there anything like TList in D that one can use instead?

 thanks
For those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 18 2008