Deutsch   English   Français   Italiano  
<1026f3t$gfc6$3@raubtier-asyl.eternal-september.org>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: news.eternal-september.org!eternal-september.org!raubtier-asyl.eternal-september.org!.POSTED!not-for-mail
From: Bonita Montero <Bonita.Montero@gmail.com>
Newsgroups: comp.lang.c
Subject: Re: encapsulating directory operations
Date: Mon, 9 Jun 2025 13:04:45 +0200
Organization: A noiseless patient Spider
Lines: 95
Message-ID: <1026f3t$gfc6$3@raubtier-asyl.eternal-september.org>
References: <100h650$23r5l$1@dont-email.me> <101h0an$1tkqk$1@dont-email.me>
 <101jk7i$34erh$1@raubtier-asyl.eternal-september.org>
 <1nj%P.3454$mAv4.2422@fx34.iad>
 <101nc3o$5pjd$1@raubtier-asyl.eternal-september.org>
 <h6H%P.676329$McHf.348392@fx15.iad>
 <101u8sb$25g28$1@raubtier-asyl.eternal-september.org>
 <3FC0Q.931590$G6Lf.397684@fx17.iad>
 <101v7d7$2cudl$1@raubtier-asyl.eternal-september.org>
 <CvF0Q.1165311$McHf.1120306@fx15.iad>
 <101v8ce$2d5it$1@raubtier-asyl.eternal-september.org>
 <0e9619f7d873a4ec436f017bac1192c73c5283e5.camel@gmail.com>
 <1020eu8$2pifl$1@raubtier-asyl.eternal-september.org>
 <1e3f53801e22a94356b9b0aded0ed7d33e67fd06.camel@gmail.com>
 <1021pgp$35sqk$1@raubtier-asyl.eternal-september.org>
 <1858c98adc50b2bec4021f15d0c5b94e2158f6b5.camel@gmail.com>
 <10223hq$38g0s$1@raubtier-asyl.eternal-september.org>
 <5484915e06dec7fa7a1371a9eb41801a00495079.camel@gmail.com>
 <1023gak$3nt1m$1@raubtier-asyl.eternal-september.org>
 <1026489$e1bd$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Mon, 09 Jun 2025 13:04:30 +0200 (CEST)
Injection-Info: raubtier-asyl.eternal-september.org; posting-host="acabef608228f73cc3be98d7637ae940";
	logging-data="540038"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX19LdlJyVy2/zTiXZ67ZfPl6Plr54BGwQVU="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:mGZgDxmnXAq4mFX6VAFU9hFVIqY=
In-Reply-To: <1026489$e1bd$1@dont-email.me>
Content-Language: de-DE

Am 09.06.2025 um 09:59 schrieb Lawrence D'Oliveiro:

> Not necessarily that simple. It might be easier if C++ had
> try/finally (like Python does), but it doesn’t.

The initial thought with C++ exceptions is that all the unrolling
happens with RAII-classe so that you don't need finally. But some-
times you won't write a class for each resource you hold. For this
cases a helper-class like experimental::scope_exit is very comfor-
table. Unfortunately that's still not in the standard so that I
had to write it on my own:

#pragma once
#include <utility>
#include <concepts>
#include "nui.h"

template<std::invocable Fn>
struct defer final
{
	defer( Fn &&fn ) :
		m_enabled( true ),
		m_fn( std::forward<Fn>( fn ) )
	{
	}
	defer( defer const & ) = delete;
	void operator =( defer const & ) = delete;
	~defer()
	{
		if( m_enabled ) [[likely]]
			m_fn();
	}
	void operator ()()
	{
		if( !m_enabled ) [[unlikely]]
			return;
		m_fn();
		m_enabled = false;
	}
	void disable()
	{
		m_enabled = false;
	}
private:
	bool m_enabled;
	NO_UNIQUE_ADDRESS Fn m_fn;
};

template<std::invocable ... Fns>
inline void disable( defer<Fns> &... defs )
{
	(defs.disable(), ...);
}

template<std::invocable Fn, std::invocable FnNext = Fn>
struct xdefer final
{
	xdefer( Fn &&fn, xdefer<FnNext> *next = nullptr ) :
		m_enabled( true ),
		m_next( next ),
		m_fn( std::forward<Fn>( fn ) )
	{
	}
	xdefer( xdefer const & ) = delete;
	void operator =( xdefer const & ) = delete;
	~xdefer()
	{
		bool enabled = m_enabled;
		if( m_next ) [[likely]]
			m_next->m_enabled = enabled;
		if( enabled ) [[likely]]
			m_fn();
	}
	void operator ()()
	{
		if( !m_enabled ) [[unlikely]]
			return;
		m_fn();
		m_enabled = false;
		if( !m_next ) [[unlikely]]
			return;
		m_next->m_enabled = true;
		(*m_next)();
	}
	void disable()
	{
		m_enabled = false;
	}
private:
	template<std::invocable Fn1, std::invocable Fn2>
	friend struct xdefer;
	bool m_enabled;
	xdefer<FnNext> *m_next;
	NO_UNIQUE_ADDRESS Fn m_fn;
};