Add ONCE_EACH macro per-value one-time execution

This commit is contained in:
Atrik 2026-07-30 23:34:32 +02:00
parent 9ab89b01c2
commit 7ed3e6b059

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2013 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -23,6 +23,9 @@
#ifndef INCLUDED_CODE_GENERATION
#define INCLUDED_CODE_GENERATION
#include <unordered_set>
#include <type_traits>
/**
* package code into a single statement.
*
@ -56,6 +59,30 @@ STMT(\
}\
)
/**
* execute the code passed as a parameter only the first time each distinct
* value of the key expression is seen.
*
* @param key_expr expression that produces the key to track (e.g., a filename).
* @param code_block code to execute the first time each key value is seen.
* the key expression result is available as 'key' inside the block.
*
* example:
* ONCE_EACH(filename, LOGWARNING("Bad file %s", key))
*
* may be called at any time (in particular before main), but is not
* thread-safe.
**/
#define ONCE_EACH(key_expr, code_block) \
STMT( \
using KeyType__ = std::decay_t<decltype(key_expr)>; \
static std::unordered_set<KeyType__> seen__; \
auto key = (key_expr); \
if (seen__.insert(key).second) { \
code_block; \
} \
)
/**
* execute the code passed as a parameter except the first time this is
* reached.