Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login


19 May, 2024: Line wrapping has been changed to be more consistent with Usenet standards.
 If you find that it is broken please let me know here

devel / comp.lang.c++ / The most versatile scope-guard

o The most versatile scope-guardBonita Montero

The most versatile scope-guard


  copy mid

  copy link   Newsgroups: comp.lang.c++
From: (Bonita Montero)
Newsgroups: comp.lang.c++
Subject: The most versatile scope-guard
Date: Tue, 5 Mar 2024 13:51:19 +0100
Organization: A noiseless patient Spider
Lines: 63
Message-ID: <us74fu$3p12c$>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 5 Mar 2024 12:51:10 -0000 (UTC)
Injection-Info:; posting-host="f14c7aad57de1eb32b96e464726dea52";
logging-data="3966028"; mail-complaints-to=""; posting-account="U2FsdGVkX18gQeR47F+TH+DNA5ECg+hQtn/7DH4cHzk="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:ETQG3LR1/ukYAIaDIXw0eBtsI4M=
Content-Language: de-DE
 by: Bonita Montero - Tue, 5 Mar 2024 12:51 UTC

I'm sometimes doing multiple changes with more than a single data
structure which have to be reverted if the latest change throws an
exception. Until today I used my home-brew experimental::scope_guard
like class multiple times and I disabled each individual scope-object
when all changes have finished.
So I got the idea to concatenate multiple scope-guards and If i disable
the a child scope-guard in the chain all depending scope-guards also
will be disabled; re-enabling the latest scope-guard also propagates
through the chain. Disabling parent scope-guards won't have an effect,
i.e only the last enable-state in the chain counts. Enabling and dis-
abling is propagated to the immediate parent on destruction.

#pragma once#pragma once
#include <utility>

template<typename Fn>
struct invoke_on_destruct;

struct iod_base
{ private:
template<typename Fn>
friend struct invoke_on_destruct;
bool m_enabled;
iod_base *m_next;
iod_base( iod_base *next ) :
m_enabled( true ),
m_next( next )

template<typename Fn>
struct invoke_on_destruct final : public iod_base
{ private:
Fn m_fn;
invoke_on_destruct( Fn &&fn, iod_base *next = nullptr )
requires requires( Fn fn ) { { fn() }; } :
iod_base( next ),
m_fn( std::forward<Fn>( fn ) )
// enable or disable parent node according to our state;
// use a conditional move for efficiency
bool enabled = (m_next ? m_next : this)->m_enabled = m_enabled;
// are we enabled ?
if( enabled ) [[unlikely]]
// yes: invoke
void disable()
m_enabled = false;
invoke_on_destruct &enable()
m_enabled = true;

devel / comp.lang.c++ / The most versatile scope-guard


rocksolid light 0.9.81
clearnet tor