cgma
|
00001 #ifndef MANAGED_PTR_VECTOR 00002 #define MANAGED_PTR_VECTOR 00003 00004 #include <vector> 00005 #include <memory> 00006 #include <cstddef> 00007 00009 00012 template <typename X> 00013 class ManagedPtrVector 00014 { 00015 public: 00016 typedef X value_type; 00017 typedef X& reference_type; 00018 typedef size_t size_type; 00019 typedef std::vector<X*> container_type; 00020 00021 class iterator 00022 { 00023 public: 00024 typedef iterator this_type; 00025 typedef X& reference; 00026 typedef size_t size_type; 00027 typedef size_t difference_type; 00028 00029 iterator() 00030 {} 00031 iterator(const this_type& rhs) 00032 :mIter(rhs.mIter) 00033 {} 00034 iterator(const typename ManagedPtrVector<X>::container_type::iterator& rhs) 00035 : mIter(rhs) 00036 {} 00037 ~iterator() 00038 {} 00039 00040 X* operator->() 00041 { return *mIter; } 00042 reference operator*() const 00043 { return **mIter; } 00044 00045 bool operator==(const this_type& rhs) const 00046 { return this->mIter == rhs.mIter; } 00047 bool operator!=(const this_type& rhs) const 00048 { return this->mIter != rhs.mIter; } 00049 00050 this_type& operator++() 00051 { 00052 ++mIter; 00053 return *this; 00054 } 00055 00056 this_type operator++(int) 00057 { 00058 this_type rv = *this; 00059 ++mIter; 00060 return rv; 00061 } 00062 00063 this_type& operator--() 00064 { 00065 --mIter; 00066 return *this; 00067 } 00068 00069 this_type operator--(int) 00070 { 00071 this_type rv = *this; 00072 --mIter; 00073 return rv; 00074 } 00075 00076 this_type operator+(difference_type n) 00077 { 00078 this_type rv = *this; 00079 rv += n; 00080 return rv; 00081 } 00082 00083 this_type& operator+=(difference_type n) 00084 { 00085 mIter += n; 00086 return *this; 00087 } 00088 00089 this_type& operator-=(difference_type n) 00090 { 00091 mIter -= n; 00092 return *this; 00093 } 00094 00095 reference operator[](difference_type i) const 00096 { 00097 return reference(*(mIter+i)); 00098 } 00099 00100 private: 00101 typename ManagedPtrVector<X>::container_type::iterator mIter; 00102 }; 00103 00104 00105 ManagedPtrVector() 00106 {} 00107 ~ManagedPtrVector() 00108 { clear(); } 00109 00110 // Add an object to the container. 00111 // The container becomes "owned" by the container. 00112 void push_back(X* obj) 00113 { mContainer.push_back(obj); } 00114 00115 iterator begin() 00116 { return iterator(mContainer.begin()); } 00117 iterator end() 00118 { return iterator(mContainer.end()); } 00119 00121 reference_type operator[](size_type i) 00122 { return *(mContainer[i]); } 00123 00125 00126 std::auto_ptr<X> release(iterator to_release) 00127 { 00128 // save a raw pointer. 00129 X* rv = to_release.operator->(); 00130 // find the iterator in the container. We don't have access 00131 // to the internal iterator, so we have to loop through to find it. 00132 // This could probably be optimized. 00133 typename container_type::iterator i = mContainer.begin(); 00134 for (; 00135 i != mContainer.end() && iterator(i) != to_release; 00136 ++i) 00137 {} 00138 // we either found the iterator, or the end. erase it. 00139 mContainer.erase(i); 00140 return std::auto_ptr<X>(rv); 00141 } 00142 00144 00148 std::auto_ptr<X> replace(iterator to_replace, std::auto_ptr<X> new_val) 00149 { 00150 // save a raw pointer. 00151 X* rv = to_replace.operator->(); 00152 // find the iterator in the container. We don't have access 00153 // to the internal iterator, so we have to loop through to find it. 00154 // This could probably be optimized. 00155 typename container_type::iterator i = mContainer.begin(); 00156 for (; 00157 i != mContainer.end(); 00158 ++i) 00159 { 00160 if (iterator(i) == to_replace) 00161 { 00162 *i = new_val; 00163 } 00164 } 00165 return std::auto_ptr<X>(NULL); 00166 } 00167 00168 // Delete all objects contained in this container. 00169 void clear() 00170 { 00171 // delete all the pointers 00172 for (typename container_type::iterator i = mContainer.begin(); 00173 i != mContainer.end(); 00174 i++) 00175 { 00176 delete *i; 00177 } 00178 mContainer.clear(); 00179 } 00180 00181 size_type size() const 00182 { return mContainer.size(); } 00183 00184 private: 00185 // Make both of these illegal 00186 ManagedPtrVector(const ManagedPtrVector<X>&); 00187 ManagedPtrVector& operator=(const ManagedPtrVector<X>&); 00188 00189 container_type mContainer; 00190 }; 00191 00192 00193 00194 #endif