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