libcwdversion 2.0.0
The C++ Debugging Support Library
Loading...
Searching...
No Matches
LibcwdForAllDebugObjects.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2000-2006, 2018, 2020, 2023, 2026 Carlo Wood
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
9
10#ifndef LIBCWD_MACRO_FORALLDEBUGOBJECTS_H
11#define LIBCWD_MACRO_FORALLDEBUGOBJECTS_H
12
13#include "LIBCWD_ASSERT.h"
14#include "libcwd/config.h"
15
16#include <type_traits>
17
18//===================================================================================================
19// Macro ForAllDebugObjects
20//
21
22namespace libcwd {
23
24class DebugObject;
25
26#ifndef HIDE_FROM_DOXYGEN
27namespace _private_ {
28
29struct DebugObjects
30{
31 using callback_type = void (*)(DebugObject&, void*);
32
33 struct Impl;
34 Impl* impl; // Deliberately leaked.
35
36 static DebugObjects const& instance();
37
38 // Register debug_object in the debug-object registry unless it is already present.
39 //
40 // The registry is write-locked for the whole lookup-and-insert operation, so callers do not need to
41 // acquire a separate lock or retry when another thread registers a debug object concurrently.
42 void add_if_missing(DebugObject* debug_object) const;
43
44 // Invoke func for each debug object currently registered in the registry.
45 //
46 // A read lock is held until all callbacks have returned. The callback receives debugObject as a
47 // DebugObject reference; it must not try to register another debug object because that would require
48 // upgrading the registry lock while this read access is still alive.
49 template <typename Func>
50 void for_each(Func&& func) const
51 {
52 using func_type = std::remove_reference_t<Func>;
53 for_each_impl([](DebugObject& debugObject, void* data) { (*static_cast<func_type*>(data))(debugObject); }, &func);
54 }
55
56 void for_each_impl(callback_type callback, void* data) const;
57};
58
59static_assert(std::is_trivial_v<DebugObjects>, "DebugObjects must be trivial to survive static destruction");
60
61} // namespace _private_
62#endif // HIDE_FROM_DOXYGEN
63
64} // namespace libcwd
65
66#define LibcwdForAllDebugObjects(dc_namespace, /*STATEMENT*/...) \
67 do \
68 { \
69 ::libcwd::_private_::DebugObjects::instance().for_each([&](::libcwd::DebugObject& debugObject) { \
70 using namespace ::libcwd; \
71 using namespace ::dc_namespace; \
72 { \
73 __VA_ARGS__; \
74 } \
75 }); \
76 } while (0)
77
78#endif // LIBCWD_MACRO_FORALLDEBUGOBJECTS_H
The Debug Object class, this object represents one output device (ostream).
Definition DebugObject.h:110
namespace for libcwd.