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()36SingleInstanceChecker<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()52SingleInstanceChecker<T>::~SingleInstanceChecker() { 53 instanceCount_--; 54 } 55 56 } // namespace reanimated 57 58 #endif // DEBUG 59