1 #pragma once
2 
3 #ifdef DEBUG
4 
5 #include <cxxabi.h>
6 
7 #include <iostream>
8 #include <string>
9 
10 namespace reanimated {
11 
12 // This is a class that counts how many instances of a different class there
13 // are. It is meant only to be used with classes that should only have one
14 // instance.
15 
16 template <class T>
17 class SingleInstanceChecker {
18  public:
19   SingleInstanceChecker();
20   ~SingleInstanceChecker();
21 
22  private:
assertWithMessage(bool condition,std::string message)23   void assertWithMessage(bool condition, std::string message) {
24     if (!condition) {
25       std::cerr << message << std::endl;
26       assert(condition);
27     }
28   }
29 
30   // A static field will exist separately for every class template.
31   // This has to be inline for automatic initialization.
32   inline static int instanceCount_;
33 };
34 
35 template <class T>
SingleInstanceChecker()36 SingleInstanceChecker<T>::SingleInstanceChecker() {
37   int status = 0;
38   std::string className =
39       __cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
40 
41   // Only one instance should exist, but it is possible for two instances
42   // to co-exist during a reload.
43   assertWithMessage(
44       instanceCount_ <= 1,
45       "More than one instance of " + className +
46           " present. This may indicate a memory leak due to a retain cycle.");
47 
48   instanceCount_++;
49 }
50 
51 template <class T>
~SingleInstanceChecker()52 SingleInstanceChecker<T>::~SingleInstanceChecker() {
53   instanceCount_--;
54 }
55 
56 } // namespace reanimated
57 
58 #endif // DEBUG
59