Jump to page: 1 2
Thread overview
TList
Mar 17, 2008
lurker
Mar 18, 2008
lurker
Mar 18, 2008
Ary Borenszweig
Mar 18, 2008
Sclytrack
Mar 18, 2008
Frits van Bommel
Mar 19, 2008
Jesse Phillips
Mar 19, 2008
Frits van Bommel
Mar 19, 2008
Jesse Phillips
Mar 19, 2008
Robert Fraser
Are dynamic arrays passed by value? (Was: TList)
Mar 19, 2008
Ary Borenszweig
March 17, 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
March 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?
>
> thanks

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


March 18, 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?
> >
> > thanks
> 
> For those of us who have never used Borland C++, could you explain what a TList is/does?
> 
> 

March 18, 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?
>>>
>>> thanks
>> For those of us who have never used Borland C++, could you explain what a TList is/does? 
>>
>>
> 
March 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.
March 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.
March 19, 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.
March 19, 2008
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?

March 19, 2008
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).
March 19, 2008
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 :)
« First   ‹ Prev
1 2