COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
Assert.h
Go to the documentation of this file.
1//
2// Copyright 2014 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
13
14#pragma once
15
16#include <cassert>
17#include <type_traits>
18#include <utility>
19
20namespace comms
21{
22
28class Assert
29{
30public:
32 virtual ~Assert() noexcept {}
33
39 virtual void fail(
40 const char* expr,
41 const char* file,
42 unsigned int line,
43 const char* function) = 0;
44
45private:
46};
47
49class AssertManager
50{
51public:
52
53 static AssertManager& instance()
54 {
55 static AssertManager mgr;
56 return mgr;
57 }
58
59 AssertManager(const AssertManager&) = delete;
60
61 AssertManager& operator=(const AssertManager&) = delete;
62
63 Assert* reset(Assert* newAssert = nullptr)
64 {
65 auto prevAssert = m_assert;
66 m_assert = newAssert;
67 return prevAssert;
68 }
69
70 Assert* getAssert()
71 {
72 return m_assert;
73 }
74
75 bool hasAssertRegistered() const
76 {
77 return (m_assert != nullptr);
78 }
79
80 static void infiniteLoop()
81 {
82 while (true) {};
83 }
84
85private:
86 AssertManager() : m_assert(nullptr) {}
87
88 Assert* m_assert;
89};
90
92
100template < typename TAssert>
102{
103 static_assert(std::is_base_of<Assert, TAssert>::value,
104 "TAssert class must be derived class of Assert");
105public:
107 using AssertType = TAssert;
108
114 template<typename... TParams>
115 EnableAssert(TParams&&... args)
116 : m_assert(std::forward<TParams>(args)...),
117 m_prevAssert(AssertManager::instance().reset(&m_assert))
118 {
119 }
120
124 ~EnableAssert() noexcept
125 {
126 AssertManager::instance().reset(m_prevAssert);
127 }
128
132 {
133 return m_assert;
134 }
135
136private:
137 AssertType m_assert;
138 Assert* m_prevAssert;
139};
140
141#ifndef COMMS_ASSERT
142#ifndef NDEBUG
143
144// NOSTDLIB definition is treated as COMMS_NOSTDLIB for backward compatiblity
145#if defined(NOSTDLIB) && !defined(COMMS_NOSTDLIB)
146#define COMMS_NOSTDLIB
147#endif
148
150#ifndef __ASSERT_FUNCTION
151#define COMMS_ASSERT_FUNCTION_STR __FUNCTION__
152#else // #ifndef __ASSERT_FUNCTION
153#define COMMS_ASSERT_FUNCTION_STR __ASSERT_FUNCTION
154#endif // #ifndef __ASSERT_FUNCTION
155
156#ifndef COMMS_NOSTDLIB
157#define COMMS_ASSERT_FAIL_FUNC(expr) assert(expr)
158#else // #ifndef COMMS_NOSTDLIB
159#define COMMS_ASSERT_FAIL_FUNC(expr) comms::AssertManager::instance().infiniteLoop()
160#endif // #ifndef COMMS_NOSTDLIB
161
163
170#define COMMS_ASSERT(expr) \
171 ((expr) \
172 ? static_cast<void>(0) \
173 : (comms::AssertManager::instance().hasAssertRegistered() \
174 ? comms::AssertManager::instance().getAssert()->fail( \
175 #expr, __FILE__, __LINE__, COMMS_ASSERT_FUNCTION_STR) \
176 : COMMS_ASSERT_FAIL_FUNC(expr)))
177
178#else // #ifndef NDEBUG
179
180#define COMMS_ASSERT(expr) static_cast<void>(0)
181
182#endif // #ifndef NDEBUG
183#endif // #ifndef COMMS_ASSERT
184
185#ifndef GASSERT
188#define GASSERT(expr) COMMS_ASSERT(expr)
189#endif // #ifndef GASSERT
190
191} // namespace comms
Base class for any custom assertion behaviour.
Definition Assert.h:29
virtual void fail(const char *expr, const char *file, unsigned int line, const char *function)=0
Pure virtual function to be called when assertion fails.
virtual ~Assert() noexcept
Destructor.
Definition Assert.h:32
Enable new assertion behaviour.
Definition Assert.h:102
AssertType & getAssert()
Provides reference to internal Assert object.
Definition Assert.h:131
EnableAssert(TParams &&... args)
Constructor.
Definition Assert.h:115
TAssert AssertType
Type of assert object.
Definition Assert.h:107
~EnableAssert() noexcept
Destructor.
Definition Assert.h:124
Main namespace for all classes / functions of COMMS library.
STL namespace.