dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
PrivateState.hpp File Reference

Macros to implement the Private State (PIMPL-like) idiom with value semantics. More...

Include dependency graph for PrivateState.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define DFX_PRIVATE_STATE(Class, logger)
 Declare a private implementation state for a class.
#define DFX_PRIVATE_STATE_DECLARE_RULE_OF_5(Class)
 Declare Rule-of-5 special member functions using the private state pattern.
#define DFX_PRIVATE_STATE_DEFINE_RULE_OF_5(ns, Class)
 Define Rule-of-5 special member functions for a private state class.

Detailed Description

Macros to implement the Private State (PIMPL-like) idiom with value semantics.

This header provides a set of macros used to implement a private state pattern, where a public-facing class owns its implementation details via an opaque internal state object.

The primary goals of these macros are:

  • Hide implementation details from headers
  • Preserve move semantics
  • Avoid dangling captures when objects are moved
  • Centralize boilerplate for Rule-of-5 declarations
Warning
Macros in this file rely on specific conventions:
  • The owning class must define an internal State type
  • The owning class must call the generated _st() accessor
  • Lifetime correctness depends on disciplined usage

Macro Definition Documentation

◆ DFX_PRIVATE_STATE

#define DFX_PRIVATE_STATE ( Class,
logger )
Value:
private: \
struct State; \
std::unique_ptr<State> _state; \
template<typename Self> \
decltype(auto) _st(this Self && self) noexcept \
{ \
if (self._state == nullptr) \
{ \
DFX_LLOG_CRITICAL(logger, #Class " used after move"); \
std::terminate(); \
} \
return *std::forward<Self>(self)._state; \
}

Declare a private implementation state for a class.

This macro declares an internal State type and a shared ownership wrapper around it. The wrapper is used to ensure that lambdas or callbacks capturing the state remain valid even if the owning object is moved.

Must be placed in the private section of a class.

Parameters
ClassName of the owning class.
loggerLogger instance or expression used by the state.
Note
The generated state is heap-allocated and shared. This is intentional to avoid dangling references when the owning object is moved.

◆ DFX_PRIVATE_STATE_DECLARE_RULE_OF_5

#define DFX_PRIVATE_STATE_DECLARE_RULE_OF_5 ( Class)
Value:
public: \
Class(Class const &) = delete; \
Class(Class &&) noexcept; \
~Class(); \
Class & operator=(Class const &) = delete; \
Class & operator=(Class &&) noexcept

Declare Rule-of-5 special member functions using the private state pattern.

This macro declares:

  • Destructor
  • Move constructor
  • Move assignment operator

Copy operations are disabled.

The destructor is not declared virtual as pimpl semantic with inheritance is messy.

Parameters
ClassName of the owning class.
Note
This macro only declares the functions. The corresponding implementation macro DFX_PRIVATE_STATE_DEFINE_RULE_OF_5 must also be used.

◆ DFX_PRIVATE_STATE_DEFINE_RULE_OF_5

#define DFX_PRIVATE_STATE_DEFINE_RULE_OF_5 ( ns,
Class )
Value:
ns::Class::Class(Class &&) noexcept = default; \
ns::Class::~Class() = default; \
ns::Class & ns::Class::operator=(Class &&) noexcept = default

Define Rule-of-5 special member functions for a private state class.

This macro provides the definitions for the functions declared by DFX_PRIVATE_STATE_DECLARE_RULE_OF_5 and must be used in a single TU.

Parameters
ClassName of the owning class.
Note
Move operations transfer ownership of the internal state. Any outstanding references to the old state remain valid.