inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_mem 00005 #define inlib_mem 00006 00007 #ifdef INLIB_MEM 00008 // to count instances. 00009 00010 // WARNING : it uses writable static data, then it is NOT thread safe. 00011 // This class must be used for debugging only. 00012 00013 #include <ostream> 00014 #include <list> 00015 #include <string> 00016 #include <cstring> //strcmp 00017 00018 namespace inlib { 00019 00020 class mem { 00021 public: 00022 mem(){increment();} 00023 virtual ~mem(){decrement();} 00024 private: 00025 mem(const mem&){} 00026 mem& operator=(const mem&){return *this;} 00027 public: 00028 static void increment(){counter()++;} 00029 static void decrement(){counter()--;} 00030 00031 00032 static void increment(const char* a_class){ 00033 counter()++; 00034 if(check_by_class()) { 00035 mem_list::iterator it; 00036 for(it=list().begin();it!=list().end();++it) { 00037 if(!::strcmp((*it).first.c_str(),a_class)) { 00038 (*it).second++; 00039 return; 00040 } 00041 } 00042 list().push_back(std::pair<std::string,int>(std::string(a_class),1)); 00043 } 00044 } 00045 00046 static void decrement(const char* a_class){ 00047 counter()--; 00048 if(check_by_class()) { 00049 mem_list::iterator it; 00050 for(it=list().begin();it!=list().end();++it) { 00051 if(!::strcmp((*it).first.c_str(),a_class)) { 00052 (*it).second--; 00053 return; 00054 } 00055 } 00056 list().push_back(std::pair<std::string,int>(std::string(a_class),-1)); 00057 } 00058 } 00059 00060 static void set_check_by_class(bool a_value) { 00061 check_by_class() = a_value; 00062 } 00063 /* 00064 static void reset(); 00065 */ 00066 00067 static void balance(std::ostream& a_out){ 00068 if(counter()) { 00069 a_out << "inlib::mem::balance :" 00070 << " bad global object balance : " << counter() 00071 << std::endl; 00072 if(check_by_class()) { 00073 a_out << "inlib::mem::balance :" 00074 << " check by class was enabled." 00075 << std::endl; 00076 } else { 00077 a_out << "inlib::mem::balance :" 00078 << " check by class was disabled." 00079 << std::endl; 00080 } 00081 } 00082 mem_list::iterator it; 00083 for(it=list().begin();it!=list().end();++it) { 00084 if((*it).second) { 00085 a_out << "inlib::mem::balance :" 00086 << " for class " << (*it).first 00087 << ", bad object balance : " << (*it).second 00088 << std::endl; 00089 } 00090 } 00091 list().clear(); 00092 } 00093 private: 00094 static int& counter() { 00095 static int s_count = 0; 00096 return s_count; 00097 } 00098 static bool& check_by_class() { 00099 static bool s_check_by_class = false; 00100 return s_check_by_class; 00101 } 00102 00103 typedef std::list< std::pair<std::string,int> > mem_list; 00104 00105 static mem_list& list() { 00106 static mem_list s_list; 00107 return s_list; 00108 } 00109 }; 00110 00111 } 00112 00113 #endif 00114 00115 #endif 00116 00117 00118 00119