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