Thread overview
A template construct like using()
Apr 26, 2022
Chris Katko
Apr 26, 2022
H. S. Teoh
Apr 26, 2022
cc
Apr 26, 2022
Adam Ruppe
Apr 27, 2022
user1234
April 26, 2022

I swear I asked something like this before years ago but it doesn't show up in my previous forum posts.

I'm looking for a construct that mimics using(var)/with(var)

bitmap* b;

draw_with(b)
  {
  draw_pixel(red, 16, 16); //draw red pixel to bitmap b (b is implied above)
  }

But the code ends up being:

bitmap* b;

set_target_bitmap(b); //entry code
draw_pixel(red, 16, 16); // body
set_target_bitmap(original_target); // exit code

The essence is wrapping something the code up in a kind of RAII-like entry and exit code that references a given target variable.

Perhaps a mixin is what I'm looking for?

April 26, 2022
On Tue, Apr 26, 2022 at 09:33:43PM +0000, Chris Katko via Digitalmars-d-learn wrote: [...]
> I'm looking for a construct that mimics using(var)/with(var)
> 
> ````D
> bitmap* b;
> 
> draw_with(b)
>   {
>   draw_pixel(red, 16, 16); //draw red pixel to bitmap b (b is implied above)
>   }
> ````
> 
> But the code ends up being:
> ````D
> bitmap* b;
> 
> set_target_bitmap(b); //entry code
> draw_pixel(red, 16, 16); // body
> set_target_bitmap(original_target); // exit code
> ````
> 
> The essence is wrapping something the code up in a kind of RAII-like entry and exit code that references a given target variable.
[...]

Kinda ugly-looking, but here's the first idea that came to mind:

	bitmap* b;
	{
		set_target_bitmap(b);
		scope(exit) set_target_bitmap(original_target);

		draw_pixel(...);
		... // blah blah blah
	} // scope(exit) runs here


T

-- 
Unix was not designed to stop people from doing stupid things, because that would also stop them from doing clever things. -- Doug Gwyn
April 26, 2022

On Tuesday, 26 April 2022 at 21:33:43 UTC, Chris Katko wrote:

>

I swear I asked something like this before years ago but it doesn't show up in my previous forum posts.

I'm looking for a construct that mimics using(var)/with(var)

void draw_with(bitmap* drawb, void delegate() dg) {
	set_target_bitmap(drawb);
	dg();
	set_target_bitmap(original_target);
}

bitmap* b;
draw_with(b, {
	draw_pixel(red, 16, 16);
});

If your draw code doesn't depend on any scoped state you can use function() instead of delegate() to save a GC call.

April 26, 2022

On Tuesday, 26 April 2022 at 23:00:57 UTC, cc wrote:

>

If your draw code doesn't depend on any scoped state you can use function() instead of delegate() to save a GC call.

scope delegate also works here and just reuses the stack.

April 27, 2022

On Tuesday, 26 April 2022 at 21:33:43 UTC, Chris Katko wrote:

>

I swear I asked something like this before years ago but it doesn't show up in my previous forum posts.

I'm looking for a construct that mimics using(var)/with(var)

bitmap* b;

draw_with(b)
  {
  draw_pixel(red, 16, 16); //draw red pixel to bitmap b (b is implied above)
  }

But the code ends up being:

bitmap* b;

set_target_bitmap(b); //entry code
draw_pixel(red, 16, 16); // body
set_target_bitmap(original_target); // exit code

The essence is wrapping something the code up in a kind of RAII-like entry and exit code that references a given target variable.

Perhaps a mixin is what I'm looking for?

assuming set_target_bitmap returns the previous target :

struct Bitmap
{
}

struct PushPopBitmap
{
    Bitmap* bitmap;
    Bitmap* old;
    alias bitmap this;

    this(Bitmap* bmp) {
        old = set_target_bitmap(bitmap = bmp);
    }

    ~this() {
        set_target_bitmap(old);
    }
}

Bitmap* set_target_bitmap(Bitmap* bmp);
void draw_pixel();

void main()
{
    Bitmap* bmp;
    with (PushPopBitmap(bmp)) draw_pixel();
}

At the end of the WithStatement block that restores the previous context.