FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Templates for writing code...

 
Post new topic   Reply to topic     Forum Index -> General
View previous topic :: View next topic  
Author Message
Brian



Joined: 08 Mar 2007
Posts: 13
Location: Talent, OR

PostPosted: Fri Mar 23, 2007 11:21 am    Post subject: Templates for writing code... Reply with quote

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
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Fri Mar 23, 2007 2:16 pm    Post subject: Reply with quote

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
View user's profile Send private message
Brian



Joined: 08 Mar 2007
Posts: 13
Location: Talent, OR

PostPosted: Mon Mar 26, 2007 12:52 pm    Post subject: RE: Templates for writing code... Reply with quote

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
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Mon Mar 26, 2007 11:15 pm    Post subject: Re: RE: Templates for writing code... Reply with quote

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
View user's profile Send private message
Brian



Joined: 08 Mar 2007
Posts: 13
Location: Talent, OR

PostPosted: Tue Mar 27, 2007 3:32 pm    Post subject: Ok, sounds good... Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> General All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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