libidx
|
00001 /*************************************************************************** 00002 * Copyright (C) 2011 by Pierre Sermanet * 00003 * pierre.sermanet@gmail.com * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Redistribution under a license not approved by the Open Source 00014 * Initiative (http://www.opensource.org) must display the 00015 * following acknowledgement in all advertising material: 00016 * This product includes software developed at the Courant 00017 * Institute of Mathematical Sciences (http://cims.nyu.edu). 00018 * * The names of the authors may not be used to endorse or promote products 00019 * derived from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 00022 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00023 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00024 * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY 00025 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00026 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00028 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 ***************************************************************************/ 00032 00033 #ifndef SMART_HPP_ 00034 #define SMART_HPP__ 00035 00036 namespace ebl { 00037 00038 // smart vector ////////////////////////////////////////////////////////////// 00039 00040 template <class T> 00041 svector<T>::svector() { 00042 } 00043 00044 template <class T> 00045 svector<T>::svector(const svector<T> &other) { 00046 this->copy(other); 00047 //EDEBUG("copied " << other << " into this: " << *this); 00048 } 00049 00050 template <class T> 00051 svector<T>::svector(uint n) : std::vector<T*>(n, NULL) { 00052 } 00053 00054 template <class T> 00055 svector<T>::~svector() { 00056 clear(); 00057 } 00058 00059 template <class T> 00060 void svector<T>::clear() { 00061 unlock_all(); 00062 std::vector<T*>::clear(); 00063 } 00064 00065 template <class T> 00066 void svector<T>::clear(uint i) { 00067 T *e = std::vector<T*>::operator[](i); 00068 if (e) { 00069 //EDEBUG("clearing element " << i << " " << *e); 00070 e->unlock(); 00071 std::vector<T*>::operator[](i) = NULL; 00072 } 00073 } 00074 00075 template <class T> 00076 T& svector<T>::operator[](uint i) { 00077 #ifdef __DEBUG__ 00078 if (i >= this->size()) 00079 eblerror("trying to access element " << i << " in vector of size " 00080 << this->size()); 00081 #endif 00082 return *(std::vector<T*>::operator[](i)); 00083 } 00084 00085 // template <class T> 00086 // const T& svector<T>::operator[](uint i) const { 00087 // return *(std::vector<T*>::operator[](i)); 00088 // } 00089 00090 template <class T> 00091 const T& svector<T>::at_const(uint i) const { 00092 return *(std::vector<T*>::operator[](i)); 00093 } 00094 00095 template <class T> 00096 bool svector<T>::exists(uint i) const { 00097 if (i >= std::vector<T*>::size()) return false; 00098 return std::vector<T*>::operator[](i) != NULL; 00099 } 00100 00101 template <class T> 00102 uint svector<T>::size_existing() const { 00103 uint n = 0; 00104 typename std::vector<T*>::const_iterator cit = std::vector<T*>::begin(); 00105 for (; cit != std::vector<T*>::end(); ++cit) 00106 if (*cit != NULL) n++; 00107 return n; 00108 } 00109 00110 template <class T> 00111 void svector<T>::remove(uint i) { 00112 if (i >= this->size()) 00113 eblerror("cannot remove element " << i << " when vector has only " 00114 << this->size() << " elements"); 00115 it = this->begin() + i; 00116 if (*it != NULL) (*it)->unlock(); 00117 this->erase(it); 00118 } 00119 00120 template <class T> 00121 void svector<T>::remove(uint start, uint end) { 00122 if (end >= this->size()) 00123 eblerror("cannot remove elements from " << start << " to " << end 00124 << " when vector has only " << this->size() << " elements"); 00125 unlock_range(start, end); 00126 it = this->begin() + start; 00127 typename std::vector<T*>::iterator itend = this->begin() + end; 00128 itend++; // include last element 00129 this->erase(it, itend); 00130 } 00131 00132 template <class T> 00133 void svector<T>::remove_empty() { 00134 for (uint i = 0; i < this->size(); ) { 00135 if (!exists(i)) this->remove(i); 00136 else i++; 00137 } 00138 } 00139 00140 template <class T> 00141 void svector<T>::push_front(T &e) { 00142 e.lock(); 00143 std::vector<T*>::insert(std::vector<T*>::begin(), 1, &e); 00144 } 00145 00146 template <class T> 00147 void svector<T>::push_front_new(T &e) { 00148 T *n = new T(e); 00149 n->lock(); 00150 std::vector<T*>::insert(std::vector<T*>::begin(), 1, n); 00151 } 00152 00153 template <class T> 00154 void svector<T>::push_back(T *e) { 00155 if (e) e->lock(); 00156 std::vector<T*>::push_back(e); 00157 } 00158 00159 template <class T> 00160 void svector<T>::push_back(T &e) { 00161 e.lock(); 00162 std::vector<T*>::push_back(&e); 00163 } 00164 00165 template <class T> 00166 void svector<T>::push_back_new(const T &e) { 00167 T *n = new T(e); 00168 //EDEBUG("pushing back " << e << " into new element " << *n); 00169 n->lock(); 00170 std::vector<T*>::push_back(n); 00171 } 00172 00173 template <class T> 00174 void svector<T>::push_back_new(const T *e) { 00175 T *n = new T(*e); 00176 //EDEBUG("pushing back " << e << " into new element " << *n); 00177 n->lock(); 00178 std::vector<T*>::push_back(n); 00179 } 00180 00181 template <class T> 00182 void svector<T>::push_back(std::vector<T*> &v) { 00183 for (it = v.begin(); it != v.end(); ++it) { 00184 (*it)->lock(); 00185 std::vector<T*>::push_back(*it); 00186 } 00187 } 00188 00189 template <class T> 00190 void svector<T>::push_back(svector<T> &v) { 00191 for (it = v.begin(); it != v.end(); ++it) { 00192 if (*it != NULL) { 00193 (*it)->lock(); 00194 std::vector<T*>::push_back(*it); 00195 } else push_back_empty(); 00196 } 00197 } 00198 00199 template <class T> 00200 void svector<T>::push_back_new(const svector<T> &v) { 00201 typename std::vector<T*>::const_iterator cit = v.begin(); 00202 for ( ; cit != v.end(); ++cit) { 00203 if (*cit != NULL) push_back_new(*cit); 00204 else push_back_empty(); 00205 } 00206 } 00207 00208 template <class T> 00209 void svector<T>::set(T &o, uint i) { 00210 T* &e = this->at(i); 00211 if (e) e->unlock(); 00212 o.lock(); 00213 e = &o; 00214 } 00215 00216 template <class T> 00217 void svector<T>::set_new(T &o, uint i) { 00218 T* &e = this->at(i); 00219 if (e) e->unlock(); 00220 T *n = new T(o); 00221 n->lock(); 00222 e = n; 00223 } 00224 00225 // template <class T> 00226 // svector<T>& svector<T>::operator=(svector<T> &other) { 00227 // if ((void*) &other != (void*) this) { 00228 // this->clear(); 00229 // this->push_back(other); 00230 // } 00231 // return *this; 00232 // } 00233 00234 template <class T> 00235 void svector<T>::operator=(svector<T> other) { 00236 if ((void*) &other != (void*) this) { 00237 this->clear(); 00238 this->push_back(other); 00239 } 00240 // return *this; 00241 } 00242 00243 template <class T> 00244 void svector<T>::push_back_empty() { 00245 std::vector<T*>::push_back(NULL); 00246 } 00247 00248 template <class T> 00249 void svector<T>::swap(uint i, uint j) { 00250 T *tmp = std::vector<T*>::at(j); 00251 std::vector<T*>::at(j) = std::vector<T*>::at(i); 00252 std::vector<T*>::at(i) = tmp; 00253 } 00254 00255 template <class T> 00256 svector<T> svector<T>::copy() { 00257 svector<T> c; 00258 for (it = std::vector<T*>::begin(); it != std::vector<T*>::end(); ++it) 00259 c.push_back(*it); 00260 return c; 00261 } 00262 00263 template <class T> 00264 void svector<T>::copy(const svector<T> &other) { 00265 this->clear(); 00266 for (typename svector<T>::const_iterator i = other.begin(); 00267 i != other.end(); ++i) 00268 if (i.exists()) this->push_back_new(*i); 00269 else this->push_back_empty(); 00270 } 00271 00272 template <class T> 00273 void svector<T>::copy(svector<T> &other) { 00274 this->clear(); 00275 for (typename svector<T>::iterator i = other.begin(); 00276 i != other.end(); ++i) 00277 if (i.exists()) this->push_back(i.ptr()); 00278 else this->push_back_empty(); 00279 } 00280 00281 template <class T> 00282 svector<T> svector<T>::narrow(uint n, uint offset) { 00283 if (offset + n > this->size()) 00284 eblerror("out-of-bounds narrow of size " << n << " starting at offset " 00285 << offset << " in " << *this); 00286 svector<T> m; 00287 for (typename svector<T>::iterator i = this->begin() + offset; 00288 i != this->begin() + offset + n; ++i) 00289 if (i.exists()) m.push_back(*i); 00290 else m.push_back_empty(); 00291 return m; 00292 } 00293 00294 template <class T> 00295 void svector<T>::resize_default(uint n) { 00296 for (uint i = this->size(); i < n; ++i) 00297 this->push_back(new T); 00298 } 00299 00300 template <class T> 00301 void svector<T>::randomize() { 00302 typename std::vector<T*>::iterator b = ((std::vector<T*>*)this)->begin(); 00303 typename std::vector<T*>::iterator e = ((std::vector<T*>*)this)->end(); 00304 std::random_shuffle(b, e); 00305 } 00306 00307 template <class T> 00308 typename svector<T>::iterator svector<T>::begin(uint off) { 00309 return iterator(std::vector<T*>::begin() + off); 00310 } 00311 00312 template <class T> 00313 typename svector<T>::const_iterator svector<T>::begin(uint off) const { 00314 return const_iterator(std::vector<T*>::begin() + off); 00315 } 00316 00317 // internal methods ////////////////////////////////////////////////////////// 00318 00319 template <class T> 00320 void svector<T>::lock_all() { 00321 for (it = this->begin(); it != this->end(); ++it) 00322 if (*it != NULL) (*it)->lock(); 00323 } 00324 00325 template <class T> 00326 void svector<T>::unlock_all() { 00327 for (it = this->begin(); it != this->end(); ++it) 00328 if (*it != NULL) (*it)->unlock(); 00329 } 00330 00331 template <class T> 00332 void svector<T>::unlock_range(uint start, uint end) { 00333 for (it = this->begin() + start; it != this->begin() + end; ++it) 00334 if (*it != NULL) (*it)->unlock(); 00335 } 00336 00337 // svector iterator ////////////////////////////////////////////////////////// 00338 00339 template <class T> 00340 svector<T>::iterator::iterator() { 00341 } 00342 00343 template <class T> 00344 svector<T>::iterator::iterator(typename std::vector<T*>::iterator &it) 00345 : std::vector<T*>::iterator(it) { 00346 } 00347 00348 template <class T> 00349 svector<T>::iterator::iterator(typename std::vector<T*>::iterator it) 00350 : std::vector<T*>::iterator(it) { 00351 } 00352 00353 template <class T> 00354 svector<T>::iterator::~iterator() { 00355 } 00356 00357 template <class T> 00358 T& svector<T>::iterator::operator*() { 00359 #if __WINDOWS__ == 1 00360 return **(this->_Ptr); 00361 #else 00362 return **(this->_M_current); 00363 #endif 00364 } 00365 00366 template <class T> 00367 T* svector<T>::iterator::operator->() { 00368 #if __WINDOWS__ == 1 00369 return *(this->_Ptr); 00370 #else 00371 return *(this->_M_current); 00372 #endif 00373 } 00374 00375 template <class T> 00376 T* svector<T>::iterator::ptr() { 00377 #if __WINDOWS__ == 1 00378 return *(this->_Ptr); 00379 #else 00380 return *(this->_M_current); 00381 #endif 00382 } 00383 00384 template <class T> 00385 bool svector<T>::iterator::exists() const { 00386 #if __WINDOWS__ == 1 00387 return *(this->_Ptr) != NULL; 00388 #else 00389 return *(this->_M_current) != NULL; 00390 #endif 00391 } 00392 00393 // svector const_iterator //////////////////////////////////////////////////// 00394 00395 template <class T> 00396 svector<T>::const_iterator::const_iterator() { 00397 } 00398 00399 template <class T> 00400 svector<T>::const_iterator:: 00401 const_iterator(typename std::vector<T*>::const_iterator &it) 00402 : std::vector<T*>::const_iterator(it) { 00403 } 00404 00405 template <class T> 00406 svector<T>::const_iterator:: 00407 const_iterator(typename std::vector<T*>::const_iterator it) 00408 : std::vector<T*>::const_iterator(it) { 00409 } 00410 00411 template <class T> 00412 svector<T>::const_iterator::~const_iterator() { 00413 } 00414 00415 template <class T> 00416 const T& svector<T>::const_iterator::operator*() const { 00417 #if __WINDOWS__ == 1 00418 return **(this->_Ptr); 00419 #else 00420 return **(this->_M_current); 00421 #endif 00422 } 00423 00424 template <class T> 00425 const T* svector<T>::const_iterator::operator->() const { 00426 #if __WINDOWS__ == 1 00427 return *(this->_Ptr); 00428 #else 00429 return *(this->_M_current); 00430 #endif 00431 } 00432 00433 template <class T> 00434 const T* svector<T>::const_iterator::ptr() const { 00435 #if __WINDOWS__ == 1 00436 return *(this->_Ptr); 00437 #else 00438 return *(this->_M_current); 00439 #endif 00440 } 00441 00442 template <class T> 00443 bool svector<T>::const_iterator::exists() const { 00444 #if __WINDOWS__ == 1 00445 return *(this->_Ptr) != NULL; 00446 #else 00447 return *(this->_M_current) != NULL; 00448 #endif 00449 } 00450 00451 // printing ////////////////////////////////////////////////////////////////// 00452 00453 template <class T, class stream> 00454 stream& operator<<(stream &o, const svector<T> &v) { 00455 o << "[ "; 00456 for (typename svector<T>::const_iterator i = v.begin(); 00457 i != v.end(); ++i) { 00458 if (i.exists()) 00459 o << (const T&)*i << " "; 00460 else 00461 o << " null "; 00462 } 00463 o << "]"; 00464 return o; 00465 } 00466 00467 template <class T, class stream> 00468 stream& operator<<(stream &o, svector<T> &v) { 00469 o << "[ "; 00470 for (typename svector<T>::iterator i = v.begin(); 00471 i != v.end(); ++i) { 00472 if (i.exists()) 00473 o << (T&)*i << " "; 00474 else 00475 o << " null "; 00476 } 00477 o << "]"; 00478 return o; 00479 } 00480 00481 } // namespace ebl 00482 00483 #endif /* SMART_HPP_ */