digitalmars.D.learn - TList
- lurker (4/4) Mar 17 2008 hi all,
- Jarrett Billingsley (4/8) Mar 17 2008 For those of us who have never used Borland C++, could you explain what ...
- lurker (4/16) Mar 17 2008 the best i can do is to offer a link. one will better understand that th...
- Ary Borenszweig (35/56) Mar 18 2008 It seems TList is just a list of anything. In that case, you can use
- Sclytrack (10/10) Mar 18 2008 I believe TList from Borland keeps an array that doubles in size.
- Frits van Bommel (18/19) Mar 18 2008 It doesn't use C realloc(). In fact, it can't for several reasons:
- Jesse Phillips (3/15) Mar 18 2008 This is something I've wondered about, so D will grow the array in-place...
- Frits van Bommel (21/37) Mar 18 2008 (Imagine this post liberally sprinkeled with "IIRC"s :) )
- Jesse Phillips (2/41) Mar 18 2008 Thanks, lots of good stuff :)
- Robert Fraser (2/7) Mar 18 2008 Tango's Seq does this AFAIK.
- Ary Borenszweig (4/73) Mar 18 2008 Writing that code without "ref" in "add" and "get" didn't work well the
- Jarrett Billingsley (19/22) Mar 19 2008 Yes, but the reference isn't passed by reference ;)
- lurker (2/14) Mar 18 2008
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
"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? thanksFor those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 17 2008
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? thanksFor those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 17 2008
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? thanksFor those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 18 2008
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
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
On Wed, 19 Mar 2008 00:15:43 +0100, Frits van Bommel wrote:Sclytrack wrote:This is something I've wondered about, so D will grow the array in-place on the ram?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).
Mar 18 2008
Jesse Phillips wrote:On Wed, 19 Mar 2008 00:15:43 +0100, Frits van Bommel wrote:(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).Sclytrack wrote:This is something I've wondered about, so D will grow the array in-place on the ram?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).
Mar 18 2008
On Wed, 19 Mar 2008 03:18:58 +0100, Frits van Bommel wrote:Jesse Phillips wrote:Thanks, lots of good stuff :)On Wed, 19 Mar 2008 00:15:43 +0100, Frits van Bommel wrote:(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).Sclytrack wrote:This is something I've wondered about, so D will grow the array in-place on the ram?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).
Mar 18 2008
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
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? thanksFor those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 18 2008
"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
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? thanksFor those of us who have never used Borland C++, could you explain what a TList is/does?
Mar 18 2008