00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef IMP_VECTOR_OF_REF_COUNTED_H
00010 #define IMP_VECTOR_OF_REF_COUNTED_H
00011
00012 #include "RefCounted.h"
00013 #include "base_types.h"
00014 #include <vector>
00015
00016 IMP_BEGIN_NAMESPACE
00017
00018 class Object;
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 template <class RC, class Policy= IMP::RefCounted::Policy>
00034 class VectorOfRefCounted {
00035 typedef std::vector<RC> Data;
00036 Data data_;
00037
00038 static void ref(RC v) {
00039 Policy::ref(v);
00040 }
00041 static void unref(RC v) {
00042 Policy::unref(v);
00043 }
00044 template <class It>
00045 static void ref(It b, It e) {
00046 for (It c= b; c != e; ++c) {
00047 ref(*c);
00048 }
00049 }
00050 template <class It>
00051 static void unref(It b, It e) {
00052 for (It c= b; c != e; ++c) {
00053 unref(*c);
00054 }
00055 }
00056 public:
00057 typedef RC const_reference;
00058 typedef RC value_type;
00059 VectorOfRefCounted(const std::vector<RC> &o):data_(o) {
00060 ref(o.begin(), o.end());
00061 }
00062 template <class It>
00063 VectorOfRefCounted(It b, It e): data_(b,e){
00064 ref(b,e);
00065 }
00066 VectorOfRefCounted(const VectorOfRefCounted<RC, Policy> &o):
00067 data_(o.begin(), o.end()){
00068 ref(o.begin(), o.end());
00069 }
00070 VectorOfRefCounted(RC rc): data_(1, rc) {
00071 ref(rc);
00072 }
00073 VectorOfRefCounted(unsigned int n, RC rc): data_(n, rc) {
00074 for (unsigned int i=0; i< n; ++i) ref(rc);
00075 }
00076 VectorOfRefCounted(unsigned int i): data_(i, RC()){}
00077 VectorOfRefCounted(){}
00078 ~VectorOfRefCounted() {
00079 clear();
00080 }
00081 #ifndef SWIG
00082 const VectorOfRefCounted<RC, Policy>
00083 operator=(const VectorOfRefCounted<RC, Policy> &o) {
00084 unref(data_.begin(), data_.end());
00085 data_= o.data_;
00086 ref(data_.begin(), data_.end());
00087 return *this;
00088 }
00089
00090 operator const std::vector<RC>&() const {
00091 return data_;
00092 }
00093 #ifndef IMP_DOXYGEN
00094
00095 template <class T>
00096 struct Proxy: public T {
00097 T &v_;
00098 Proxy(T& v): T(v), v_(v){}
00099
00100 template <class O>
00101 void operator=(O ov) {
00102 T &v=ov;
00103 using std::swap;
00104 swap(v_, v);
00105 ref(v_);
00106 unref(v);
00107 }
00108 };
00109 template <class T>
00110 struct Proxy<T*> {
00111 T* &v_;
00112 Proxy(T*& v): v_(v){}
00113 operator T*() {return v_;}
00114 void operator=(T* v) {
00115 using std::swap;
00116 swap(v_, v);
00117 ref(v_);
00118 unref(v);
00119 }
00120 T* operator->() {
00121 return v_;
00122 }
00123 };
00124 typedef Proxy<RC> reference;
00125
00126 Proxy<RC> operator[](unsigned int i) {
00127 IMP_USAGE_CHECK(i < size(), "Index out of range in []: "
00128 << i << ">=" << size());
00129 return Proxy<RC>(data_[i]);
00130 }
00131 #else
00132 typedef RC& reference;
00133
00134
00135 RC& operator[](unsigned int i);
00136 #endif
00137
00138 #endif
00139 RC operator[](unsigned int i) const {
00140 IMP_USAGE_CHECK(i < size(), "Index out of range in []: "
00141 << i << ">=" << size());
00142 return data_[i];
00143 }
00144 RC get(unsigned int i) const {
00145 return operator[](i);
00146 }
00147 void set(unsigned int i, RC p) {
00148 IMP_USAGE_CHECK(i < size(), "Index out of range in set "
00149 << i << ">=" << size());
00150 using std::swap;
00151 swap(data_[i], p);
00152 ref(data_[i]);
00153 unref(p);
00154 }
00155 RC back() const {
00156 IMP_USAGE_CHECK(!empty(), "Can't call back on empty container");
00157 return data_.back();
00158 }
00159 RC front() const {
00160 IMP_USAGE_CHECK(!empty(), "Can't call front on empty container");
00161 return data_.front();
00162 }
00163 void reserve(unsigned int i){ data_.reserve(i);}
00164 unsigned int size() const {return data_.size();}
00165 void resize(unsigned int i) {data_.resize(i);}
00166
00167 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
00168 typedef typename Data::iterator iterator;
00169 typedef typename Data::const_iterator const_iterator;
00170 #else
00171 class iterator;
00172 class const_iterator;
00173 #endif
00174 #ifndef SWIG
00175 const_iterator begin() const {return data_.begin();}
00176 const_iterator end() const {return data_.end();}
00177 #endif
00178 iterator begin() {return data_.begin();}
00179 iterator end() {return data_.end();}
00180 template <class It>
00181 void insert(iterator loc, It b, It e) {
00182 data_.insert(data_.begin()+(loc-data_.begin()), b, e);
00183 ref(b,e);
00184 }
00185 void insert(iterator loc, RC p) {
00186 data_.insert(loc, p);
00187 ref(p);
00188 }
00189 void push_back(RC p) {
00190 data_.push_back(p);
00191 ref(p);
00192 }
00193 void pop_back() {
00194 unref(data_.back());
00195 data_.pop_back();
00196 }
00197 bool empty() const {return data_.empty();}
00198 #ifndef IMP_DOXYGEN
00199 void swap_with(VectorOfRefCounted<RC, Policy> &a) {
00200 std::swap(a.data_, data_);
00201 }
00202 void swap_with(std::vector<RC> &a) {
00203 std::swap(a, data_);
00204 ref(data_.begin(), data_.end());
00205 unref(a.begin(), a.end());
00206 }
00207 #endif
00208 void clear(){
00209 unref(data_.begin(), data_.end());
00210 data_.clear();
00211 }
00212 void show(std::ostream &out=std::cout) const {
00213 out << "[";
00214 for (unsigned int i=0; i< size(); ++i) {
00215 IMP::show(out, data_[i]);
00216 if (i+1 != size()) {
00217 out << ", ";
00218 }
00219 }
00220 out << "]";
00221 }
00222 void erase(iterator it) {
00223 unref(*it);
00224 data_.erase(it);
00225 }
00226 void erase(iterator b, iterator e) {
00227 unref(b, e);
00228 data_.erase(b, e);
00229 }
00230 template <class F>
00231 void remove_if(const F &f) {
00232 std::vector<RC> bye;
00233 for (iterator it= begin(); it != end(); ++it) {
00234 if (f(*it)) bye.push_back(*it);
00235 }
00236 if (!bye.empty()) {
00237 data_.resize(std::remove_if(begin(), end(), f)-begin());
00238 unref(bye.begin(), bye.end());
00239 }
00240 }
00241
00242 template <class Less>
00243 void sort(const Less &f) {
00244 std::sort(data_.begin(), data_.end(), f);
00245 }
00246 void remove(RC r) {
00247 for (unsigned int i=0; i< data_.size(); ++i) {
00248 if (data_[i]==r) {
00249 unref(r);
00250 data_.erase(data_.begin()+i);
00251 }
00252 }
00253 }
00254 };
00255
00256 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
00257 template <class RC, class Policy>
00258 std::ostream &operator<<(std::ostream &out,
00259 const VectorOfRefCounted<RC, Policy> &v) {
00260 v.show(out);
00261 return out;
00262 }
00263
00264 template <class RC, class Policy>
00265 void swap(VectorOfRefCounted<RC, Policy> &a,
00266 VectorOfRefCounted<RC, Policy> &b) {
00267 a.swap_with(b);
00268 }
00269
00270 template <class RC, class Policy>
00271 void swap(VectorOfRefCounted<RC, Policy> &a,
00272 std::vector<RC> &b) {
00273 a.swap_with(b);
00274 }
00275 template <class RC, class Policy>
00276 void swap(std::vector<RC> &b,
00277 VectorOfRefCounted<RC, Policy> &a) {
00278 a.swap_with(b);
00279 }
00280 #endif
00281
00282 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
00283 namespace internal {
00284
00285 template <class T, class F>
00286 void remove_if(T &t, const F &f) {
00287 t.remove_if(f);
00288 }
00289
00290 template <class T, class F>
00291 void remove_if(std::vector<T> &t, const F &f) {
00292 t.erase(std::remove_if(t.begin(), t.end(), f), t.end());
00293 }
00294
00295
00296
00297 }
00298 #endif
00299
00300 IMP_END_NAMESPACE
00301
00302 #endif