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 - 2024 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
11
12#pragma once
13
14#include <cassert>
15#include <type_traits>
16#include <utility>
17
18namespace comms
19{
20
26class Assert
27{
28public:
30 virtual ~Assert() noexcept {}
31
37 virtual void fail(
38 const char* expr,
39 const char* file,
40 unsigned int line,
41 const char* function) = 0;
42
43private:
44};
45
47class AssertManager
48{
49public:
50
51 static AssertManager& instance()
52 {
53 static AssertManager mgr;
54 return mgr;
55 }
56
57 AssertManager(const AssertManager&) = delete;
58
59 AssertManager& operator=(const AssertManager&) = delete;
60
61 Assert* reset(Assert* newAssert = nullptr)
62 {
63 auto prevAssert = assert_;
64 assert_ = newAssert;
65 return prevAssert;
66 }
67
68 Assert* getAssert()
69 {
70 return assert_;
71 }
72
73 bool hasAssertRegistered() const
74 {
75 return (assert_ != nullptr);
76 }
77
78 static void infiniteLoop()
79 {
80 while (true) {};
81 }
82
83private:
84 AssertManager() : assert_(nullptr) {}
85
86 Assert* assert_;
87};
88
90
98template < typename TAssert>
100{
101 static_assert(std::is_base_of<Assert, TAssert>::value,
102 "TAssert class must be derived class of Assert");
103public:
105 using AssertType = TAssert;
106
112 template<typename... TParams>
113 EnableAssert(TParams&&... args)
114 : assert_(std::forward<TParams>(args)...),
115 prevAssert_(AssertManager::instance().reset(&assert_))
116 {
117 }
118
122 ~EnableAssert() noexcept
123 {
124 AssertManager::instance().reset(prevAssert_);
125 }
126
127
131 {
132 return assert_;
133 }
134
135private:
136 AssertType assert_;
137 Assert* prevAssert_;
138};
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:27
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:30
Enable new assertion behaviour.
Definition Assert.h:100
AssertType & getAssert()
Provides reference to internal Assert object.
Definition Assert.h:130
EnableAssert(TParams &&... args)
Constructor.
Definition Assert.h:113
TAssert AssertType
Type of assert object.
Definition Assert.h:105
~EnableAssert() noexcept
Destructor.
Definition Assert.h:122
Main namespace for all classes / functions of COMMS library.
STL namespace.