00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef SC_VECTOR_H_INCLUDED_
00028 #define SC_VECTOR_H_INCLUDED_
00029
00030 #include <vector>
00031 #include <iterator>
00032 #include <string>
00033 #include <algorithm>
00034
00035 #include "sysc/kernel/sc_object.h"
00036 #include "sysc/packages/boost/config.hpp"
00037 #include "sysc/packages/boost/utility/enable_if.hpp"
00038
00039
00040
00041 namespace sc_core {
00042 namespace sc_meta {
00043
00044 using ::sc_boost::enable_if;
00045
00046
00047 template< typename T > struct remove_const { typedef T type; };
00048 template< typename T > struct remove_const<const T> { typedef T type; };
00049
00050 template< typename T, typename U >
00051 struct is_same { SC_BOOST_STATIC_CONSTANT( bool, value = false ); };
00052 template< typename T >
00053 struct is_same<T,T> { SC_BOOST_STATIC_CONSTANT( bool, value = true ); };
00054
00055 template< typename T >
00056 struct is_const { SC_BOOST_STATIC_CONSTANT( bool, value = false ); };
00057 template< typename T >
00058 struct is_const< const T> { SC_BOOST_STATIC_CONSTANT( bool, value = true ); };
00059
00060 template< typename CT, typename T >
00061 struct is_more_const {
00062 SC_BOOST_STATIC_CONSTANT( bool, value
00063 = ( is_same< typename remove_const<CT>::type
00064 , typename remove_const<T>::type
00065 >::value
00066 && ( is_const<CT>::value >= is_const<T>::value ) ) );
00067 };
00068
00069 struct special_result {};
00070 template< typename T > struct remove_special_fptr {};
00071 template< typename T >
00072 struct remove_special_fptr< special_result& (*)( T ) >
00073 { typedef T type; };
00074
00075 #define SC_RPTYPE_(Type) \
00076 typename ::sc_core::sc_meta::remove_special_fptr \
00077 < ::sc_core::sc_meta::special_result& (*) Type >::type
00078
00079 #define SC_ENABLE_IF_( Cond ) \
00080 typename ::sc_core::sc_meta::enable_if \
00081 < SC_RPTYPE_(Cond) >::type * = NULL
00082
00083 }
00084
00085
00086 template< typename T > class sc_vector;
00087 template< typename T, typename MT > class sc_vector_assembly;
00088 template< typename T, typename MT > class sc_vector_iter;
00089
00090
00091 template< typename Container, typename ArgumentIterator >
00092 typename Container::iterator
00093 sc_vector_do_bind( Container & cont
00094 , ArgumentIterator first
00095 , ArgumentIterator last
00096 , typename Container::iterator from );
00097
00098
00099 template< typename Container, typename ArgumentIterator >
00100 typename Container::iterator
00101 sc_vector_do_operator_paren( Container & cont
00102 , ArgumentIterator first
00103 , ArgumentIterator last
00104 , typename Container::iterator from );
00105
00106 class sc_vector_base
00107 : public sc_object
00108 {
00109
00110 template<typename,typename> friend class sc_vector_assembly;
00111 template<typename,typename> friend class sc_vector_iter;
00112
00113 public:
00114
00115 typedef std::vector< void* > storage_type;
00116 typedef storage_type::size_type size_type;
00117 typedef storage_type::difference_type difference_type;
00118
00119 const char * kind() const { return "sc_vector"; }
00120
00121 std::vector<sc_object*> const & get_elements() const;
00122
00123 size_type size() const
00124 { return vec_.size(); }
00125
00126 protected:
00127
00128
00129
00130 typedef storage_type::iterator iterator;
00131 typedef storage_type::const_iterator const_iterator;
00132
00133 sc_vector_base();
00134
00135 sc_vector_base( const char* prefix )
00136 : sc_object( prefix )
00137 , vec_()
00138 , objs_vec_(0)
00139 {}
00140
00141 ~sc_vector_base()
00142 { delete objs_vec_; }
00143
00144 void * & at( size_type i )
00145 { return vec_[i]; }
00146
00147 void const * at( size_type i ) const
00148 { return vec_[i]; }
00149
00150 void reserve( size_type n )
00151 { vec_.reserve(n); }
00152
00153 void clear()
00154 { vec_.clear(); }
00155
00156 void push_back( void* item )
00157 { vec_.push_back(item); }
00158
00159 void check_index( size_type i ) const;
00160 bool check_init( size_type n ) const;
00161
00162 static std::string make_name( const char* prefix, size_type index );
00163
00164 iterator begin() { return vec_.begin(); }
00165 iterator end() { return vec_.end(); }
00166
00167 const_iterator begin() const { return vec_.begin(); }
00168 const_iterator end() const { return vec_.end(); }
00169
00170 virtual sc_object* object_cast( void* ) const = 0;
00171
00172 sc_object* implicit_cast( sc_object* p ) const { return p; }
00173 sc_object* implicit_cast( ... ) const;
00174
00175 public:
00176
00177 void report_empty_bind( const char* kind_, bool dst_range_ ) const;
00178
00179 private:
00180 storage_type vec_;
00181 mutable std::vector< sc_object* >* objs_vec_;
00182
00183
00184 sc_vector_base( const sc_vector_base& );
00185 sc_vector_base& operator=( const sc_vector_base& );
00186
00187 };
00188
00189
00190 template< typename ElementType >
00191 struct sc_direct_access
00192 {
00193 typedef ElementType element_type;
00194 typedef element_type type;
00195 typedef typename sc_meta::remove_const<type>::type plain_type;
00196
00197 typedef sc_direct_access< type > policy;
00198 typedef sc_direct_access< plain_type > non_const_policy;
00199 typedef sc_direct_access< const plain_type > const_policy;
00200
00201 sc_direct_access(){}
00202 sc_direct_access( const non_const_policy& ) {}
00203
00204 template<typename U>
00205 sc_direct_access( const U&
00206 , SC_ENABLE_IF_((
00207 sc_meta::is_more_const<type,typename U::policy::element_type>
00208 )) )
00209 {}
00210
00211 type* get( type* this_ ) const
00212 { return this_; }
00213 };
00214
00215
00216 template< typename ElementType
00217 , typename AccessType >
00218 class sc_member_access
00219 {
00220 public:
00221 template< typename, typename > friend class sc_member_access;
00222
00223 typedef ElementType element_type;
00224 typedef AccessType access_type;
00225 typedef access_type (ElementType::*member_type);
00226 typedef access_type type;
00227 typedef typename sc_meta::remove_const<type>::type plain_type;
00228 typedef typename sc_meta::remove_const<ElementType>::type plain_elem_type;
00229
00230 typedef sc_member_access< element_type, access_type > policy;
00231 typedef sc_member_access< plain_elem_type, plain_type >
00232 non_const_policy;
00233 typedef sc_member_access< const plain_elem_type, const plain_type >
00234 const_policy;
00235
00236 sc_member_access( member_type ptr )
00237 : ptr_(ptr) {}
00238
00239 sc_member_access( const non_const_policy& other )
00240 : ptr_(other.ptr_)
00241 {}
00242
00243 access_type * get( element_type* this_ ) const
00244 { return &(this_->*ptr_); }
00245
00246 private:
00247 member_type ptr_;
00248 };
00249
00250
00251 template< typename ElementType
00252 , typename AccessPolicy = sc_direct_access<ElementType> >
00253 class sc_vector_iter
00254 : public std::iterator< std::random_access_iterator_tag
00255 , typename AccessPolicy::type >
00256 , private AccessPolicy
00257 {
00258 typedef ElementType element_type;
00259 typedef typename AccessPolicy::policy access_policy;
00260 typedef typename AccessPolicy::non_const_policy non_const_policy;
00261 typedef typename AccessPolicy::const_policy const_policy;
00262 typedef typename access_policy::type access_type;
00263
00264 typedef typename sc_meta::remove_const<ElementType>::type plain_type;
00265 typedef const plain_type const_plain_type;
00266
00267 friend class sc_vector< plain_type >;
00268 template< typename, typename > friend class sc_vector_assembly;
00269 template< typename, typename > friend class sc_vector_iter;
00270
00271 typedef std::iterator< std::random_access_iterator_tag, access_type > base_type;
00272 typedef sc_vector_iter this_type;
00273 typedef sc_vector<plain_type> vector_type;
00274 typedef sc_vector_base::storage_type storage_type;
00275
00276
00277 template< typename U > struct select_iter
00278 { typedef typename storage_type::iterator type; };
00279 template< typename U > struct select_iter< const U >
00280 { typedef typename storage_type::const_iterator type; };
00281
00282 typedef typename select_iter<ElementType>::type raw_iterator;
00283 typedef sc_vector_iter< const_plain_type, const_policy > const_iterator;
00284
00285
00286
00287 raw_iterator it_;
00288
00289 sc_vector_iter( raw_iterator it, access_policy acc = access_policy() )
00290 : access_policy(acc), it_(it) {}
00291
00292 access_policy const & get_policy() const { return *this; }
00293
00294 public:
00295
00296
00297
00298 typedef typename base_type::difference_type difference_type;
00299 typedef typename base_type::reference reference;
00300 typedef typename base_type::pointer pointer;
00301
00302 sc_vector_iter() : access_policy(), it_() {}
00303
00304
00305 template< typename OtherElement, typename OtherPolicy >
00306 sc_vector_iter( const sc_vector_iter<OtherElement, OtherPolicy>& it
00307 , SC_ENABLE_IF_((
00308 sc_meta::is_more_const< element_type
00309 , typename OtherPolicy::element_type >
00310 ))
00311 )
00312 : access_policy( it.get_policy() ), it_( it.it_ )
00313 {}
00314
00315
00316 this_type& operator++(){ ++it_; return *this; }
00317 this_type& operator--(){ --it_; return *this; }
00318 this_type operator++(int){ this_type old(*this); ++it_; return old; }
00319 this_type operator--(int){ this_type old(*this); --it_; return old; }
00320
00321
00322 this_type operator+( difference_type n ) const
00323 { return this_type( it_ + n, get_policy()); }
00324 this_type operator-( difference_type n ) const
00325 { return this_type( it_ - n, get_policy()); }
00326
00327 this_type& operator+=( difference_type n ) { it_+=n; return *this; }
00328 this_type& operator-=( difference_type n ) { it_-=n; return *this; }
00329
00330
00331 bool operator== ( const this_type& that ) const { return it_ == that.it_; }
00332 bool operator!= ( const this_type& that ) const { return it_ != that.it_; }
00333 bool operator<= ( const this_type& that ) const { return it_ <= that.it_; }
00334 bool operator>= ( const this_type& that ) const { return it_ >= that.it_; }
00335 bool operator< ( const this_type& that ) const { return it_ < that.it_; }
00336 bool operator> ( const this_type& that ) const { return it_ > that.it_; }
00337
00338
00339 reference operator*() const
00340 { return *access_policy::get( static_cast<element_type*>(*it_) ); }
00341 pointer operator->() const
00342 { return access_policy::get( static_cast<element_type*>(*it_) ); }
00343 reference operator[]( difference_type n ) const
00344 { return *access_policy::get( static_cast<element_type*>(it_[n]) ); }
00345
00346
00347 difference_type operator-( this_type const& that ) const
00348 { return it_-that.it_; }
00349
00350 };
00351
00352 template< typename T >
00353 class sc_vector
00354 : public sc_vector_base
00355 {
00356 typedef sc_vector_base base_type;
00357 typedef sc_vector<T> this_type;
00358
00359 public:
00360 typedef T element_type;
00361 typedef sc_vector_iter< element_type > iterator;
00362 typedef sc_vector_iter< const element_type > const_iterator;
00363
00364 sc_vector(){}
00365
00366 explicit sc_vector( const char* prefix )
00367 : base_type( prefix )
00368 {}
00369
00370 explicit sc_vector( const char* prefix, size_type n )
00371 : base_type( prefix )
00372 { init(n); }
00373
00374 template< typename Creator >
00375 sc_vector( const char* prefix, size_type n, Creator creator )
00376 : base_type( prefix )
00377 {
00378 init( n, creator );
00379 }
00380
00381 virtual ~sc_vector();
00382
00383 element_type& operator[]( size_type i )
00384 { return *static_cast<element_type*>( base_type::at(i) ); }
00385
00386 element_type& at( size_type i )
00387 { check_index(i); return (*this)[i]; }
00388
00389 const element_type& operator[]( size_type i ) const
00390 { return *static_cast<element_type const *>( base_type::at(i) ); }
00391
00392 const element_type& at( size_type i ) const
00393 { check_index(i); return (*this)[i]; }
00394
00395 void init( size_type n )
00396 { init( n, &this_type::create_element ); }
00397
00398 template< typename Creator >
00399 void init( size_type n, Creator c );
00400
00401 static element_type * create_element( const char* prefix, size_type index );
00402
00403 iterator begin() { return base_type::begin(); }
00404 iterator end() { return base_type::end(); }
00405
00406 const_iterator begin() const { return base_type::begin(); }
00407 const_iterator end() const { return base_type::end(); }
00408
00409 const_iterator cbegin() const { return base_type::begin(); }
00410 const_iterator cend() const { return base_type::end(); }
00411
00412 template< typename ContainerType, typename ArgumentType >
00413 iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c )
00414 { return bind( c.begin(), c.end() ); }
00415
00416 template< typename BindableContainer >
00417 iterator bind( BindableContainer & c )
00418 { return bind( c.begin(), c.end() ); }
00419
00420 template< typename BindableIterator >
00421 iterator bind( BindableIterator first, BindableIterator last )
00422 { return bind( first, last, this->begin() ); }
00423
00424 template< typename BindableIterator >
00425 iterator bind( BindableIterator first, BindableIterator last
00426 , iterator from )
00427 { return sc_vector_do_bind( *this, first, last, from ); }
00428
00429 template< typename ContainerType, typename ArgumentType >
00430 iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c )
00431 { return operator()( c.begin(), c.end() ); }
00432
00433 template< typename ArgumentContainer >
00434 iterator operator()( ArgumentContainer & c )
00435 { return operator()( c.begin(), c.end() ); }
00436
00437 template< typename ArgumentIterator >
00438 iterator operator()( ArgumentIterator first, ArgumentIterator last )
00439 { return operator()( first, last, this->begin() ); }
00440
00441 template< typename ArgumentIterator >
00442 iterator operator()( ArgumentIterator first, ArgumentIterator last
00443 , iterator from )
00444 { return sc_vector_do_operator_paren( *this, first, last, from ); }
00445
00446
00447
00448 template< typename MT >
00449 sc_vector_assembly<T,MT> assemble( MT (T::*member_ptr) )
00450 { return sc_vector_assembly<T,MT>( *this, member_ptr ); }
00451
00452 protected:
00453
00454 void clear();
00455
00456 virtual sc_object* object_cast( void* p ) const
00457 { return implicit_cast( static_cast<element_type*>(p) ); }
00458
00459 };
00460
00461 template< typename T, typename MT >
00462 class sc_vector_assembly
00463 {
00464 template< typename U > friend class sc_vector;
00465
00466 public:
00467
00468 typedef sc_vector<T> base_type;
00469
00470 typedef sc_vector_iter< T, sc_member_access<T, MT> > iterator;
00471 typedef sc_vector_iter< const T
00472 , sc_member_access<const T, const MT> > const_iterator;
00473
00474 typedef T element_type;
00475 typedef MT access_type;
00476
00477 typedef typename base_type::size_type size_type;
00478 typedef typename base_type::difference_type difference_type;
00479 typedef typename iterator::reference reference;
00480 typedef typename iterator::pointer pointer;
00481 typedef typename const_iterator::reference const_reference;
00482 typedef typename const_iterator::pointer const_pointer;
00483
00484
00485 typedef access_type (T::*member_type);
00486
00487 const char* name() const { return vec_->name(); }
00488 const char* kind() const { return "sc_vector_assembly"; }
00489
00490 iterator begin()
00491 { return iterator( (*vec_).begin().it_, ptr_ ); }
00492 iterator end()
00493 { return iterator( (*vec_).end().it_, ptr_ ); }
00494
00495 const_iterator cbegin() const
00496 { return const_iterator( (*vec_).cbegin().it_, ptr_ ); }
00497 const_iterator cend() const
00498 { return const_iterator( (*vec_).cend().it_, ptr_ ); }
00499
00500 const_iterator begin() const
00501 { return const_iterator( (*vec_).begin().it_, ptr_ ); }
00502 const_iterator end() const
00503 { return const_iterator( (*vec_).end().it_, ptr_ ); }
00504
00505 size_type size() const { return vec_->size(); }
00506 const std::vector< sc_object* > & get_elements() const;
00507
00508 reference operator[]( size_type idx )
00509 { return (*vec_)[idx].*ptr_; }
00510 reference at( size_type idx )
00511 { return vec_->at(idx).*ptr_; }
00512 const_reference operator[]( size_type idx ) const
00513 { return (*vec_)[idx].*ptr_; }
00514 const_reference at( size_type idx ) const
00515 { return vec_->at(idx).*ptr_; }
00516
00517 template< typename ContainerType, typename ArgumentType >
00518 iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c )
00519 { return bind( c.begin(), c.end() ); }
00520
00521 template< typename BindableContainer >
00522 iterator bind( BindableContainer & c )
00523 { return bind( c.begin(), c.end() ); }
00524
00525 template< typename BindableIterator >
00526 iterator bind( BindableIterator first, BindableIterator last )
00527 { return bind( first, last, this->begin() ); }
00528
00529 template< typename BindableIterator >
00530 iterator bind( BindableIterator first, BindableIterator last
00531 , iterator from )
00532 { return sc_vector_do_bind( *this, first, last, from ); }
00533
00534 template< typename BindableIterator >
00535 iterator bind( BindableIterator first, BindableIterator last
00536 , typename base_type::iterator from )
00537 { return bind( first, last, iterator(from.it_, ptr_) ); }
00538
00539 template< typename ContainerType, typename ArgumentType >
00540 iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c )
00541 { return operator()( c.begin(), c.end() ); }
00542
00543 template< typename ArgumentContainer >
00544 iterator operator()( ArgumentContainer & c )
00545 { return operator()( c.begin(), c.end() ); }
00546
00547 template< typename ArgumentIterator >
00548 iterator operator()( ArgumentIterator first, ArgumentIterator last )
00549 { return operator()( first, last, this->begin() ); }
00550
00551 template< typename ArgumentIterator >
00552 iterator operator()( ArgumentIterator first, ArgumentIterator last
00553 , iterator from )
00554 { return sc_vector_do_operator_paren( *this, first, last, from ); }
00555
00556 template< typename ArgumentIterator >
00557 iterator operator()( ArgumentIterator first, ArgumentIterator last
00558 , typename base_type::iterator from )
00559 { return operator()( first, last, iterator(from.it_, ptr_) ); }
00560
00561 sc_vector_assembly( const sc_vector_assembly & other )
00562 : vec_( other.vec_ )
00563 , ptr_( other.ptr_ )
00564 , child_vec_(0)
00565 {}
00566
00567 sc_vector_assembly& operator=( sc_vector_assembly other_copy )
00568 {
00569 swap( other_copy );
00570 return *this;
00571 }
00572
00573 void swap( sc_vector_assembly & that )
00574 {
00575 using std::swap;
00576 swap( vec_, that.vec_ );
00577 swap( ptr_, that.ptr_ );
00578 swap( child_vec_, that.child_vec_ );
00579 }
00580
00581 void report_empty_bind( const char* kind_, bool dst_empty_ ) const
00582 { vec_->report_empty_bind( kind_, dst_empty_ ); }
00583
00584 ~sc_vector_assembly()
00585 { delete child_vec_; }
00586
00587 private:
00588
00589 sc_vector_assembly( base_type & v, member_type ptr )
00590 : vec_(&v)
00591 , ptr_(ptr)
00592 , child_vec_(0)
00593 {}
00594
00595 sc_object* object_cast( pointer p ) const
00596 { return vec_->implicit_cast( p ); }
00597
00598 base_type * vec_;
00599 member_type ptr_;
00600
00601 mutable std::vector< sc_object* >* child_vec_;
00602 };
00603
00604 template< typename T, typename MT >
00605 sc_vector_assembly<T,MT>
00606 sc_assemble_vector( sc_vector<T> & vec, MT (T::*ptr) )
00607 {
00608 return vec.assemble( ptr );
00609 }
00610
00611 template< typename T >
00612 typename sc_vector<T>::element_type *
00613 sc_vector<T>::create_element( const char* name, size_type )
00614 {
00615 return new T( name );
00616 }
00617
00618 template< typename T >
00619 template< typename Creator >
00620 void
00621 sc_vector<T>::init( size_type n, Creator c )
00622 {
00623 if ( base_type::check_init(n) )
00624 {
00625 base_type::reserve( n );
00626 try
00627 {
00628 for ( size_type i = 0; i<n; ++i )
00629 {
00630
00631 std::string name = make_name( basename(), i );
00632 const char* cname = name.c_str();
00633
00634 void* p = c( cname, i ) ;
00635 base_type::push_back(p);
00636 }
00637 }
00638 catch ( ... )
00639 {
00640 clear();
00641 throw;
00642 }
00643 }
00644 }
00645
00646 template< typename T >
00647 void
00648 sc_vector<T>::clear()
00649 {
00650 size_type i = size();
00651 while ( i --> 0 )
00652 {
00653 delete &( (*this)[i] );
00654 base_type::at(i) = 0;
00655 }
00656 base_type::clear();
00657 }
00658
00659 template< typename Container, typename ArgumentIterator >
00660 typename Container::iterator
00661 sc_vector_do_bind( Container & cont
00662 , ArgumentIterator first
00663 , ArgumentIterator last
00664 , typename Container::iterator from )
00665 {
00666 typename Container::iterator end = cont.end();
00667
00668 if( !cont.size() || from == end || first == last )
00669 cont.report_empty_bind( cont.kind(), from == end );
00670
00671 while( from!=end && first != last )
00672 (*from++).bind( *first++ );
00673 return from;
00674 }
00675
00676 template< typename Container, typename ArgumentIterator >
00677 typename Container::iterator
00678 sc_vector_do_operator_paren( Container& cont
00679 , ArgumentIterator first
00680 , ArgumentIterator last
00681 , typename Container::iterator from )
00682 {
00683 typename Container::iterator end = cont.end();
00684
00685 if( !cont.size() || from == end || first == last )
00686 cont.report_empty_bind( cont.kind(), from == end );
00687
00688 while( from!=end && first != last )
00689 (*from++)( *first++ );
00690 return from;
00691 }
00692
00693 template< typename T >
00694 sc_vector<T>::~sc_vector()
00695 {
00696 clear();
00697 }
00698
00699 template< typename T, typename MT >
00700 std::vector< sc_object* > const &
00701 sc_vector_assembly<T,MT>::get_elements() const
00702 {
00703 if( !child_vec_ )
00704 child_vec_ = new std::vector< sc_object* >;
00705
00706 if( child_vec_->size() || !size() )
00707 return *child_vec_;
00708
00709 child_vec_->reserve( size() );
00710 for( const_iterator it=begin(); it != end(); ++it )
00711 if( sc_object * obj = object_cast( const_cast<MT*>(&*it) ) )
00712 child_vec_->push_back( obj );
00713
00714 return *child_vec_;
00715 }
00716
00717 }
00718 #undef SC_RPTYPE_
00719 #undef SC_ENABLE_IF_
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749 #endif // SC_VECTOR_H_INCLUDED_
00750