'raii' for structs

David Medlock noone at nowhere.com
Fri Oct 27 06:04:16 PDT 2006


Don Clugston wrote:
> I'm trying to get an implementation of floating-point rounding modes.
> Normally, you set the rounding mode at the start of a function, and 
> restore it at exit.
> 
> void somefunc()
> {
>  RoundingMode oldmode = setRoundingMode(ROUNDTOZERO);
> :
> :
> :
>  setRoundingMode(oldmode);
> }
> 
> It's a classic RAII situation.
> In C++, you'd do it as:
> 
> struct TemporaryRoundingMode
> {
>   RoundingMode oldmode;
>   TemporaryRoundingMode(RoundingMode newmode)
>     { oldmode = setRoundingMode(newmode); }
> ~TemporaryRoundingMode() { setRoundingMode(oldmode); }
> };
> 
> void somefunc()
> {
>   TemporaryRoundingMode tempMode(ROUNDTOZERO);
>   :
>   :
> }
> 
> How can it be done in D? It's only 2 asm instructions, you definitely do 
> not want memory allocation happening.
> 
> Unfortunately you can't do
> 
> template TempRoundingMode(int mode)
> {
>   int oldmode = setRoundingMode(mode);
>   scope(exit) int junk = setRoundingMode(oldmode);
> }
> 
> void somefunc()
> {
>   mixin TemporaryRoundingMode!(ROUNDTOZERO);
>   :
>   :
> }
> 
> which doesn't require you to name a useless temporary variable; but it 
> doesn't work, because you can't use scope(exit) in a mixin. And you 
> couldn't do variables that way, anyway.
> 
> Any ideas?

Using inner functions its just as clean IMO.

void withRounding( int mode, void delegate() dg )
{
   setRoundingMode( mode);
   dg();
   restoreRoundingMode();
}

Then to use it:

void foo()
{
   withRounding( ROUNDTOZERO, { ..do some stuff here } );
}

-David



More information about the Digitalmars-d-learn mailing list