latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*---------------------------------------------------------------- 00025 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiGenericVector.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 09.04.99 00030 * revisions ..: $Id: ltiGenericVector.h,v 1.16 2008/08/17 22:20:13 alvarado Exp $ 00031 */ 00032 00033 #ifndef _LTI_GENERIC_VECTOR_H_ 00034 #define _LTI_GENERIC_VECTOR_H_ 00035 00036 #include "ltiMathObject.h" 00037 #include "ltiException.h" 00038 #include "ltiTypes.h" 00039 #include "ltiMath.h" 00040 #include <cstring> // for memcpy 00041 #include <vector> 00042 00043 namespace lti { 00044 /** 00045 * Vector container class. 00046 * 00047 * The lti::genericVector class allows the representation of 00048 * n-dimensional vectors. The elements of the vector will be 00049 * indexed between 0 an n-1. 00050 * 00051 * Note that this class is NOT intended to be a subtitute for 00052 * std::vector. If you need a vector of elements which use some 00053 * sort of dynamic memory allocation then you should use the 00054 * std::vector class of the Standard Template Library. This means, 00055 * you should not try to make lti::genericVector of other vectors or 00056 * matrices, which administrate some memory. If you do so, the 00057 * behaviour of copy or fill operations will be unpredictable. 00058 * 00059 * The difference between lti::genericVector and its most used 00060 * inherited class lti::vector is the support for arithmetical 00061 * operations. The generic vector is more a container than a 00062 * multi-dimensional point representation. It inherits its memory 00063 * managment versatility to lti::vector. Again, it is usually 00064 * employed as a container of any \e static type, which do not do by 00065 * itself any memory managment. 00066 * 00067 * The genericVector class is a generic container class implemented 00068 * as template. 00069 * 00070 * If you need to create a vector of floats with 256 elements all 00071 * initialized with a value of 4.27 just create it: 00072 * 00073 * \code 00074 * lti::genericVector<float> myVct(256,4.27f) // creates vector with 256 00075 * // elements all initialized 00076 * // with 4.27f 00077 * \endcode 00078 * 00079 * To access the vector elements use the access operators at() (or the 00080 * overloaded operator[]()). For example: 00081 * 00082 * \code 00083 * float accu = 0; // initialize accumulator 00084 * 00085 * for (int i = 0; i < myVct.size(); i++) { 00086 * tmp += myVct.at(i); // access each element of the vector 00087 * } 00088 * \endcode 00089 * 00090 * @ingroup gAggregate 00091 */ 00092 template<class T> 00093 class genericVector : public mathObject { 00094 public: 00095 /** 00096 * Type of the genericVector elements. 00097 */ 00098 typedef T value_type; 00099 00100 /** 00101 * constReferenceException class 00102 * 00103 * constReferenceException is thrown if a constant object is modified. 00104 * @see lti::genericVector::useExternData() 00105 */ 00106 class constReferenceException : public exception { 00107 public: 00108 constReferenceException() 00109 : exception("const reference can not be changed") {}; 00110 virtual const char* getTypeName() const { 00111 return "genericVector::constReferenceException"; 00112 }; 00113 }; 00114 00115 # ifdef NDEBUG 00116 /** 00117 * iterator type (allows read and write operations) The use of the 00118 * iterator classes is similar to the iterators of the STL 00119 * (Standard Template Library). See lti::genericVector::begin() and 00120 * lti::genericVector::inverseBegin() for examples. 00121 * 00122 * For the debugging version of the iterators, boundary check will be 00123 * done! This explains the low speed of the iterators of the debug 00124 * version. In the release version, no boundary check will be done, 00125 * and the iterators are sometimes a factor 10 faster than the 00126 * debug iterators. 00127 * 00128 * The use of the access operator at(.) is faster than the iterators 00129 * in the debug version only. If you need to iterate on a genericVector use 00130 * iterators instead (in the release version iterators are approx. a 00131 * factor 3 faster than "at(.)"). 00132 * 00133 * CAUTION: Try to use the prefix incremental operator 00134 * (i.e. ++it) instead of the postfix operator (i.e. it++) to 00135 * allow efficient code also in debug-modus! 00136 * 00137 * see also const_iterator 00138 */ 00139 typedef T* iterator; 00140 00141 /** 00142 * const iterator type (allows read-only operations) 00143 * The use of the iterator classes is similar to the iterators of 00144 * the STL (Standard Template Library). See lti::genericVector::begin() 00145 * for an example. 00146 * 00147 * For the debugging version of the iterators, boundary check will be 00148 * done! This explains the low speed of the iterators of the debug 00149 * version. In the release version, no boundary check will be done, 00150 * and the iterators are sometimes a factor 10 faster than the 00151 * debug iterators. 00152 * 00153 * The use of the access operator at(.) is faster than the iterators 00154 * in the debug version only. If you need to iterate on a genericVector use 00155 * iterators instead (in the release version iterators are approx. a 00156 * factor 3 faster than "at(.)"). 00157 * 00158 * CAUTION: Try to use the prefix incremental operator (i.e. ++it) 00159 * instead of the postfix operator (i.e. it++) to allow efficient 00160 * code also in debug-modus! 00161 * 00162 * see also iterator 00163 */ 00164 typedef const T* const_iterator; 00165 00166 00167 # else 00168 00169 class const_iterator; 00170 /** 00171 * iterator type (allows read and write operations). 00172 * 00173 * The use of the iterator classes is similar to the iterators of 00174 * the STL (Standard Template Library). See lti::genericVector::begin() 00175 * for an example 00176 * 00177 * For the debugging version of the iterators, boundary check will be 00178 * done! This explains the low speed of the iterators of the debug 00179 * version. In the release version, no boundary check will be done, 00180 * and the iterators are sometimes a factor 10 faster than the 00181 * debug iterators. 00182 * 00183 * The use of the access operator at(.) is faster than the iterators 00184 * in the debug version only. If you need to iterate on a genericVector use 00185 * iterators instead (in the release version iterators are approx. a 00186 * factor 3 faster than "at(.)"). 00187 * 00188 * CAUTION: Try to use the prefix incremental operator (i.e. ++it) 00189 * instead of the postfix operator (i.e. it++) to allow efficient 00190 * code also in debug-modus! 00191 * 00192 * see also const_iterator 00193 */ 00194 class iterator { 00195 friend class genericVector<T>; 00196 # ifdef _LTI_MSC_6 00197 friend class const_iterator; 00198 # else 00199 friend class genericVector<T>::const_iterator; 00200 # endif 00201 public: 00202 /** 00203 * Default constructor 00204 */ 00205 iterator() 00206 : pos(0), theGenericVector(0) {}; 00207 00208 /** 00209 * copy constructor 00210 */ 00211 iterator(const iterator& other) 00212 : pos(other.pos),theGenericVector(other.theGenericVector) {}; 00213 00214 /** 00215 * advance to next item 00216 */ 00217 inline iterator& operator++() {++pos; return *this;}; // prefix 00218 00219 /** 00220 * advance to next item 00221 */ 00222 inline iterator operator++(int) { 00223 iterator tmp(*this); 00224 pos++; return tmp; 00225 }; // postfix 00226 00227 /** 00228 * recede to previous item 00229 */ 00230 inline iterator& operator--() {--pos; return *this;}; // prefix 00231 00232 /** 00233 * recede to previous item 00234 */ 00235 inline iterator operator--(int) { 00236 iterator tmp(*this); 00237 pos--; return tmp; 00238 }; // postfix 00239 00240 /** 00241 * advance (skip) some elements. 00242 * Use this operator with care! Note that you can skip the end of 00243 * the genericVector, and read (or even worse: write!) out of bounds! 00244 */ 00245 inline iterator& operator+=(const int n) {pos+=n; return *this;}; 00246 00247 /** 00248 * recede (skip) some elements. 00249 * Use this operator with care! Note that you can skip the beginning of 00250 * the genericVector, and read (or even worse: write!) out of bounds! 00251 */ 00252 inline iterator& operator-=(const int n) {pos-=n; return *this;}; 00253 00254 /** 00255 * advance (skip) some elements. 00256 * Use this operator with care! Note that you can skip the end of 00257 * the genericVector, and read (or even worse: write!) out of bounds! 00258 */ 00259 inline iterator operator+(const int n) { 00260 return iterator(pos+n,theGenericVector); 00261 }; 00262 00263 /** 00264 * recede (skip) some elements. 00265 * Use this operator with care! Note that you can skip the beginning of 00266 * the genericVector, and read (or even worse: write!) out of bounds! 00267 */ 00268 inline iterator operator-(const int n) { 00269 return iterator(pos-n,theGenericVector); 00270 }; 00271 00272 /** 00273 * compare if both pointed positions are the same 00274 */ 00275 inline bool operator==(const iterator& other) const { 00276 return (pos == other.pos); 00277 }; 00278 00279 /** 00280 * compare if both pointed positions are different 00281 */ 00282 inline bool operator!=(const iterator& other) const { 00283 return (pos != other.pos); 00284 }; 00285 00286 /** 00287 * compare if the position of the first iterator is smaller than 00288 * the position of the second iterator 00289 */ 00290 inline bool operator<(const iterator& other) const { 00291 return (pos < other.pos); 00292 }; 00293 00294 /** 00295 * compare if the position of the first iterator is greater than 00296 * the position of the second iterator 00297 */ 00298 inline bool operator>(const iterator& other) const { 00299 return (pos > other.pos); 00300 }; 00301 00302 /** 00303 * compare if the position of the first iterator is smaller or equal than 00304 * the position of the second iterator 00305 */ 00306 inline bool operator<=(const iterator& other) const { 00307 return (pos <= other.pos); 00308 }; 00309 00310 /** 00311 * compare if the position of the first iterator is greater or equal 00312 * than the position of the second iterator 00313 */ 00314 inline bool operator>=(const iterator& other) const { 00315 return (pos >= other.pos); 00316 }; 00317 00318 /** 00319 * get pointed data 00320 */ 00321 inline T& operator*() {return theGenericVector->at(pos);}; 00322 00323 /** 00324 * access the elements relative to the iterator position 00325 */ 00326 inline T& operator[](const int i) {return theGenericVector->at(pos+i);}; 00327 00328 /** 00329 * copy member 00330 */ 00331 inline iterator& operator=(const iterator& other) { 00332 pos = other.pos; 00333 theGenericVector = other.theGenericVector; 00334 return *this; 00335 }; 00336 00337 protected: 00338 /** 00339 * protected constructor (for internal use only) 00340 * NEVER USE EXPLICITLY THIS CONSTRUCTOR, OR YOUR CODE WILL NOT 00341 * COMPILE IN THE RELEASE VERSION! 00342 */ 00343 explicit iterator(const int startPos,genericVector<T>* vct) 00344 : pos(startPos), theGenericVector(vct) {}; 00345 00346 /** 00347 * for internal use only!!! 00348 * This method does not exist in the release version! 00349 */ 00350 const int& getPos() const {return pos;}; 00351 00352 /** 00353 * for internal use only!!! 00354 * This method does not exist in the release version! 00355 */ 00356 const genericVector<T>* getGenericVector() const { 00357 return theGenericVector; 00358 }; 00359 00360 private: 00361 /** 00362 * actual genericVector index 00363 */ 00364 int pos; 00365 00366 /** 00367 * pointer to the actual genericVector 00368 */ 00369 genericVector<T>* theGenericVector; 00370 }; 00371 00372 /** 00373 * const iterator type (allows read-only operations). 00374 * 00375 * The use of the iterator classes is similar to the iterators of 00376 * the STL (Standard Template Library). See lti::genericVector::begin() 00377 * for an example. 00378 * 00379 * For the debugging version of the iterators, boundary check will be 00380 * done! This explains the low speed of the iterators of the debug 00381 * version. In the release version, no boundary check will be done, 00382 * and the iterators are sometimes a factor 10 faster than the 00383 * debug iterators. 00384 * 00385 * The use of the access operator at(.) is faster than the 00386 * iterators in the debug version only. If you need to iterate on 00387 * a genericVector use iterators instead (in the release version 00388 * iterators are approx. a factor 3 faster than "at(.)"). 00389 * 00390 * CAUTION: Try to use the prefix incremental operator 00391 * (i.e. ++it) instead of the postfix operator (i.e. it++) to 00392 * allow efficient code also in debug-modus! 00393 * 00394 * see also iterator 00395 */ 00396 class const_iterator { 00397 friend class genericVector<T>; 00398 public: 00399 /** 00400 * default constructor 00401 */ 00402 const_iterator() 00403 : pos(0), theGenericVector(0) {}; 00404 00405 /** 00406 * copy constructor 00407 */ 00408 const_iterator(const const_iterator& other) {(*this)=other;}; 00409 00410 /** 00411 * copy constructor 00412 */ 00413 const_iterator(const iterator& other) {(*this)=other;}; 00414 00415 /** 00416 * advance to next item -- prefix 00417 */ 00418 inline const_iterator& operator++() {++pos; return *this;}; 00419 00420 /** 00421 * advance to next item -- postfix 00422 */ 00423 inline const_iterator operator++(int) { 00424 const_iterator tmp(*this); pos++; return tmp; 00425 }; 00426 00427 /** 00428 * recede to previous item -- prefix 00429 */ 00430 inline const_iterator& operator--() {--pos; return *this;}; 00431 00432 /** 00433 * recede to previous item -- postfix 00434 */ 00435 inline const_iterator operator--(int) { 00436 const_iterator tmp(*this); pos--; return tmp; 00437 }; 00438 00439 /** 00440 * advance (skip) some elements. 00441 * Use this operator with care! Note that you can skip the end of 00442 * the genericVector, and read (or even worse: write!) out of bounds! 00443 */ 00444 inline const_iterator& operator+=(const int n) {pos+=n; return *this;}; 00445 00446 /** 00447 * recede (skip) some elements. 00448 * Use this operator with care! Note that you can skip the beginning of 00449 * the genericVector, and read (or even worse: write!) out of bounds! 00450 */ 00451 inline const_iterator& operator-=(const int n) {pos-=n; return *this;}; 00452 00453 /** 00454 * advance (skip) some elements. 00455 * Use this operator with care! Note that you can skip the end of 00456 * the genericVector, and read (or even worse: write!) out of bounds! 00457 */ 00458 inline const_iterator operator+(const int n) { 00459 return const_iterator(pos+n,theGenericVector); 00460 }; 00461 00462 /** 00463 * recede (skip) some elements. 00464 * Use this operator with care! Note that you can skip the beginning of 00465 * the genericVector, and read (or even worse: write!) out of bounds! 00466 */ 00467 inline const_iterator operator-(const int n) { 00468 return const_iterator(pos-n,theGenericVector); 00469 }; 00470 00471 /** 00472 * compare if both pointed positions are the same 00473 */ 00474 inline bool operator==(const const_iterator& other) const { 00475 return (pos == other.pos); 00476 }; 00477 00478 /** 00479 * compare if both pointed positions are different 00480 */ 00481 inline bool operator!=(const const_iterator& other) const { 00482 return (pos != other.pos); 00483 }; 00484 00485 /** 00486 * compare if both pointed positions are the same 00487 */ 00488 inline bool operator==(const iterator& other) const { 00489 return (pos == other.getPos()); 00490 }; 00491 00492 /** 00493 * compare if both pointed positions are different 00494 */ 00495 inline bool operator!=(const iterator& other) const { 00496 return (pos != other.getPos()); 00497 }; 00498 00499 /** 00500 * compare if the position of the first iterator is smaller than 00501 * the position of the second iterator 00502 */ 00503 inline bool operator<(const iterator& other) const { 00504 return (pos < other.pos); 00505 }; 00506 00507 /** 00508 * compare if the position of the first iterator is greater than 00509 * the position of the second iterator 00510 */ 00511 inline bool operator>(const iterator& other) const { 00512 return (pos > other.pos); 00513 }; 00514 00515 /** 00516 * compare if the position of the first iterator is smaller or equal than 00517 * the position of the second iterator 00518 */ 00519 inline bool operator<=(const iterator& other) const { 00520 return (pos <= other.pos); 00521 }; 00522 00523 /** 00524 * compare if the position of the first iterator is greater or equal 00525 * than the position of the second iterator 00526 */ 00527 inline bool operator>=(const iterator& other) const { 00528 return (pos >= other.pos); 00529 }; 00530 00531 /** 00532 * compare if the position of the first iterator is smaller than 00533 * the position of the second iterator 00534 */ 00535 inline bool operator<(const const_iterator& other) const { 00536 return (pos < other.pos); 00537 }; 00538 00539 /** 00540 * compare if the position of the first iterator is greater than 00541 * the position of the second iterator 00542 */ 00543 inline bool operator>(const const_iterator& other) const { 00544 return (pos > other.pos); 00545 }; 00546 00547 /** 00548 * compare if the position of the first iterator is smaller or equal than 00549 * the position of the second iterator 00550 */ 00551 inline bool operator<=(const const_iterator& other) const { 00552 return (pos <= other.pos); 00553 }; 00554 00555 /** 00556 * compare if the position of the first iterator is greater or equal 00557 * than the position of the second iterator 00558 */ 00559 inline bool operator>=(const const_iterator& other) const { 00560 return (pos >= other.pos); 00561 }; 00562 00563 /** 00564 * get pointed data 00565 */ 00566 inline const T& operator*() {return theGenericVector->at(pos);}; 00567 00568 /** 00569 * access the elements relative to the iterator position 00570 */ 00571 inline const T& operator[](const int i) { 00572 return theGenericVector->at(pos+i); 00573 }; 00574 00575 /** 00576 * copy member 00577 */ 00578 inline const_iterator& operator=(const const_iterator& other) { 00579 pos = other.pos; 00580 theGenericVector = other.theGenericVector; 00581 return *this; 00582 }; 00583 00584 /** 00585 * copy member 00586 */ 00587 inline const_iterator& operator=(const iterator& other) { 00588 pos = other.getPos(); 00589 theGenericVector = other.getGenericVector(); 00590 return *this; 00591 }; 00592 00593 protected: 00594 /** 00595 * protected constructor 00596 * DO NOT EXPLICITLY USE THIS CONSTRUCTOR. OTHERWISE YOUR CODE WILL NOT 00597 * COMPILE IN THE RELEASE VERSION! 00598 */ 00599 explicit const_iterator(int startPos,const genericVector<T>* vct) 00600 : pos(startPos), theGenericVector(vct) {}; 00601 00602 private: 00603 00604 /** 00605 * actual genericVector index 00606 */ 00607 int pos; 00608 00609 /** 00610 * pointer to the actual genericVector 00611 */ 00612 const genericVector<T>* theGenericVector; 00613 }; 00614 00615 # endif 00616 00617 /** 00618 * Default constructor creates an empty genericVector; 00619 */ 00620 genericVector(); 00621 00622 /** 00623 * Create a genericVector of the given size and initialize it with the 00624 * given value. 00625 * @param theSize number of elements of the genericVector. 00626 * @param iniValue all elements will be initialized with this value. 00627 */ 00628 explicit genericVector(int theSize,const T& iniValue = T()); 00629 00630 /** 00631 * Create a genericVector of the given size and initialize it with the 00632 * given data. The \a data will be copied. 00633 * @see useExternData() 00634 * @param theSize number of elements of the genericVector. 00635 * @param data a pointer to the data that will be copied. 00636 */ 00637 genericVector(int theSize,const T data[]); 00638 00639 /** 00640 * Create a genericVector of the given size and initialize it with the 00641 * given data, the same way "useExternData" does. 00642 * The \a data will not be copied!. 00643 * @see useExternData() 00644 * @param theSize number of elements of the genericVector. 00645 * @param data a pointer to the data that will be used. 00646 * @param constRef if this parameter is true, it will not be possible to 00647 * change the pointer to the external memory block nor 00648 * to resize the genericVector. Despite this, the value of 00649 * each element can be changed by the access operators. 00650 */ 00651 genericVector(int theSize,T data[],const bool constRef); 00652 00653 /** 00654 * Create this genericVector as a copy of another genericVector 00655 * @param other the genericVector to be copied. 00656 */ 00657 genericVector(const genericVector<T>& other); 00658 00659 /** 00660 * Create this genericVector as a copy of specified interval of 00661 * elements of another genericVector. Indices below zero are set 00662 * to zero, indices greater than the size of the %genericVector to 00663 * the size-1. 00664 * @param other the genericVector to be copied. 00665 * @param from starting point included 00666 * @param to end point included. 00667 */ 00668 genericVector(const genericVector<T>& other, 00669 int from, int to=MaxInt32); 00670 00671 /** 00672 * Create this genericVector as a copy of specified elements of 00673 * another genericVector. \a idx can contain the same index more 00674 * than once. 00675 * @param other the genericVector to be copied. 00676 * @param idx indices of the elements to be copied 00677 */ 00678 genericVector(const genericVector<T>& other, 00679 const genericVector<int>& idx); 00680 00681 /** 00682 * Create this genericVector as a copy of another std::genericVector 00683 * @param other the genericVector to be copied. 00684 */ 00685 genericVector(const std::vector<T>& other); 00686 00687 /** 00688 * If \a init is true this constructor is equivalent to calling 00689 * genericVector(int theSize), and thus initializing 00690 * all elements with T(). However, in some cases the elements need 00691 * not be initialized during construction, since complex 00692 * initializion is required. Especially for large genericVectors, the 00693 * unnecessary constructor initialization is very time consuming. 00694 * 00695 * If \a init is false, memory is allocated but no initialization 00696 * takes place. Thus the following is equivalent: 00697 * \code 00698 * genericVector<int> a(false,10000); 00699 * 00700 * matrix<int> a; 00701 * a.resize(10000,0,false,false); 00702 * \endcode 00703 * 00704 * @param init initialize matrix or not 00705 * @param theSize number of elements of the genericVector. 00706 */ 00707 genericVector(bool init, int theSize); 00708 00709 /** 00710 * destructor 00711 */ 00712 virtual ~genericVector(); 00713 00714 /** 00715 * returns the name of this class: "genericVector" 00716 */ 00717 const char* getTypeName() const {return "genericVector";}; 00718 00719 /** 00720 * Check whether this %object owns the data. 00721 * returns \a false if this genericVector contains a reference to extern 00722 * data. 00723 */ 00724 inline bool ownsData() const; 00725 00726 /** 00727 * If this object does not own its data, this member will create a 00728 * new memory buffer with the same data and will make this matrix 00729 * as its owner. You can also be sure, that the new memory block 00730 * will be connected (see also getMode() ). If this genericVector 00731 * already owns its data nothing happens. 00732 */ 00733 void restoreOwnership(); 00734 00735 /** 00736 * Reference to extern data. 00737 * 00738 * This member allows the use of this %object as an wrapper-%object to 00739 * access some memory block as a genericVector. 00740 * The user must take care for memory allocation and deallocation of 00741 * the block. This %object will never delete the external data!. 00742 * @param theSize number of \e elements in the external block. Note that 00743 * this is NOT the number of bytes of the external block. 00744 * @param data pointer to the external memory block. 00745 * @param constRef if this parameter is true, it will not be possible to 00746 * change the pointer to the external memory block nor 00747 * to resize the genericVector. Despite this, the value of 00748 * each element can be changed by the access operators. 00749 * For Example: 00750 * \code 00751 * int i; 00752 * double tmp; 00753 * double a[10]; // memory block! 00754 * 00755 * for (i=0;i<10;i++) { 00756 * a[i]=2*i; // initialize the memory block 00757 * } 00758 * 00759 * lti::genericVector<double> myVct; // an empty genericVector 00760 * 00761 * myVct.resize(5,0); // resize the genericVector: now 5 elements 00762 * // initialized with 0 00763 * 00764 * myVct.useExternData(10,a,true); // use the genericVector as wrapper 00765 * // for the memory block 00766 * 00767 * tmp = myVct.at(5); // tmp is now 10 00768 * 00769 * myVct.at(9) = 3; // the last element of myVct 00770 * // has now the value 3 00771 * 00772 * myVct.resize(5); // INVALID!! this will throw an exception 00773 * // constReferenceException() 00774 * \endcode 00775 * 00776 * 00777 * If \a theSize is greater than the allocated memory, the behaviour could 00778 * be unpredictible. 00779 */ 00780 void useExternData(int theSize,T* data,bool constRef=false); 00781 00782 /** 00783 * Attach extern data to the matrix. 00784 * 00785 * This member allows the use of this %object as an access-functor for 00786 * the 'data'. An access to the element at (x) is equivalent to 00787 * data[x]. 00788 * If \a theSize is an invalid dimension, the 00789 * behaviour will be unpredictible. 00790 * 00791 * The memory will be administrated by this genericVector 00792 * instance, and may be deleted if required (genericVector deleted 00793 * or resized!). The user should not try to manipulate the memory 00794 * allocation of the data after the attachment! See also 00795 * useExternData(). 00796 * 00797 * @param theSize number of elements of the genericVector 00798 * @param data a pointer to the memory block to be used 00799 * 00800 * Example: 00801 * \code 00802 * lti::genericVector<int> myVct; 00803 * int block1[25]; 00804 * int* block2; 00805 * block2 = new int[25]; 00806 * 00807 * myVct.useExternData(25,block1); // ok 00808 * myVct.attach(25,block1); // wrong!!! matrix will try to manipulate 00809 * // stack memory: DO NOT DO THIS!!!!! 00810 * myVct.attach(25,block2); // ok! but do not try to delete the memory 00811 * // block2!! 00812 * \endcode 00813 */ 00814 void attach(int theSize,T* data); 00815 00816 /** 00817 * Free the data of this object and hand it over to the 00818 * "receiver". The value of ownsData is also transfered to the 00819 * receiver. (see Note). 00820 * 00821 * This function makes a "memory block transfusion" to another 00822 * genericVector. It is a very efficient way to make a copy of 00823 * this genericVector, if you don't need the source data anymore! 00824 * 00825 * \b Note: Take care that if the attach() or useExternData() 00826 * methods of this genericVector have been called before detachment, the 00827 * same rules for memory management apply now for the receiver. 00828 * 00829 * At the end of the detachment, this genericVector will be empty. 00830 * @param receiver the genericVector which will receive the memory 00831 * block. All data of that genericVector will be first deleted! 00832 */ 00833 void detach(genericVector<T>& receiver); 00834 00835 /** 00836 * \deprecated Please use swap() instead. 00837 */ 00838 void exchange(genericVector<T>& other); 00839 00840 /** 00841 * Exchange (in a fast way) the data between this and the other 00842 * genericVector. Similar to detach(), this method will exchange 00843 * the complete memory blocks, avoiding an element-wise copy. 00844 * @param other the genericVector with which the data will be 00845 * exchanged. 00846 */ 00847 void swap(genericVector<T>& other); 00848 00849 /** 00850 * Return type of the size() member 00851 */ 00852 typedef int size_type; 00853 00854 /** 00855 * Returns the number of elements of the genericVector 00856 */ 00857 inline const int& size() const; 00858 00859 /** 00860 * Returns first index (normally 0) 00861 */ 00862 inline int firstIdx() const; 00863 00864 /** 00865 * Returns first element as a const_iterator. 00866 * 00867 * Note that you can not change the values of the genericVector 00868 * elements when you use a const_iterator. See also begin() 00869 */ 00870 inline const_iterator begin() const; 00871 00872 /** 00873 * Returns iterator pointing to the first element. 00874 * 00875 * The use of the iterators is similar to the iterators of the 00876 * Standard Template Library (STL). 00877 * If you need to iterate on all elements of the genericVector, you can 00878 * use following code: 00879 * 00880 * \code 00881 * int tmp,accu; // a temporal variable 00882 * lti::genericVector<int> myVct(10,1); // a genericVector with 10 elements 00883 * lti::genericVector<int>::iterator it=myVct.begin(); // an iterator set to the beginning of myVct 00884 * lti::genericVector<int>::iterator eit=myVct.begin(); // an iterator set to the end of myVct 00885 * 00886 * for (; it!=eit ; ++it) { 00887 * tmp = *it; // tmp has value of element pointed 00888 * // by the iterator. 00889 * accu += tmp; 00890 * (*it) = accu; // change the value in the genericVector. 00891 * } 00892 * \endcode 00893 * 00894 * \b NOTE: It is significantly faster in debug builds to use a 00895 * pre-increment with iterators (++it) than a post-increment 00896 * (it++). 00897 * 00898 * Please note that if you define \a it as a const_iterator, 00899 * you can not do something like \a *it=accu. 00900 */ 00901 inline iterator begin(); 00902 00903 /** 00904 * returns last index (in a genericVector this is always size()-1) 00905 */ 00906 inline int lastIdx() const; 00907 00908 /** 00909 * returns last index as a const iterator. 00910 * For an example see begin() 00911 */ 00912 inline const_iterator end() const; 00913 00914 /** 00915 * returns last index as an iterator 00916 * For an example see begin() 00917 */ 00918 inline iterator end(); 00919 00920 00921 /** 00922 * This method returns an iterator that points to the \b last 00923 * valid element of the genericVector. It is used for inverse order 00924 * iteration through the genericVector using normal iterators (as opposed 00925 * to reverse_iterators used in the STL). This has the advantage 00926 * that iterators going from front to end and in the inverse 00927 * direction are the same and can thus be compared, copied 00928 * etc. Further the implementation of reverse_iterators is not as 00929 * fast as that of iterators and thus not desired in the LTI-Lib. 00930 * 00931 * \code 00932 * igenericVector v(false,10); 00933 * int i,tmp; 00934 * for (i=0; i<10; i++) { 00935 * v.at(i)=i; 00936 * } 00937 * igenericVector::iterator forwardIt=v.begin(); 00938 * igenericVector::iterator backIt=v.inverseBegin(); 00939 * 00940 * while (forwardIt<=backIt) { 00941 * tmp = (*forwardIt); (*forwardIt)=(*backIt); (*backIt)=tmp; 00942 * ++forwardIt; ++backIt; 00943 * } 00944 * \endcode 00945 */ 00946 inline iterator inverseBegin(); 00947 00948 /** 00949 * This method returns an iterator that points to the \b last 00950 * valid element of the genericVector. See inverseBegin() for more details. 00951 */ 00952 inline const_iterator inverseBegin() const; 00953 00954 /** 00955 * This method returns an iterator that points to the element \b 00956 * before the \b first valid element of the genericVector. It is used to 00957 * mark the end for inverse order iteration through the genericVector 00958 * using normal iterators (as opposed to reverse_iterators as used 00959 * in the STL). This has the advantage that iterators going from 00960 * front to end and in the inverse direction are the same and can 00961 * thus be compared, copied etc.Further the implementation of 00962 * reverse_iterators is not as fast as that of iterators and thus 00963 * not desired in the LTI-Lib. 00964 */ 00965 inline iterator inverseEnd(); 00966 00967 /** 00968 * This method returns an iterator that points to the element \b 00969 * before the \b first valid element of the genericVector. 00970 */ 00971 inline const_iterator inverseEnd() const; 00972 00973 /** 00974 * change dimension of the genericVector. 00975 * @param newSize the new size of the genericVector 00976 * @param iniValue the initialization value. 00977 * @param copyData if this parameter is true, the old data of the 00978 * genericVector will be copied. If it is false, 00979 * the old data will be lost. 00980 * @param initNew if this parameter is true, then all new elements (if 00981 * they exist) will be initialized with 00982 * \a iniValue. 00983 * if \a initNew is false, then the new 00984 * elements are left uninitialized. 00985 * 00986 * For example: 00987 * \code 00988 * lti::genericVector<int> myVct; // creates empty genericVector 00989 * myVct.resize(5,0); // genericVector with 5 elements initialized 00990 * // with 0 00991 * myVct.resize(10,2); // genericVector has now 10 elements: the 00992 * // first five are still 0 and the 00993 * // rest have a 2 00994 * myVct.resize(20,3,false,false); // now the genericVector has 20 00995 * // elements but their values 00996 * // are unknown. 00997 * myVct.resize(5,1,false,true); // the genericVector has now 5 00998 * // elements initialized with 1 00999 * 01000 * // note that the last line could also be written: 01001 * 01002 * myVct.resize(5,1,false); // the genericVector has now 5 01003 * // elements initialized with 1 01004 * 01005 * \endcode 01006 * 01007 * 01008 * If the new size is not equal to the old size, the genericVector 01009 * always owns the data afterwards (i.e. new memory is allocated) 01010 * even if it didn't own the data before. Otherwise the ownership 01011 * remains unchanged. You can use restoreOwnership() if you just 01012 * want to own the data. 01013 */ 01014 void resize(int newSize, 01015 const T& iniValue = T(), 01016 bool copyData = true, 01017 bool initNew = true); 01018 01019 /** 01020 * clears the genericVector (dimension 0) 01021 */ 01022 void clear(); 01023 01024 /** 01025 * returns true if the genericVector is empty 01026 */ 01027 bool empty() const; 01028 01029 /** 01030 * fills the genericVector elements with \a iniValue between 01031 * \a from and \a to. 01032 * @param iniValue the elements will be initialized with this 01033 * value. 01034 * @param from first element index 01035 * @param to last element index 01036 * 01037 * If \a from or \a to are out of bounds, 01038 * they will be (internaly) adjusted to to correct value. 01039 * 01040 * Example: 01041 * \code 01042 * lti::genericVector<double> myVct(10,0); // genericVector with 10 elements 01043 * // with 0 01044 * myVct.fill(9,1,3); // myVct=[0,9,9,9,0,0,0,0,0,0] 01045 * \endcode 01046 */ 01047 void fill(const T& iniValue,int from = 0, 01048 int to = MaxInt32); 01049 01050 /** 01051 * fills the genericVector elements with data pointed by \a data 01052 * between \a from and \a to. 01053 * @param data the data to by copied into this genericVector 01054 * @param from first element index 01055 * @param to last element index 01056 * 01057 * If \a from or \a to are out of bounds, 01058 * they will be (internaly) adjusted to to correct value. 01059 * 01060 * Example: 01061 * \code 01062 * double* data = {2,4,8,16}; 01063 * lti::genericVector<double> myVct(10,0); // genericVector with 10 elements 01064 * // with 0 01065 * myVct.fill(data,1,3); // myVct=[0,2,4,8,0,0,0,0,0,0] 01066 * \endcode 01067 */ 01068 void fill(const T data[],int from = 0, 01069 int to = MaxInt32); 01070 01071 /** 01072 * fills the genericVector elements from \a from to 01073 * \a to with the elements of \a vct starting 01074 * at \a startAt. 01075 * @param vct genericVector with the elements to be copied 01076 * @param from first element index of the actual genericVector 01077 * @param to last element index of the actual genericVector 01078 * @param startAt start index of the source genericVector \a vct. 01079 * 01080 * Example: if a = [0 0 0 0 0] and b = [1 2 3], after a.fill(b,3,4,1) 01081 * results a = [0 0 0 2 3] 01082 */ 01083 void fill(const genericVector<T>& vct,int from = 0, 01084 int to = MaxInt32, 01085 int startAt = 0); 01086 01087 /** 01088 * access element x of the genericVector 01089 * @param x index of the genericVector element to be accessed. It should 01090 * be between firstIdx() and lastIdx() 01091 */ 01092 inline T& at(const int x); 01093 01094 /** 01095 * access element x of the genericVector in a read-only modus 01096 * @param x index of the genericVector element to be accessed. It should 01097 * be between firstIdx() and lastIdx() 01098 */ 01099 inline const T& at(const int x) const; 01100 01101 /** 01102 * access operator (alias for at(const int x)). 01103 */ 01104 inline T& operator[](const int x); 01105 01106 /** 01107 * const access operator (alias for at(const int x) const). 01108 */ 01109 inline const T& operator[](const int x) const; 01110 01111 /** assigment operator. 01112 * copy the contents of \a other in this %object. 01113 * @param other the source genericVector to be copied. 01114 */ 01115 genericVector<T>& copy(const genericVector<T>& other); 01116 01117 /** 01118 * assignment operator. 01119 * copy of specified interval of elements of another genericVector. 01120 * @param other the genericVector to be copied. 01121 * @param from starting point included 01122 * @param to end point included. 01123 */ 01124 genericVector<T>& copy(const genericVector<T>& other, 01125 int from, int to=MaxInt32); 01126 01127 /** 01128 * assignment operator. 01129 * copy of specified elements of \a other in this %object. 01130 * \a idx can contain the same index more than once. 01131 * @param other the genericVector to be copied. 01132 * @param idx indices of the elements to be copied 01133 */ 01134 genericVector<T>& copy(const genericVector<T>& other, const genericVector<int>& idx); 01135 01136 /** 01137 * assigment operator (alias for copy(other)). 01138 * @param other the genericVector to be copied 01139 * @return a reference to the actual genericVector 01140 */ 01141 genericVector<T>& operator=(const genericVector<T>& other) {return copy(other);}; 01142 01143 /** 01144 * create a clone of this genericVector 01145 * @return a pointer to a copy of this genericVector 01146 */ 01147 virtual mathObject* clone() const; 01148 01149 /** 01150 * compare this genericVector with other 01151 * @param other the other genericVector to be compared with 01152 * @return true if both genericVectors have the same elements and same size 01153 */ 01154 bool equals(const genericVector<T>& other) const; 01155 01156 /** 01157 * compare this genericVector with other 01158 * @param other the other genericVector to be compared with 01159 * @return true if both genericVectors have the same elements and same size 01160 */ 01161 inline bool operator==(const genericVector<T>& other) const; 01162 01163 /** 01164 * compare this genericVector with other 01165 * @param other the other genericVector to be compared with 01166 * @return true if both genericVectors different dimensions or elements 01167 */ 01168 inline bool operator!=(const genericVector<T>& other) const; 01169 01170 /** 01171 * copy the \a other genericVector by casting each of its 01172 * elements. 01173 * @param other The genericVector to be copied. 01174 * 01175 * For Example: 01176 * \code 01177 * lti::genericVector<int> vctA(10,1); // a genericVector of integers 01178 * lti::genericVector<double> vctB; // a genericVector of doubles 01179 * 01180 * vctB.castFrom(vctA); // this will copy vctA in vctB!! 01181 * \endcode 01182 */ 01183 template<class U> 01184 genericVector<T>& castFrom(const genericVector<U>& other) { 01185 typename genericVector<U>::const_iterator it,eit; 01186 typename genericVector<T>::iterator dit; 01187 01188 // only resize if necessary. castFrom doesn't guarantee ownership. 01189 if (other.size() != size()) { 01190 resize(other.size(),T(),false,false); 01191 } 01192 01193 for (it=other.begin(),dit=begin(),eit=other.end(); 01194 it!=eit;++it,++dit) { 01195 *dit = static_cast<T>(*it); 01196 } 01197 01198 return *this; 01199 }; 01200 01201 /** 01202 * cast from a std::vector of the same type 01203 */ 01204 template<class U> 01205 genericVector<T>& castFrom(const std::vector<U>& other) { 01206 typename std::vector<U>::const_iterator it,eit; 01207 typename genericVector<T>::iterator dit; 01208 01209 // only resize if necessary. castFrom doesn't guarantee ownership. 01210 if (static_cast<int>(other.size()) != size()) { 01211 resize(static_cast<int>(other.size()),T(),false,false); 01212 } 01213 01214 for (it=other.begin(),dit=begin(),eit=other.end(); 01215 it!=eit;++it,++dit) { 01216 *dit = static_cast<T>(*it); 01217 } 01218 01219 return *this; 01220 }; 01221 01222 01223 /** 01224 * @name Apply Methods 01225 */ 01226 //@{ 01227 01228 /** 01229 * applies a C-function to each element of the genericVector. 01230 * 01231 * In the following example, %genericVector \a vct is initialized with 01232 * 4.0. After applying \a sqrt(), all elements of \a vct are 2.0. 01233 * \code 01234 * genericVector<float> vct(4,4.0); 01235 * vct.apply(sqrt); 01236 * \endcode 01237 * @param function a pointer to a C-function 01238 * @return a reference to the actual genericVector 01239 */ 01240 genericVector<T>& apply(T (*function)(T)); 01241 01242 /** 01243 * applies a C-function to each element of the other genericVector and leaves 01244 * the result here. 01245 * @param other the source genericVector 01246 * @param function a pointer to a C-function 01247 * @return a reference to the actual genericVector 01248 */ 01249 genericVector<T>& apply(const genericVector<T>& other,T (*function)(T)); 01250 01251 /** 01252 * applies a C-function to each element of the genericVector. 01253 * @param function a pointer to a C-function 01254 * @return a reference to the actual genericVector 01255 */ 01256 genericVector<T>& apply(T (*function)(const T&)); 01257 01258 /** 01259 * applies a C-function to each element the other genericVector and 01260 * leaves the result here. 01261 * @param other the genericVector with the source data 01262 * @param function a pointer to a C-function 01263 * @return a reference to the actual genericVector 01264 */ 01265 genericVector<T>& apply(const genericVector<T>& other, 01266 T (*function)(const T&)); 01267 01268 /** 01269 * a two-parameter C-function receives the i-th elements of this 01270 * and the given genericVector and the result will be left in this 01271 * genericVector. Note that both genericVectors MUST have the same size! 01272 * If both genericVectors have different size, the function will throw an 01273 * assertion without changing anything! 01274 * @param other the second genericVector to be considered (the first 01275 * genericVector will be this object!) 01276 * @param function a pointer to a two parameters C-function 01277 * @return a reference to the actual genericVector 01278 */ 01279 genericVector<T>& apply(const genericVector<T>& other, 01280 T (*function)(const T&,const T&)); 01281 01282 /** 01283 * a two-parameter C-function receives the i-th elements of this 01284 * and the given genericVector and the result will be left in this 01285 * genericVector. Note that both genericVectors MUST have the same size! 01286 * If both genericVectors have different size, the function will throw an 01287 * assertion without changing anything! 01288 * @param other the second genericVector to be considered (the first 01289 * genericVector will be this object!) 01290 * @param function a pointer to a two parameters C-function 01291 * @return a reference to the actual genericVector 01292 */ 01293 genericVector<T>& apply(const genericVector<T>& other,T (*function)(T,T)); 01294 01295 /** 01296 * a two-parameter C-function receives the i-th elements of the 01297 * given genericVectors and leaves the result here. 01298 * Note that both genericVectors MUST have the same size! 01299 * If both genericVectors have different size, the function will throw an 01300 * assertion without changing anything! 01301 * 01302 * The following example uses lti::min as function. The genericVectors \a 01303 * a and \a b contain the values [1,2,3,4] and [4,3,2,1], 01304 * respectively. After applying the function, %genericVector \a c 01305 * contains the values [1,2,2,1]. 01306 * \code 01307 * igenericVector a,b,c; 01308 * int i=0; 01309 * for (i=0; i<4; ++i) { 01310 * a.at(i)=i+1; 01311 * b.at(i)=4-i; 01312 * } 01313 * c.apply(a,b,lti::min); 01314 * \endcode 01315 * @param a the first genericVector 01316 * @param b the second genericVector 01317 * @param function a pointer to a two parameters C-function 01318 * @return a reference to the actual genericVector 01319 */ 01320 genericVector<T>& apply(const genericVector<T>& a, 01321 const genericVector<T>& b, 01322 T (*function)(const T&,const T&)); 01323 01324 /** 01325 * a two-parameter C-function receives the i-th elements of the 01326 * given genericVectors and leaves the result here. 01327 * Note that both genericVectors MUST have the same size! 01328 * If both genericVectors have different size, the function will throw an 01329 * assertion without changing anything! 01330 * @param a the first genericVector 01331 * @param b the second genericVector 01332 * @param function a pointer to a two parameters C-function 01333 * @return a reference to the actual genericVector 01334 */ 01335 genericVector<T>& apply(const genericVector<T>& a, 01336 const genericVector<T>& b, 01337 T (*function)(T,T)); 01338 01339 //@} 01340 01341 /** 01342 * @name Input and Output 01343 */ 01344 //@{ 01345 /** 01346 * write the object in the given ioHandler 01347 */ 01348 virtual bool write(ioHandler& handler,const bool complete = true) const; 01349 01350 /** 01351 * read the object from the given ioHandler 01352 */ 01353 virtual bool read(ioHandler& handler,const bool complete = true); 01354 //@} 01355 01356 protected: 01357 /** 01358 * dimension of the genericVector. 01359 */ 01360 int vectorSize; 01361 01362 /** 01363 * index of the last element of the genericVector (always 01364 * vectorSize-1) 01365 */ 01366 int idxLastElement; 01367 01368 /** 01369 * pointer to the first element of the genericVector. 01370 */ 01371 T* theElements; 01372 01373 /** 01374 * reference to extern data. 01375 * if this value ist \a false, then the data pointed by 01376 * \a theElements will never be deleted in this 01377 * %object! (see useExternData()) 01378 */ 01379 bool ownData; 01380 01381 /** 01382 * if constReference=true, is not possible to resize or change 01383 * the reference of this genericVector. Important for the matrix class!! 01384 * (see useExternData()) 01385 */ 01386 bool constReference; 01387 }; 01388 01389 } // namespace lti 01390 01391 /* 01392 * outputs the elements of the genericVector on a stream 01393 */ 01394 namespace std { 01395 template <class T> 01396 ostream& operator<<(ostream& s,const lti::genericVector<T>& v); 01397 } 01398 01399 #include "ltiGenericVector_inline.h" 01400 #include "ltiGenericVector_template.h" 01401 01402 #else 01403 #include "ltiGenericVector_template.h" 01404 #endif