00001 #ifndef SIM_OBJECTPOOL_HH 00002 #define SIM_OBJECTPOOL_HH 00003 00004 #include <list> 00005 #include <boost/noncopyable.hpp> 00006 #include <boost/thread/mutex.hpp> 00007 #include <utilmm/memory/sweep.hh> 00008 00009 namespace utilmm 00010 { 00011 namespace pools 00012 { 00021 template<typename T> 00022 class object_pool : boost::noncopyable 00023 { 00024 boost::mutex m_mutex; 00025 std::list<T*> m_available; 00026 00027 typedef boost::mutex mutex; 00028 00029 public: 00030 ~object_pool() 00031 { sweep(m_available.begin(), m_available.end()); } 00032 00033 T* get() 00034 { mutex::scoped_lock lock(m_mutex); 00035 if (m_available.empty()) 00036 m_available.push_back(new T()); 00037 00038 T* ret = m_available.front(); 00039 m_available.pop_front(); 00040 return ret; 00041 } 00042 00043 void put(T* object) 00044 { mutex::scoped_lock lock(m_mutex); 00045 m_available.push_back(object); 00046 } 00047 }; 00048 00052 template<typename T> 00053 class use : boost::noncopyable 00054 { 00055 object_pool<T>& m_pool; 00056 T* m_object; 00057 00058 public: 00059 use(object_pool<T>& pool) 00060 : m_pool(pool), m_object(pool.get()) {} 00061 ~use() { m_pool.put(m_object); } 00062 00063 T* operator -> () { return m_object; } 00064 T const* operator ->() const { return m_object; } 00065 T& operator *() { return *m_object; } 00066 T const& operator *() const { return *m_object; } 00067 }; 00068 } 00069 } 00070 00071 #endif 00072