00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef TORC_GENERIC_OM_VECTOR_HPP
00017 #define TORC_GENERIC_OM_VECTOR_HPP
00018
00019 #include "torc/generic/om/DumpRestoreConfig.hpp"
00020
00021 #include <algorithm>
00022 #include <numeric>
00023 #include <vector>
00024
00025
00026 #ifdef GENOM_SERIALIZATION
00027 #include <boost/bind.hpp>
00028 #include <boost/mem_fn.hpp>
00029 #include <boost/serialization/access.hpp>
00030 #include <boost/serialization/base_object.hpp>
00031 #include <boost/serialization/vector.hpp>
00032 #include <boost/serialization/shared_ptr.hpp>
00033 #include <boost/serialization/split_member.hpp>
00034 #endif //GENOM_SERIALIZATION
00035
00036 #include "torc/generic/om/Composite.hpp"
00037 #include "torc/generic/om/CompositionType.hpp"
00038 #include "torc/generic/util/Error.hpp"
00039 #include "torc/generic/om/FactoryType.hpp"
00040 #include "torc/generic/om/SymTab.hpp"
00041
00042
00043 namespace torc {
00044
00045 namespace generic {
00046
00047
00048
00049
00050
00051
00052 template<
00053 typename _Type,
00054 typename _ChildType,
00055 typename _ChildFactoryType,
00056 bool cPreserve = false>
00057 class Vector : public virtual Composite<_Type>
00058 {
00059 #ifdef GENOM_SERIALIZATION
00060 friend class boost::serialization::access;
00061 #endif //GENOM_SERIALIZATION
00062
00063 public:
00064 typedef Composite<_Type> BaseType;
00065 typedef typename BaseType::Type Type;
00066 typedef typename BaseType::List List;
00067 typedef typename BaseType::Pointer Pointer;
00068 typedef typename BaseType::SizeType SizeType;
00069 typedef _ChildType ChildType;
00070 typedef boost::shared_ptr<ChildType> ChildPointer;
00071 typedef _ChildFactoryType ChildFactory;
00072 typedef boost::shared_ptr<_ChildFactoryType> ChildFactorySharedPtr;
00073
00074 private:
00075 typedef SymTab<SizeType,Pointer> SparseElements;
00076
00077 protected:
00078 Vector();
00079
00080
00081 public:
00082 virtual
00083 ~Vector() throw();
00084
00085
00086
00087
00088
00089
00090 virtual CompositionType
00091 getCompositionType() const throw();
00092
00093
00094
00095
00096
00097 virtual SizeType
00098 getSize() const throw();
00099
00100 #if 0
00101
00102
00103
00104
00105
00106
00107
00108
00109 virtual void
00110 addChild(const boost::shared_ptr<Type> & inChild,
00111 const std::vector<int> & inIndices) throw(Error);
00112 #endif
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 virtual const Pointer
00164 get(const std::vector<SizeType> & inIndices) const throw(Error);
00165
00166
00167
00168
00169
00170
00171
00172
00173 virtual void
00174 getChildren( List &outChildren ) const throw(Error);
00175
00176
00177 protected:
00178
00179
00180
00181
00182
00183 void
00184 setChildren(const List & inSource) throw(Error);
00185
00186 virtual void
00187 onAutoBlast() const throw(Error);
00188
00189 public:
00190
00191
00192
00193
00194
00195 virtual void
00196 getCreatedChildren( List &outChildren ) const throw(Error);
00197
00198 protected:
00199
00200
00201
00202
00203
00204 virtual void
00205 onChildCreate( const boost::shared_ptr<ChildType> &inCreatedChild
00206 ) const throw(Error);
00207
00208 public:
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 inline void
00219 constructChildren(
00220 const boost::shared_ptr<ChildFactory> & inFactory,
00221 const std::vector<SizeType> &inLimits) throw(Error);
00222
00223
00224 private:
00225 inline void
00226 autoBlast() const throw(Error);
00227
00228 void
00229 incrementIndices( std::vector<SizeType> &indices,
00230 const std::vector<SizeType> &limits ) const throw();
00231
00232
00233 inline SizeType
00234 indicesToAbsoluteIndex(
00235 const std::vector<SizeType> &inIndices ) const throw();
00236
00237 inline SizeType
00238 storageSize() const;
00239
00240 public:
00241
00242
00243
00244
00245
00246 inline void
00247 getLimits(std::vector<SizeType> &outLimits) const throw();
00248
00249 inline bool
00250 getIsPreserved() const throw();
00251
00252 protected:
00253
00254
00255
00256
00257
00258 void
00259 setLimits(const std::vector<SizeType> & inSource) throw();
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 inline const boost::shared_ptr<ChildFactory>
00280 getFactory() const throw();
00281
00282
00283
00284
00285
00286
00287 void
00288 setFactory(const boost::shared_ptr<ChildFactory> & inSource) throw();
00289
00290
00291 private:
00292 #ifdef GENOM_SERIALIZATION
00293 template<class Archive> void
00294 load( Archive &ar, unsigned int );
00295
00296 template<class Archive> void
00297 save( Archive &ar, unsigned int ) const;
00298
00299 BOOST_SERIALIZATION_SPLIT_MEMBER()
00300 #endif //GENOM_SERIALIZATION
00301
00302 std::vector<SizeType> mLimits;
00303 mutable List mChildren;
00304 mutable SparseElements mSparseElements;
00305 boost::shared_ptr<ChildFactory> mFactory;
00306 bool mIsPreserved;
00307 SizeType mPreservationThreshold;
00308
00309 Vector(const Vector<_Type, _ChildType, _ChildFactoryType, cPreserve> & source) throw();
00310
00311 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve> &
00312 operator=(const Vector<_Type, _ChildType, _ChildFactoryType, cPreserve> & source) throw();
00313
00314 };
00315
00316 template<
00317 typename _Type,
00318 typename _ChildType,
00319 typename _ChildFactoryType,
00320 bool cPreserve>
00321 Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::~Vector() throw() {
00322 }
00323
00324 template<
00325 typename _Type,
00326 typename _ChildType,
00327 typename _ChildFactoryType,
00328 bool cPreserve>
00329 Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::Vector()
00330 :BaseType(),
00331 mLimits(),
00332 mChildren(),
00333 mFactory(),
00334 mIsPreserved( cPreserve ),
00335 mPreservationThreshold( 1024 ) {
00336 }
00337
00338
00339
00340
00341
00342
00343 template<
00344 typename _Type,
00345 typename _ChildType,
00346 typename _ChildFactoryType,
00347 bool cPreserve>
00348 CompositionType
00349 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::getCompositionType() const throw() {
00350 return eCompositionTypeVector;
00351 }
00352
00353
00354
00355
00356
00357 template<
00358 typename _Type,
00359 typename _ChildType,
00360 typename _ChildFactoryType,
00361 bool cPreserve>
00362 typename Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::SizeType
00363 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::getSize() const throw()
00364 {
00365 return storageSize();
00366 }
00367
00368 #if 0
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 template<
00379 typename _Type,
00380 typename _ChildType,
00381 typename _ChildFactoryType,
00382 bool cPreserve>
00383 void
00384 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::addChild(
00385 const boost::shared_ptr<Type> & inChild,
00386 const std::vector<SizeType> & inIndices) throw(Error) {
00387
00388
00389 if( inIndices.size() > mLimits.size() )
00390 {
00391
00392 }
00393 if( cPreserve && mChildren.empty() )
00394 {
00395 try
00396 {
00397 autoBlast();
00398 }
00399 catch(Error &e)
00400 {
00401 e.setCurrentLocation(
00402 __FUNCTION__, __FILE__, __LINE__ );
00403 throw;
00404 }
00405 }
00406 }
00407
00408 #endif
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 template<
00422 typename _Type,
00423 typename _ChildType,
00424 typename _ChildFactoryType,
00425 bool cPreserve>
00426 const typename Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::Pointer
00427 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::get(
00428 const std::vector<SizeType> &inIndices) const throw(Error) {
00429 if( inIndices.size() != mLimits.size() )
00430 {
00431 Error e( eMessageIdErrorArrayIndexSizeMismatch,
00432 __FUNCTION__, __FILE__, __LINE__ );
00433 e.saveContextData("Array Index", inIndices.size());
00434 e.saveContextData("Array Dimension", mLimits.size());
00435 throw e;
00436 }
00437 else
00438 {
00439 typename std::vector<SizeType>::const_iterator lend = mLimits.end();
00440 typename std::vector<SizeType>::const_iterator limit
00441 = mLimits.begin();
00442 typename std::vector<SizeType>::const_iterator index
00443 = inIndices.begin();
00444 for(; limit != lend; ++limit, ++index )
00445 {
00446 if( *index >= *limit )
00447 {
00448 Error e( eMessageIdErrorArrayIndexOutOfBounds,
00449 __FUNCTION__, __FILE__, __LINE__ );
00450 e.saveContextData("Array Index", *index );
00451 e.saveContextData("Array Dimension", *limit );
00452 throw e;
00453 }
00454 }
00455 }
00456
00457 SizeType index = indicesToAbsoluteIndex( inIndices );
00458
00459 Pointer thisPtr = BaseType::getSharedThis();
00460 boost::shared_ptr<ChildFactory> factory = getFactory();
00461 if( !factory )
00462 {
00463 Error e( eMessageIdErrorNullChildfactory,
00464 __FUNCTION__, __FILE__, __LINE__ );
00465 e.saveContextData("Null Child Factory", factory);
00466 throw e;
00467 }
00468
00469 Pointer child;
00470 if( cPreserve && mChildren.empty() )
00471 {
00472 if( false == mSparseElements.get( index, child ) )
00473 {
00474 ChildPointer newChild;
00475 try
00476 {
00477 factory->create( newChild );
00478 newChild->setParentCollection( thisPtr );
00479 newChild->setIndices( inIndices );
00480 newChild->setAbsoluteIndex( index );
00481 mSparseElements.set( index, newChild );
00482 child = newChild;
00483 onChildCreate( newChild );
00484 }
00485 catch(Error &e)
00486 {
00487 e.setCurrentLocation(
00488 __FUNCTION__, __FILE__, __LINE__ );
00489 throw;
00490 }
00491 }
00492
00493 }
00494 else
00495 {
00496 child = mChildren[ index ];
00497 }
00498
00499 return child;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509 template<
00510 typename _Type,
00511 typename _ChildType,
00512 typename _ChildFactoryType,
00513 bool cPreserve>
00514 void
00515 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::getChildren(
00516 typename Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::List &outChildren
00517 ) const throw(Error) {
00518 if( cPreserve
00519 && !mLimits.empty()
00520 && mChildren.empty() )
00521 {
00522 try
00523 {
00524 autoBlast();
00525 }
00526 catch(Error &e)
00527 {
00528 e.setCurrentLocation(
00529 __FUNCTION__, __FILE__, __LINE__ );
00530 throw;
00531 }
00532 }
00533 outChildren.insert( outChildren.end(),
00534 mChildren.begin(), mChildren.end() );
00535 return;
00536 }
00537
00538
00539
00540
00541
00542
00543 template<
00544 typename _Type,
00545 typename _ChildType,
00546 typename _ChildFactoryType,
00547 bool cPreserve>
00548 void
00549 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::setChildren(
00550 const Vector::List & inSource) throw(Error) {
00551 mChildren = inSource;
00552 }
00553
00554 template<
00555 typename _Type,
00556 typename _ChildType,
00557 typename _ChildFactoryType,
00558 bool cPreserve>
00559 void
00560 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::onAutoBlast() const throw(Error)
00561 {
00562
00563
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 template<
00577 typename _Type,
00578 typename _ChildType,
00579 typename _ChildFactoryType,
00580 bool cPreserve>
00581 inline void
00582 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::constructChildren(
00583 const boost::shared_ptr<ChildFactory> & inFactory,
00584 const std::vector<SizeType> &inLimits) throw(Error) {
00585 if( inLimits.empty() )
00586 {
00587 Error e( eMessageIdErrorEmptyArray,
00588 __FUNCTION__, __FILE__, __LINE__ );
00589 e.saveContextData("Empty Array,", inLimits.empty());
00590 throw e;
00591 }
00592 else
00593 {
00594 typename std::vector<SizeType>::const_iterator index
00595 = inLimits.begin();
00596 typename std::vector<SizeType>::const_iterator lend
00597 = inLimits.end();
00598 for(; index != lend; index++ )
00599 {
00600 if( *index == 0 )
00601 {
00602 Error e( eMessageIdErrorEmptyArray,
00603 __FUNCTION__, __FILE__, __LINE__ );
00604 e.saveContextData("Empty Array,", *index);
00605 throw e;
00606 }
00607 }
00608 }
00609
00610 setFactory( inFactory );
00611 setLimits( inLimits );
00612 if( !cPreserve )
00613 {
00614 try
00615 {
00616 autoBlast();
00617 }
00618 catch(Error &e)
00619 {
00620 e.setCurrentLocation(
00621 __FUNCTION__, __FILE__, __LINE__);
00622 throw;
00623 }
00624 }
00625 }
00626
00627 template<
00628 typename _Type,
00629 typename _ChildType,
00630 typename _ChildFactoryType,
00631 bool cPreserve>
00632 inline void
00633 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::autoBlast() const throw(Error) {
00634 SizeType size = storageSize();
00635 mChildren.resize( mChildren.size() + size );
00636 Pointer thisPtr = BaseType::getSharedThis();
00637 std::vector<SizeType> indices( mLimits.size() );
00638 fill( indices.begin(), indices.end(), 0 );
00639 if( !thisPtr )
00640 {
00641 Error e( eMessageIdErrorPointerToItemDoesNotExist,
00642 __FUNCTION__, __FILE__, __LINE__ );
00643 e.saveContextData("Pointer to this object does not exist", thisPtr);
00644 throw e;
00645 }
00646 boost::shared_ptr<ChildFactory> factory = getFactory();
00647 if( !factory )
00648 {
00649 Error e( eMessageIdErrorNullChildfactory,
00650 __FUNCTION__, __FILE__, __LINE__ );
00651 e.saveContextData("Null Child Factory", factory);
00652 throw e;
00653 }
00654 for( SizeType index = 0; index < size; index++ )
00655 {
00656 Pointer child;
00657 bool createNew = ( cPreserve
00658 && mSparseElements.getSize() > 0
00659 && mSparseElements.get( index, child ) )
00660 ? false : true;
00661 if( createNew )
00662 {
00663 ChildPointer newChild;
00664 try
00665 {
00666 factory->create( newChild );
00667 newChild->setParentCollection( thisPtr );
00668 newChild->setIndices( indices );
00669 newChild->setAbsoluteIndex( index );
00670 child = newChild;
00671 onChildCreate( newChild );
00672 }
00673 catch(Error &e)
00674 {
00675 mChildren.clear();
00676 e.setCurrentLocation(
00677 __FUNCTION__, __FILE__, __LINE__ );
00678 throw;
00679 }
00680 }
00681 incrementIndices( indices, mLimits );
00682 mChildren[ index ] = child;
00683 }
00684 mSparseElements.clear();
00685 try
00686 {
00687 onAutoBlast();
00688 }
00689 catch( Error &e )
00690 {
00691 e.setCurrentLocation( __FUNCTION__,
00692 __FILE__, __LINE__ );
00693 throw;
00694 }
00695 }
00696
00697 template<
00698 typename _Type,
00699 typename _ChildType,
00700 typename _ChildFactoryType,
00701 bool cPreserve>
00702 void
00703 Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::getCreatedChildren(
00704 List &outChildren ) const throw(Error) {
00705 if( cPreserve && mChildren.empty() )
00706 {
00707 mSparseElements.getValues( outChildren );
00708 }
00709 else if( !mChildren.empty() )
00710 {
00711 try
00712 {
00713 getChildren( outChildren );
00714 }
00715 catch( Error &e )
00716 {
00717 e.setCurrentLocation(
00718 __FUNCTION__, __FILE__, __LINE__ );
00719 throw;
00720 }
00721 }
00722 return;
00723 }
00724
00725 template<
00726 typename _Type,
00727 typename _ChildType,
00728 typename _ChildFactoryType,
00729 bool cPreserve>
00730 void
00731 Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::onChildCreate(
00732 const boost::shared_ptr<ChildType> &inCreatedChild) const throw(Error) {
00733
00734 }
00735
00736 template<
00737 typename _Type,
00738 typename _ChildType,
00739 typename _ChildFactoryType,
00740 bool cPreserve>
00741 void
00742 Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::incrementIndices(
00743 std::vector<SizeType> &indices,
00744 const std::vector<SizeType> &limits ) const throw()
00745 {
00746 SizeType size = limits.size();
00747 bool incr = false;
00748 for( SizeType i = 0; i < size; i++ )
00749 {
00750 if( i == 0 || incr )
00751 {
00752 ++indices[i];
00753 if( indices[i] == limits[i] )
00754 {
00755 indices[i] = 0;
00756 incr = true;
00757 }
00758 else
00759 {
00760 incr = false;
00761 }
00762 }
00763 }
00764 }
00765
00766 template<
00767 typename _Type,
00768 typename _ChildType,
00769 typename _ChildFactoryType,
00770 bool cPreserve>
00771 inline typename Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::SizeType
00772 Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::indicesToAbsoluteIndex(
00773 const std::vector<SizeType> &inIndices ) const throw()
00774 {
00775 SizeType idx = 0;
00776 SizeType size = mLimits.size();
00777 for( SizeType k = 1; k <= size; k++ )
00778 {
00779 SizeType prod = 1;
00780 for(SizeType l = k+1; l <= size; l++ )
00781 {
00782 prod *= mLimits[ l - 1 ];
00783 }
00784 idx += prod * inIndices[ k - 1 ];
00785 }
00786 return idx;
00787 }
00788
00789 template<
00790 typename _Type,
00791 typename _ChildType,
00792 typename _ChildFactoryType,
00793 bool cPreserve>
00794 inline typename Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::SizeType
00795 Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::storageSize(
00796 ) const
00797 {
00798 return std::accumulate(
00799 mLimits.begin(), mLimits.end(), 1,
00800 std::multiplies<typename Vector<_Type,_ChildType,_ChildFactoryType,cPreserve>::SizeType>() );
00801 }
00802
00803
00804
00805
00806
00807
00808 template<
00809 typename _Type,
00810 typename _ChildType,
00811 typename _ChildFactoryType,
00812 bool cPreserve>
00813 inline void
00814 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::getLimits(
00815 std::vector<SizeType> &outLimits) const throw() {
00816 outLimits.insert( outLimits.end(),
00817 mLimits.begin(), mLimits.end() );
00818 }
00819
00820 template<
00821 typename _Type,
00822 typename _ChildType,
00823 typename _ChildFactoryType,
00824 bool cPreserve>
00825 inline bool
00826 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::getIsPreserved() const throw()
00827 {
00828 return mIsPreserved;
00829 }
00830
00831
00832
00833
00834
00835
00836 template<
00837 typename _Type,
00838 typename _ChildType,
00839 typename _ChildFactoryType,
00840 bool cPreserve>
00841 void
00842 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::setLimits(
00843 const std::vector<SizeType> & inSource) throw() {
00844 mLimits = inSource;
00845 }
00846
00847
00848
00849
00850
00851
00852 template<
00853 typename _Type,
00854 typename _ChildType,
00855 typename _ChildFactoryType,
00856 bool cPreserve>
00857 inline const boost::shared_ptr<_ChildFactoryType>
00858 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::getFactory() const throw() {
00859 return mFactory;
00860 }
00861
00862
00863
00864
00865
00866
00867 template<
00868 typename _Type,
00869 typename _ChildType,
00870 typename _ChildFactoryType,
00871 bool cPreserve>
00872 void
00873 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::setFactory(
00874 const boost::shared_ptr<Vector::ChildFactory> & inSource) throw() {
00875 mFactory = inSource;
00876 }
00877
00878 #ifdef GENOM_SERIALIZATION
00879 template<
00880 typename _Type,
00881 typename _ChildType,
00882 typename _ChildFactoryType,
00883 bool cPreserve>
00884 template<class Archive> void
00885 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::load(
00886 Archive &ar, unsigned int ) {
00887 ar & boost::serialization::base_object< BaseType >( *this );
00888 ar & mLimits;
00889 ar & mChildren;
00890 ar & mSparseElements;
00891 ar & mIsPreserved;
00892 ar & mPreservationThreshold;
00893 if( !mChildren.empty() )
00894 {
00895 for_each( mChildren.begin(), mChildren.end(),
00896 boost::bind( boost::mem_fn(
00897 &ChildType::setParentCollection ), _1,
00898 SelfReferencing<_Type>::getSharedThis() ));
00899 }
00900 else
00901 {
00902 mSparseElements.applyOnAll(
00903 boost::bind( boost::mem_fn(
00904 &ChildType::setParentCollection ), _1,
00905 SelfReferencing<_Type>::getSharedThis() ));
00906 }
00907 }
00908
00909 template<
00910 typename _Type,
00911 typename _ChildType,
00912 typename _ChildFactoryType,
00913 bool cPreserve>
00914 template<class Archive> void
00915 Vector<_Type, _ChildType, _ChildFactoryType, cPreserve>::save(
00916 Archive &ar, unsigned int ) const {
00917 ar & boost::serialization::base_object< BaseType >( *this );
00918 ar & mLimits;
00919 ar & mChildren;
00920 ar & mSparseElements;
00921 ar & mIsPreserved;
00922 ar & mPreservationThreshold;
00923 }
00924
00925 #endif //GENOM_SERIALIZATION
00926
00927 }
00928
00929 }
00930 #endif // TORC_GENERIC_OM_VECTOR_HPP