Lodestar
An integrated real-time control package in C++
RecursionException.hpp
1 //
2 // Created by Hamza El-Kebir on 5/27/21.
3 //
4 
5 #ifndef LODESTAR_RECURSIONEXCEPTION_HPP
6 #define LODESTAR_RECURSIONEXCEPTION_HPP
7 
8 #include <exception>
9 
10 /*
11  * ptrToEffectiveEnd is computed to limit the subsequent find calls to the range of the array in which addresses have
12  * been previously initialized.
13  */
14 #define INIT_RECURSION_GUARD(CALLSTACK, CURRENT_ADDRESS) \
15 {try { \
16  {auto ptrToEffectiveEnd = std::find(std::get<0>(CALLSTACK).begin(), std::get<0>(CALLSTACK).end(), decltype(CURRENT_ADDRESS){}); \
17  auto idx = std::find(std::get<0>(CALLSTACK).begin(), ptrToEffectiveEnd, CURRENT_ADDRESS); \
18  if (idx != ptrToEffectiveEnd) { \
19  throw RecursionException<std::size_t>(std::get<1>(CALLSTACK)); \
20  } \
21  std::get<0>(CALLSTACK)[std::get<2>(CALLSTACK)] = CURRENT_ADDRESS; \
22  std::get<1>(CALLSTACK) = CURRENT_ADDRESS; \
23  std::get<2>(CALLSTACK)++;}
24 
25 #define OPEN_RECURSION_GUARD(CALLSTACK, CURRENT_ADDRESS) \
26 {try { \
27 std::get<1>(CALLSTACK) = CURRENT_ADDRESS;
28 
29 #define CLOSE_RECURSION_GUARD(CALLSTACK, CURRENT_ADDRESS) \
30 } catch (const RecursionException<std::size_t> &rexception) { \
31  if (rexception.getInstance() == CURRENT_ADDRESS) std::get<1>(CALLSTACK) = CURRENT_ADDRESS; \
32  else throw rexception; \
33 }}
34 
35 #define OPEN_CATCH_RECURSION_GUARD(CALLSTACK, CURRENT_ADDRESS) } \
36 catch (const RecursionException<std::size_t> &rexception) { \
37  if (rexception.getInstance() != CURRENT_ADDRESS) { throw rexception; }
38 
39 #define CLOSE_CATCH_RECURSION_GUARD(CALLSTACK, CURRENT_ADDRESS) \
40  std::get<1>(CALLSTACK) = CURRENT_ADDRESS; \
41 }}
42 
43 template <typename TType>
44 class RecursionException : public std::exception {
45 public:
46  RecursionException(TType instance) : instance_(instance) {}
47 
48  virtual ~RecursionException() noexcept {}
49 
50  virtual const char* what() const noexcept {
51  std::cout << instance_ << std::endl;
52  return std::to_string(instance_).c_str();
53  }
54 
55  virtual const TType getInstance() const noexcept {
56  return instance_;
57  }
58 protected:
59  TType instance_;
60 };
61 
62 #endif //LODESTAR_RECURSIONEXCEPTION_HPP
RecursionException
Definition: RecursionException.hpp:44