View previous topic :: View next topic |
Author |
Message |
Brian
Joined: 08 Mar 2007 Posts: 13 Location: Talent, OR
|
Posted: Fri Mar 23, 2007 11:21 am Post subject: Templates for writing code... |
|
|
Hi all,
I'm new to D and really REALLY like it. I've been writing this wrapper around Mike Cowlishaw's decNumber library and have gotten farther in a shorter time than I would have imagined, all due to D's powerful and elegant design.
One thing I've run into a couple of times though, is wanting to reduce redundant code by using templates. It seems like you can't do it because templates are only for declarations. Now I've got a situation that really bugs me, and I'd like an elegant way around it but can't see one.
I've got a decimal number class that implements free lists. Each decimal context class keeps a free list of decimal numbers it has created. Now, to use these decimal numbers on the free list, the programmer must use an allocate (create_decimal()) and deallocate method call. So I would like to write a template that expands to code like this:
rdbms_decimal name = create_decimal();
scope(exit) {deallocate(name);}
Which of course doesn't work because there's more than just declarations here. It sucks having to remember to clutter up your code with all the scope statements to deallocate the decimals; I'd so much rather have the code generated with an allocate_decimal!() template instantiation since you know you're going to want to issue one for every create_decimal() call you make. Does anyone know of a way to do this or have a better solution?
Thanx
Brian |
|
Back to top |
|
|
sean
Joined: 24 Jun 2004 Posts: 609 Location: Bay Area, CA
|
Posted: Fri Mar 23, 2007 2:16 pm Post subject: |
|
|
Can you implement a custom allocator inside your decimal class and use "scope" for declarations you want cleaned up on scope end? ie.
Code: |
class Decimal
{
new( size_t sz )
{
// if one exists on the free list return it
// else
return new void[sz].ptr;
}
delete( void* ptr )
{
// add ptr to the free list
}
}
...
scope d = new Decimal();
|
The drawback to this approach is that the dtor of the Decimal class will be run on deletion, so you'll have to be careful not to clean up state you want to retain. |
|
Back to top |
|
|
Brian
Joined: 08 Mar 2007 Posts: 13 Location: Talent, OR
|
Posted: Mon Mar 26, 2007 12:52 pm Post subject: RE: Templates for writing code... |
|
|
This was my initial idea, but I thought it wouldn't work because object destruction would deallocate memory. Maybe I'm just thinking in terms of C/C++ though.
If I write a deallocator that adds the object to a freelist, will the memory for those objects be deallocated after (or is it before) the dtor exits (because it's a scope variable), even if there's still a valid reference to the object?
I've come up with a compromise that I'm moderately happy with. I made the deallocate function that returns the decimals to the freelist variadic. I can now deallocate all the variables I allocate in one scope (exit) statement. Much less clutter, but still some. I'd rather have none at all.
In this way, the allocator/deallocator solution is better. If that would work, I'd prefer to do that. Currently, for optimal performance you can't use the overloaded binary operators for more than two operands because they allocate a new decimal (taken from the freelist) to return the results of their operation. If you use more than two operands in an expression, you end up leaking temporary decimals. These are of course cleaned up by the garbage collector, but it defeats the purpose of the freelist.
If I could use the allocators and deallocators approach, I wouldn't have to worry about the above problem. The objects would always be returned to the freelist. |
|
Back to top |
|
|
sean
Joined: 24 Jun 2004 Posts: 609 Location: Bay Area, CA
|
Posted: Mon Mar 26, 2007 11:15 pm Post subject: Re: RE: Templates for writing code... |
|
|
Brian wrote: | This was my initial idea, but I thought it wouldn't work because object destruction would deallocate memory. Maybe I'm just thinking in terms of C/C++ though.
If I write a deallocator that adds the object to a freelist, will the memory for those objects be deallocated after (or is it before) the dtor exits (because it's a scope variable), even if there's still a valid reference to the object? |
If you write a custom deallocator the it's in charge of deallocating memory. All the system will do is call the object's dtor and release its monitor. For reference, you can check internal/gc/gc.d:_d_delclass(). |
|
Back to top |
|
|
Brian
Joined: 08 Mar 2007 Posts: 13 Location: Talent, OR
|
Posted: Tue Mar 27, 2007 3:32 pm Post subject: Ok, sounds good... |
|
|
I checked out the source file you referenced and it looks like it does do what I want. I also saw the reference in the DOCs about needing to clean up your own memory if you use allocators/deallocators.
It also looks like the deallocator is always called on class destruction if the class has one. So here's one more question:
In my situation, the decimal context object keeps the freelist. If the decimal context is deallocated, all the decimals on the freelist should be deallocated as well.
So if the memory for the decimal is allocated out of gc collected memory, and the deallocator returns it to the freelist, will the decimal ever be deallocated? It looks to me like if the context object containing the freelist is deallocated, the gc will eventually try to deallocate all the objects on the freelist, which will then try to add themselves back to a freelist in a non-existent context. Does this sound correct?
In that case, I can add a flag to the decimal object that defaults to false, but when true, causes the deallocator to return the decimal to the free list and when false, frees the memory it's using. Then the dtor of the context will set all of its freelist object's flags back to false, causing them to be freed when next the gc runs.
This allows the user to manually allocate their own decimals that will be garbage collected if they choose rather than forcing them to use the freelist (by using two different constructors, one simply allocating, the other taking from the freelist). Not sure this would ever be used, but it would indeed be nice to have if needed. It also allows temp decimals generated in expression evaluation to be returned to the freelist invisibly. Nice!!!
If my assumptions above are correct that is....
Thanx again,
Brian |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|