00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef TYPES_INCLUDES
00022 #error "You can't include vectordata.h directly; Instead, You have to include types.h"
00023
00024 #define VECTORDATA_H
00025 #endif
00026
00027 #ifndef VECTORDATA_H
00028 #define VECTORDATA_H
00029
00037 #include "memutils.h"
00038 #include <vector>
00039
00040
00041 namespace nnfw {
00042
00049 template<class T>
00050 class NNFW_TEMPLATE VectorData : private Observer, public Observable {
00051 public:
00053 typedef enum { datachanged = 1, datadestroying = 2 } t_notify;
00054
00057
00059 VectorData()
00060 : Observer(), Observable() {
00061 vsize = 0;
00062 allocated = 0;
00063 data = 0;
00064 view = false;
00065 observed = 0;
00066 idstart = 0;
00067 idend = 0;
00068 };
00069
00071 VectorData( u_int size )
00072 : Observer(), Observable() {
00073 vsize = size;
00074 allocated = size;
00075 if ( vsize == 0 ) {
00076 data = 0;
00077 } else {
00078 data = new T[vsize];
00079 memoryZeroing( data, vsize );
00080 }
00081
00082 view = false;
00083 observed = 0;
00084 idstart = 0;
00085 idend = 0;
00086 };
00087
00089 VectorData( u_int size, T& value )
00090 : Observer(), Observable() {
00091 vsize = size;
00092 allocated = size;
00093 (vsize==0) ? (data = 0) : (data = new T[vsize]);
00094 for(u_int i = 0; i<size; i++) {
00095 data[i] = value;
00096 }
00097
00098 view = false;
00099 observed = 0;
00100 idstart = 0;
00101 idend = 0;
00102 };
00103
00105 VectorData( VectorData<T>& src, u_int idStart, u_int idEnd )
00106 : Observer(), Observable() {
00107 if ( idStart > src.vsize || idEnd > src.vsize || idStart >= idEnd ) {
00108 nError() << "Wrongs indexes specified in VectorData constructor; using 0 and src.size()" ;
00109 idstart = 0;
00110 idend = src.size();
00111 } else {
00112 idstart = idStart;
00113 idend = idEnd;
00114 }
00115 data = (src.data) + idstart;
00116 vsize = idend - idstart;
00117 allocated = 0;
00118 view = true;
00119 src.addObserver( this );
00120 observed = &src;
00121 };
00122
00124 VectorData( const T* r, u_int dim )
00125 : Observer(), Observable() {
00126 data = new T[dim];
00127 vsize = dim;
00128 allocated = dim;
00129 memoryCopy( data, r, dim );
00130
00131 view = false;
00132 observed = 0;
00133 idstart = 0;
00134 idend = 0;
00135 };
00136
00142 VectorData( const VectorData& src )
00143 : Observer(), Observable() {
00144
00145
00146 vsize = src.vsize;
00147 allocated = vsize;
00148 data = new T[allocated];
00149 memoryCopy( data, src.data, vsize );
00150 view = false;
00151 observed = 0;
00152 };
00153
00160 VectorData& operator=( const VectorData& src ) {
00161 VectorData& self = *this;
00162 self.resize( src.size() );
00163 self.assign( src );
00164 return self;
00165 };
00166
00169 ~VectorData() {
00170 notifyAll( NotifyEvent( datadestroying ) );
00171 if ( view ) {
00172 observed->delObserver( this );
00173 } else {
00174 delete []data;
00175 }
00176 };
00178
00180
00183 u_int size() const {
00184 return vsize;
00185 };
00186
00189 bool isView() const {
00190 return view;
00191 };
00192
00195 bool operator==( const VectorData<T>& b ) {
00196 if ( this->size() != b.size() ) return false;
00197 VectorData<T>& self = *this;
00198 for( u_int i=0; i<size(); i++ ) {
00199 if ( self[i] != b[i] ) {
00200 return false;
00201 }
00202 }
00203 return true;
00204 };
00205
00208 bool operator!=( const VectorData<T>& b ) {
00209 return !( *this == b );
00210 };
00211
00213
00215
00217 void zeroing() {
00218 memoryZeroing( data, vsize );
00219 };
00220
00222 void setAll( const T& value ) {
00223 for( u_int i=0; i<vsize; i++ ) {
00224 data[i] = value;
00225 }
00226 };
00227
00229 void erase( int id ) {
00230 if ( view ) {
00231 nError() << "you can't erase element from a VectorData view" ;
00232 } else {
00233 if ( id < 0 || id >= (int)vsize ) return;
00234 for( u_int i=(u_int)id; i<vsize-1; i++ ) {
00235 data[id] = data[id+1];
00236 }
00237 vsize = vsize-1;
00238 notifyAll( NotifyEvent( datachanged ) );
00239 }
00240 };
00241
00243 VectorData<T>& assign( u_int num, const T& value ) {
00244 #ifdef NNFW_DEBUG
00245 if ( num > vsize ) {
00246 nError() << "Wrong number of elements passed to assign method" ;
00247 num = vsize;
00248 }
00249 #endif
00250 for( u_int i=0; i<num; i++ ) {
00251 data[i] = value;
00252 }
00253 return (*this);
00254 };
00255
00257 VectorData<T>& assign( const VectorData<T>& src ) {
00258 #ifdef NNFW_DEBUG
00259 if ( vsize != src.vsize ) {
00260 nError() << "Wrong number of elements between VectorData to assign method" ;
00261 return (*this);
00262 }
00263 #endif
00264 memoryCopy( data, src.data, vsize );
00265 return (*this);
00266 };
00267
00271 VectorData<T>& assign( const VectorData<T>& src, u_int sizec ) {
00272 #ifdef NNFW_DEBUG
00273 if ( vsize < sizec || src.size() < sizec ) {
00274 nError() << "Wrong size specified in assign method" ;
00275 return (*this);
00276 }
00277 #endif
00278 memoryCopy( data, src.data, sizec );
00279 return (*this);
00280 };
00281
00283 VectorData<T>& assign_reverse( const VectorData<T>& src ) {
00284 #ifdef NNFW_DEBUG
00285 if ( vsize != src.vsize ) {
00286 nError() << "Wrong number of elements between VectorData to assign method" ;
00287 return (*this);
00288 }
00289 #endif
00290 for( u_int i=0, j=vsize-1; i<vsize; i++, j-- ) {
00291 data[i] = src.data[j];
00292 }
00293 return (*this);
00294 };
00295
00304 VectorData<int>& compare( const VectorData<T>& b, VectorData<int>& comparison ) {
00305 #ifdef NNFW_DEBUG
00306 if ( vsize != b.vsize ) {
00307 nError() << "Wrong number of elements between VectorData to compare method" ;
00308 return (*this);
00309 }
00310 #endif
00311 VectorData<T>& self = *this;
00312 comparison.resize(size());
00313 for( u_int i=0; i<size(); i++ ) {
00314 if ( self[i] == b[i] ) {
00315 comparison[i] = true;
00316 }
00317 else {
00318 comparison[i] = false;
00319 }
00320 }
00321 return comparison;
00322 };
00323
00327 T& operator[]( u_int index ) {
00328 #ifdef NNFW_DEBUG
00329 if( index >= vsize ) {
00330 nError() << "Accessing elements outside boundary" ;
00331 return data[0];
00332 }
00333 #endif
00334 return data[index];
00335 };
00336
00340 const T& operator[]( u_int index ) const {
00341 #ifdef NNFW_DEBUG
00342 if( index >= vsize ) {
00343 nError() << "Accessing elements outside boundary" ;
00344 return data[0];
00345 }
00346 #endif
00347 return data[index];
00348 };
00349
00353 T& at( u_int index ) {
00354 #ifdef NNFW_DEBUG
00355 if( index >= vsize ) {
00356 nError() << "Accessing elements outside boundary" ;
00357 return data[0];
00358 }
00359 #endif
00360 return data[index];
00361 };
00362
00366 const T& at( u_int index ) const {
00367 #ifdef NNFW_DEBUG
00368 if( index >= vsize ) {
00369 nError() << "Accessing elements outside boundary" ;
00370 return data[0];
00371 }
00372 #endif
00373 return data[index];
00374 };
00375
00377 void resize( u_int newsize ) {
00378 if ( view ) {
00379 nError() << "It's not possible resize RealVec views" ;
00380 return;
00381 }
00382 if ( allocated < newsize ) {
00383 if ( allocated == 0 ) {
00384 allocated = newsize+20;
00385 data = new T[allocated];
00386 } else {
00387 allocated = newsize+20;
00388 T* tmp = new T[allocated];
00389 memoryCopy( tmp, data, vsize );
00390 delete []data;
00391 data = tmp;
00392 }
00393 }
00394 if ( newsize > vsize ) {
00395 memoryZeroing( data+vsize, newsize-vsize );
00396 }
00397 vsize = newsize;
00398
00399 notifyAll( NotifyEvent( datachanged ) );
00400 };
00401
00403 void append( const T& value ) {
00404 resize( vsize+1 );
00405 data[vsize-1] = value;
00406 };
00407
00409 VectorData<T>& operator<<( const T& value ) {
00410 append( value );
00411 return (*this);
00412 };
00414
00416
00420 void setView( u_int idStart, u_int idEnd ) {
00421 if ( !view ) {
00422 nError() << "setView can be called only if VectorData is a view" ;
00423 return;
00424 }
00425 if ( idStart > observed->vsize || idEnd > observed->vsize || idStart >= idEnd ) {
00426 nError() << "Wrongs indexes specified in VectorData setView; using 0 and observed->size()" ;
00427 idstart = 0;
00428 idend = observed->size();
00429 }
00430 idstart = idStart;
00431 idend = idEnd;
00432 data = (observed->data) + idstart;
00433 vsize = idend - idstart;
00434
00435 notifyAll( NotifyEvent( datachanged ) );
00436 };
00437
00440 void convertToView( VectorData<T>& src, u_int idStart, u_int idEnd ) {
00441 if ( observed == (&src) ) {
00442 setView( idStart, idEnd );
00443 return;
00444 }
00445 if ( view ) {
00446
00447 observed->delObserver( this );
00448 } else if ( allocated > 0 ) {
00449
00450 delete []data;
00451 }
00452
00453 if ( idStart > src.vsize || idEnd > src.vsize || idStart >= idEnd ) {
00454 nError() << "Wrongs indexes specified in convertToView; using 0 and src.size()" ;
00455 idstart = 0;
00456 idend = src.size();
00457 } else {
00458 idstart = idStart;
00459 idend = idEnd;
00460 }
00461 data = (src.data) + idstart;
00462 vsize = idend - idstart;
00463 allocated = 0;
00464 view = true;
00465 observed = &src;
00466 observed->addObserver( this );
00467 };
00468
00470
00472
00473 class vectordataIterator;
00474 friend class vectordataIterator;
00475
00477 typedef T value_type;
00479 typedef T& reference;
00481 typedef const T& const_reference;
00483 typedef vectordataIterator iterator;
00485 typedef const vectordataIterator const_iterator;
00487 typedef size_t size_type;
00489 typedef ptrdiff_t difference_type;
00490
00492 size_type max_size() {
00493 return 300000;
00494 };
00495
00497 bool empty() {
00498 return (vsize==0);
00499 };
00500
00502 void push_back( const T& value ) {
00503 resize( vsize+1 );
00504 data[vsize-1] = value;
00505 };
00506
00508 iterator begin() {
00509 return vectordataIterator( *this );
00510 };
00512 const_iterator begin() const {
00513 return vectordataIterator( ((VectorData&)*this) );
00514 };
00515
00517 iterator end() {
00518 return vectordataIterator( *this, vsize );
00519 };
00521 const_iterator end() const {
00522 return vectordataIterator( ((VectorData&)*this), vsize );
00523 };
00524
00526 iterator erase( iterator pos ) {
00527 if ( view ) {
00528 nError() << "you can't erase element from a VectorData view" ;
00529 } else {
00530 u_int id = pos.getIndex();
00531 for( u_int i=id; i<vsize-1; i++ ) {
00532 data[id] = data[id+1];
00533 }
00534 vsize = vsize-1;
00535 notifyAll( NotifyEvent( datachanged ) );
00536 }
00537 return (pos);
00538 };
00539
00541 void clear() {
00542 if ( view ) {
00543 nError() << "you can't clear a VectorData view" ;
00544 } else {
00545 vsize = 0;
00546 notifyAll( NotifyEvent( datachanged ) );
00547 }
00548 };
00549
00551 class vectordataIterator : public std::iterator<std::bidirectional_iterator_tag,T,ptrdiff_t> {
00552 public:
00554 vectordataIterator( VectorData& data, u_int startId = 0 ) : vecdata(data), id(startId) { };
00556 vectordataIterator( const vectordataIterator& src ) : vecdata(src.vecdata), id(src.id) { };
00558 vectordataIterator& operator=( const vectordataIterator& src ) {
00559 vecdata = src.vecdata;
00560 id = src.id;
00561 return (*this);
00562 };
00564 bool operator==( const vectordataIterator& x ) const {
00565 return ( &vecdata == &(x.vecdata) && id == x.id );
00566 };
00568 bool operator!=( const vectordataIterator& x ) const {
00569 return ( &vecdata != &(x.vecdata) || id != x.id );
00570 };
00572 const T& operator*() const {
00573 return vecdata[id];
00574 };
00576 T& operator*() {
00577 return vecdata[id];
00578 };
00580 vectordataIterator& operator++() {
00581 id = (id < vecdata.size()) ? id+1 : vecdata.size();
00582 return (*this);
00583 };
00585 const vectordataIterator& operator++() const {
00586 id = (id < vecdata.size()) ? id+1 : vecdata.size();
00587 return (*this);
00588 };
00590 vectordataIterator& operator--() {
00591 id = ( id > 0 ) ? id-1 : 0;
00592 return (*this);
00593 };
00595 const vectordataIterator& operator--() const {
00596 id = ( id > 0 ) ? id-1 : 0;
00597 return (*this);
00598 };
00600 u_int getIndex() {
00601 return id;
00602 };
00603 private:
00605 VectorData& vecdata;
00607 u_int id;
00608 };
00610
00611 protected:
00612
00614 T* rawdata() const {
00615 return data;
00616 };
00617
00619 u_int vsize;
00621 u_int allocated;
00623 T* data;
00624
00626 bool view;
00628 u_int idstart;
00630 u_int idend;
00632 VectorData* observed;
00633
00635 virtual void notify( const NotifyEvent& event ) {
00636 switch( event.type() ) {
00637 case datachanged:
00638 if ( idstart > observed->vsize || idend > observed->vsize ) {
00639 nError() << "Indexes become invalid after data changing; using 0 and viewed->size()" ;
00640 idstart = 0;
00641 idend = observed->size();
00642 }
00643 data = (observed->data) + idstart;
00644 vsize = idend - idstart;
00645 allocated = 0;
00646 break;
00647 case datadestroying:
00648 #ifdef NNFW_DEBUG
00649 nWarning() << "Destroying a VectorData before its views!!!" ;
00650 #endif
00651
00652 view = false;
00653 data = 0;
00654 vsize = 0;
00655 allocated = 0;
00656 observed = 0;
00657 idstart = 0;
00658 idend = 0;
00659 break;
00660 default:
00661 break;
00662 }
00663
00664 notifyAll( NotifyEvent( datachanged ) );
00665 };
00666
00667 };
00668
00669 }
00670
00671 #endif