00001 // Copyright (C) 2004, 2006 International Business Machines and others. 00002 // All Rights Reserved. 00003 // This code is published under the Common Public License. 00004 // 00005 // $Id: IpReferenced.hpp 1019 2007-06-24 03:52:34Z andreasw $ 00006 // 00007 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 00008 00009 #ifndef __IPREFERENCED_HPP__ 00010 #define __IPREFERENCED_HPP__ 00011 00012 #include "IpTypes.hpp" 00013 #include "IpDebug.hpp" 00014 00015 #include <list> 00016 00017 namespace Ipopt 00018 { 00019 00023 class Referencer 00024 {} 00025 ; 00026 00166 class ReferencedObject 00167 { 00168 public: 00169 ReferencedObject() 00170 : 00171 reference_count_(0) 00172 {} 00173 00174 virtual ~ReferencedObject() 00175 { 00176 DBG_ASSERT(reference_count_ == 0); 00177 } 00178 00179 Index ReferenceCount() const; 00180 00181 void AddRef(const Referencer* referencer) const; 00182 00183 void ReleaseRef(const Referencer* referencer) const; 00184 00185 private: 00186 mutable Index reference_count_; 00187 00188 # ifdef REF_DEBUG 00189 00190 mutable std::list<const Referencer*> referencers_; 00191 # endif 00192 00193 }; 00194 00195 /* inline methods */ 00196 inline 00197 Index ReferencedObject::ReferenceCount() const 00198 { 00199 // DBG_START_METH("ReferencedObject::ReferenceCount()", 0); 00200 // DBG_PRINT((1,"Returning reference_count_ = %d\n", reference_count_)); 00201 return reference_count_; 00202 } 00203 00204 inline 00205 void ReferencedObject::AddRef(const Referencer* referencer) const 00206 { 00207 // DBG_START_METH("ReferencedObject::AddRef(const Referencer* referencer)", 0); 00208 reference_count_++; 00209 // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); 00210 # ifdef REF_DEBUG 00211 00212 referencers_.push_back(referencer); 00213 # endif 00214 00215 } 00216 00217 inline 00218 void ReferencedObject::ReleaseRef(const Referencer* referencer) const 00219 { 00220 // DBG_START_METH("ReferencedObject::ReleaseRef(const Referencer* referencer)", 00221 // 0); 00222 reference_count_--; 00223 // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); 00224 00225 # ifdef REF_DEBUG 00226 00227 bool found = false; 00228 std::list<const Referencer*>::iterator iter; 00229 for (iter = referencers_.begin(); iter != referencers_.end(); iter++) { 00230 if ((*iter) == referencer) { 00231 found = true; 00232 break; 00233 } 00234 } 00235 00236 // cannot call release on a reference that was never added... 00237 DBG_ASSERT(found); 00238 00239 if (found) { 00240 referencers_.erase(iter); 00241 } 00242 # endif 00243 00244 } 00245 00246 00247 } // namespace Ipopt 00248 00249 #endif