COMMS
Template library intended to help with implementation of communication protocols.
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 
18 namespace comms
19 {
20 
26 class Assert
27 {
28 public:
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 
43 private:
44 };
45 
47 class AssertManager
48 {
49 public:
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 
83 private:
84  AssertManager() : assert_(nullptr) {}
85 
86  Assert* assert_;
87 };
88 
90 
98 template < typename TAssert>
100 {
101  static_assert(std::is_base_of<Assert, TAssert>::value,
102  "TAssert class must be derived class of Assert");
103 public:
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 
135 private:
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.