summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/utils/sc_vector.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/utils/sc_vector.h')
-rw-r--r--ext/systemc/src/sysc/utils/sc_vector.h724
1 files changed, 724 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/utils/sc_vector.h b/ext/systemc/src/sysc/utils/sc_vector.h
new file mode 100644
index 000000000..2afbaf45e
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_vector.h
@@ -0,0 +1,724 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_vector.h - A vector of named (SystemC) objects (modules, ports, channels)
+
+ Original Author: Philipp A. Hartmann, OFFIS
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_VECTOR_H_INCLUDED_
+#define SC_VECTOR_H_INCLUDED_
+
+#include <vector>
+#include <iterator>
+#include <string>
+#include <algorithm> // std::swap
+
+#include "sysc/kernel/sc_object.h"
+#include <type_traits>
+
+//#define SC_VECTOR_HEADER_ONLY_
+
+namespace sc_core {
+namespace sc_meta {
+
+ using ::std::enable_if;
+ using ::std::remove_const;
+ using ::std::is_same;
+ using ::std::is_const;
+
+ template< typename CT, typename T >
+ struct is_more_const {
+ static constexpr bool value
+ = ( is_same< typename remove_const<CT>::type
+ , typename remove_const<T>::type
+ >::value
+ && ( is_const<CT>::value >= is_const<T>::value ) );
+ };
+
+} // namespace sc_meta
+
+// forward declarations
+template< typename T > class sc_vector;
+template< typename T, typename MT > class sc_vector_assembly;
+template< typename T, typename MT > class sc_vector_iter;
+
+// implementation-defined
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_bind( Container & cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from );
+
+// implementation-defined
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_operator_paren( Container & cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from );
+
+class sc_vector_base
+ : public sc_object
+{
+
+ template<typename,typename> friend class sc_vector_assembly;
+ template<typename,typename> friend class sc_vector_iter;
+
+public:
+
+ typedef std::vector< void* > storage_type;
+ typedef storage_type::size_type size_type;
+ typedef storage_type::difference_type difference_type;
+
+ const char * kind() const { return "sc_vector"; }
+
+ std::vector<sc_object*> const & get_elements() const;
+
+ size_type size() const
+ { return vec_.size(); }
+
+protected:
+
+ // begin implementation defined
+
+ typedef storage_type::iterator iterator;
+ typedef storage_type::const_iterator const_iterator;
+
+ sc_vector_base();
+
+ sc_vector_base( const char* prefix )
+ : sc_object( prefix )
+ , vec_()
+ , objs_vec_(0)
+ {}
+
+ ~sc_vector_base()
+ { delete objs_vec_; }
+
+ void * & at( size_type i )
+ { return vec_[i]; }
+
+ void const * at( size_type i ) const
+ { return vec_[i]; }
+
+ void reserve( size_type n )
+ { vec_.reserve(n); }
+
+ void clear()
+ { vec_.clear(); }
+
+ void push_back( void* item )
+ { vec_.push_back(item); }
+
+ void check_index( size_type i ) const;
+ bool check_init( size_type n ) const;
+
+ static std::string make_name( const char* prefix, size_type index );
+
+ iterator begin() { return vec_.begin(); }
+ iterator end() { return vec_.end(); }
+
+ const_iterator begin() const { return vec_.begin(); }
+ const_iterator end() const { return vec_.end(); }
+
+ virtual sc_object* object_cast( void* ) const = 0;
+
+ sc_object* implicit_cast( sc_object* p ) const { return p; }
+ sc_object* implicit_cast( ... /* incompatible */ ) const;
+
+public:
+
+ void report_empty_bind( const char* kind_, bool dst_range_ ) const;
+
+private:
+ storage_type vec_;
+ mutable std::vector< sc_object* >* objs_vec_;
+
+ // disabled
+ sc_vector_base( const sc_vector_base& );
+ sc_vector_base& operator=( const sc_vector_base& );
+
+}; // sc_vector_base
+
+// iterator access adapters
+template< typename ElementType >
+struct sc_direct_access
+{
+ typedef ElementType element_type;
+ typedef element_type type;
+ typedef typename sc_meta::remove_const<type>::type plain_type;
+
+ typedef sc_direct_access< type > policy;
+ typedef sc_direct_access< plain_type > non_const_policy;
+ typedef sc_direct_access< const plain_type > const_policy;
+
+ sc_direct_access(){}
+ sc_direct_access( const non_const_policy& ) {}
+ // convert from any policy to (const) direct policy
+ template <typename U>
+ sc_direct_access(const U&,
+ typename sc_meta::enable_if<sc_meta::is_more_const<
+ type,
+ typename U::policy::element_type>::value>::type* = NULL)
+ {}
+
+ type* get( type* this_ ) const
+ { return this_; }
+};
+
+// iterator access adapters
+template< typename ElementType
+ , typename AccessType >
+class sc_member_access
+{
+ public:
+ template< typename, typename > friend class sc_member_access;
+
+ typedef ElementType element_type;
+ typedef AccessType access_type;
+ typedef access_type (ElementType::*member_type);
+ typedef access_type type;
+ typedef typename sc_meta::remove_const<type>::type plain_type;
+ typedef typename sc_meta::remove_const<ElementType>::type plain_elem_type;
+
+ typedef sc_member_access< element_type, access_type > policy;
+ typedef sc_member_access< plain_elem_type, plain_type >
+ non_const_policy;
+ typedef sc_member_access< const plain_elem_type, const plain_type >
+ const_policy;
+
+ sc_member_access( member_type ptr )
+ : ptr_(ptr) {}
+
+ sc_member_access( const non_const_policy& other )
+ : ptr_(other.ptr_)
+ {}
+
+ access_type * get( element_type* this_ ) const
+ { return &(this_->*ptr_); }
+
+ private:
+ member_type ptr_;
+}; // sc_member_access
+
+
+template< typename ElementType
+ , typename AccessPolicy = sc_direct_access<ElementType> >
+class sc_vector_iter
+ : public std::iterator< std::random_access_iterator_tag
+ , typename AccessPolicy::type >
+ , private AccessPolicy
+{
+ typedef ElementType element_type;
+ typedef typename AccessPolicy::policy access_policy;
+ typedef typename AccessPolicy::non_const_policy non_const_policy;
+ typedef typename AccessPolicy::const_policy const_policy;
+ typedef typename access_policy::type access_type;
+
+ typedef typename sc_meta::remove_const<ElementType>::type plain_type;
+ typedef const plain_type const_plain_type;
+
+ friend class sc_vector< plain_type >;
+ template< typename, typename > friend class sc_vector_assembly;
+ template< typename, typename > friend class sc_vector_iter;
+
+ typedef std::iterator< std::random_access_iterator_tag, access_type > base_type;
+ typedef sc_vector_iter this_type;
+ typedef sc_vector<plain_type> vector_type;
+ typedef sc_vector_base::storage_type storage_type;
+
+ // select correct base-type iterator
+ template< typename U > struct select_iter
+ { typedef typename storage_type::iterator type; };
+ template< typename U > struct select_iter< const U >
+ { typedef typename storage_type::const_iterator type; };
+
+ typedef typename select_iter<ElementType>::type raw_iterator;
+ typedef sc_vector_iter< const_plain_type, const_policy > const_iterator;
+
+ // underlying vector iterator
+
+ raw_iterator it_;
+
+ sc_vector_iter( raw_iterator it, access_policy acc = access_policy() )
+ : access_policy(acc), it_(it) {}
+
+ access_policy const & get_policy() const { return *this; }
+
+public:
+ // interface for Random Access Iterator category,
+ // see ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements]
+
+ typedef typename base_type::difference_type difference_type;
+ typedef typename base_type::reference reference;
+ typedef typename base_type::pointer pointer;
+
+ sc_vector_iter() : access_policy(), it_() {}
+
+ // iterator conversions to more const, and/or direct iterators
+ template< typename OtherElement, typename OtherPolicy >
+ sc_vector_iter( const sc_vector_iter<OtherElement, OtherPolicy>& it
+ , typename sc_meta::enable_if<sc_meta::is_more_const<
+ element_type,
+ typename OtherPolicy::element_type>::value>::type* = NULL)
+ : access_policy( it.get_policy() ), it_( it.it_ )
+ {}
+
+ // step
+ this_type& operator++(){ ++it_; return *this; }
+ this_type& operator--(){ --it_; return *this; }
+ this_type operator++(int){ this_type old(*this); ++it_; return old; }
+ this_type operator--(int){ this_type old(*this); --it_; return old; }
+
+ // advance
+ this_type operator+( difference_type n ) const
+ { return this_type( it_ + n, get_policy()); }
+ this_type operator-( difference_type n ) const
+ { return this_type( it_ - n, get_policy()); }
+
+ this_type& operator+=( difference_type n ) { it_+=n; return *this; }
+ this_type& operator-=( difference_type n ) { it_-=n; return *this; }
+
+ // relations
+ bool operator== ( const this_type& that ) const { return it_ == that.it_; }
+ bool operator!= ( const this_type& that ) const { return it_ != that.it_; }
+ bool operator<= ( const this_type& that ) const { return it_ <= that.it_; }
+ bool operator>= ( const this_type& that ) const { return it_ >= that.it_; }
+ bool operator< ( const this_type& that ) const { return it_ < that.it_; }
+ bool operator> ( const this_type& that ) const { return it_ > that.it_; }
+
+ // dereference
+ reference operator*() const
+ { return *access_policy::get( static_cast<element_type*>(*it_) ); }
+ pointer operator->() const
+ { return access_policy::get( static_cast<element_type*>(*it_) ); }
+ reference operator[]( difference_type n ) const
+ { return *access_policy::get( static_cast<element_type*>(it_[n]) ); }
+
+ // distance
+ difference_type operator-( this_type const& that ) const
+ { return it_-that.it_; }
+
+}; // sc_vector_iter
+
+template< typename T >
+class sc_vector
+ : public sc_vector_base
+{
+ typedef sc_vector_base base_type;
+ typedef sc_vector<T> this_type;
+
+public:
+ typedef T element_type;
+ typedef sc_vector_iter< element_type > iterator;
+ typedef sc_vector_iter< const element_type > const_iterator;
+
+ sc_vector(){}
+
+ explicit sc_vector( const char* prefix )
+ : base_type( prefix )
+ {}
+
+ explicit sc_vector( const char* prefix, size_type n )
+ : base_type( prefix )
+ { init(n); }
+
+ template< typename Creator >
+ sc_vector( const char* prefix, size_type n, Creator creator )
+ : base_type( prefix )
+ {
+ init( n, creator );
+ }
+
+ virtual ~sc_vector();
+
+ element_type& operator[]( size_type i )
+ { return *static_cast<element_type*>( base_type::at(i) ); }
+
+ element_type& at( size_type i )
+ { check_index(i); return (*this)[i]; }
+
+ const element_type& operator[]( size_type i ) const
+ { return *static_cast<element_type const *>( base_type::at(i) ); }
+
+ const element_type& at( size_type i ) const
+ { check_index(i); return (*this)[i]; }
+
+ void init( size_type n )
+ { init( n, &this_type::create_element ); }
+
+ template< typename Creator >
+ void init( size_type n, Creator c );
+
+ static element_type * create_element( const char* prefix, size_type index );
+
+ iterator begin() { return base_type::begin(); }
+ iterator end() { return base_type::end(); }
+
+ const_iterator begin() const { return base_type::begin(); }
+ const_iterator end() const { return base_type::end(); }
+
+ const_iterator cbegin() const { return base_type::begin(); }
+ const_iterator cend() const { return base_type::end(); }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableContainer >
+ iterator bind( BindableContainer & c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last )
+ { return bind( first, last, this->begin() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last
+ , iterator from )
+ { return sc_vector_do_bind( *this, first, last, from ); }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentContainer >
+ iterator operator()( ArgumentContainer & c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last )
+ { return operator()( first, last, this->begin() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last
+ , iterator from )
+ { return sc_vector_do_operator_paren( *this, first, last, from ); }
+
+ // member-wise access
+
+ template< typename MT >
+ sc_vector_assembly<T,MT> assemble( MT (T::*member_ptr) )
+ { return sc_vector_assembly<T,MT>( *this, member_ptr ); }
+
+protected:
+
+ void clear();
+
+ virtual sc_object* object_cast( void* p ) const
+ { return implicit_cast( static_cast<element_type*>(p) ); }
+
+};
+
+template< typename T, typename MT >
+class sc_vector_assembly
+{
+ template< typename U > friend class sc_vector;
+
+public:
+
+ typedef sc_vector<T> base_type;
+
+ typedef sc_vector_iter< T, sc_member_access<T, MT> > iterator;
+ typedef sc_vector_iter< const T
+ , sc_member_access<const T, const MT> > const_iterator;
+
+ typedef T element_type;
+ typedef MT access_type;
+
+ typedef typename base_type::size_type size_type;
+ typedef typename base_type::difference_type difference_type;
+ typedef typename iterator::reference reference;
+ typedef typename iterator::pointer pointer;
+ typedef typename const_iterator::reference const_reference;
+ typedef typename const_iterator::pointer const_pointer;
+
+
+ typedef access_type (T::*member_type);
+
+ const char* name() const { return vec_->name(); }
+ const char* kind() const { return "sc_vector_assembly"; }
+
+ iterator begin()
+ { return iterator( (*vec_).begin().it_, ptr_ ); }
+ iterator end()
+ { return iterator( (*vec_).end().it_, ptr_ ); }
+
+ const_iterator cbegin() const
+ { return const_iterator( (*vec_).cbegin().it_, ptr_ ); }
+ const_iterator cend() const
+ { return const_iterator( (*vec_).cend().it_, ptr_ ); }
+
+ const_iterator begin() const
+ { return const_iterator( (*vec_).begin().it_, ptr_ ); }
+ const_iterator end() const
+ { return const_iterator( (*vec_).end().it_, ptr_ ); }
+
+ size_type size() const { return vec_->size(); }
+ const std::vector< sc_object* > & get_elements() const;
+
+ reference operator[]( size_type idx )
+ { return (*vec_)[idx].*ptr_; }
+ reference at( size_type idx )
+ { return vec_->at(idx).*ptr_; }
+ const_reference operator[]( size_type idx ) const
+ { return (*vec_)[idx].*ptr_; }
+ const_reference at( size_type idx ) const
+ { return vec_->at(idx).*ptr_; }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableContainer >
+ iterator bind( BindableContainer & c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last )
+ { return bind( first, last, this->begin() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last
+ , iterator from )
+ { return sc_vector_do_bind( *this, first, last, from ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last
+ , typename base_type::iterator from )
+ { return bind( first, last, iterator(from.it_, ptr_) ); }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentContainer >
+ iterator operator()( ArgumentContainer & c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last )
+ { return operator()( first, last, this->begin() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last
+ , iterator from )
+ { return sc_vector_do_operator_paren( *this, first, last, from ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last
+ , typename base_type::iterator from )
+ { return operator()( first, last, iterator(from.it_, ptr_) ); }
+
+ sc_vector_assembly( const sc_vector_assembly & other )
+ : vec_( other.vec_ )
+ , ptr_( other.ptr_ )
+ , child_vec_(0)
+ {}
+
+ sc_vector_assembly& operator=( sc_vector_assembly other_copy )
+ {
+ swap( other_copy );
+ return *this;
+ }
+
+ void swap( sc_vector_assembly & that )
+ {
+ using std::swap;
+ swap( vec_, that.vec_ );
+ swap( ptr_, that.ptr_ );
+ swap( child_vec_, that.child_vec_ );
+ }
+
+ void report_empty_bind( const char* kind_, bool dst_empty_ ) const
+ { vec_->report_empty_bind( kind_, dst_empty_ ); }
+
+ ~sc_vector_assembly()
+ { delete child_vec_; }
+
+private:
+
+ sc_vector_assembly( base_type & v, member_type ptr )
+ : vec_(&v)
+ , ptr_(ptr)
+ , child_vec_(0)
+ {}
+
+ sc_object* object_cast( pointer p ) const
+ { return vec_->implicit_cast( p ); }
+
+ base_type * vec_;
+ member_type ptr_;
+
+ mutable std::vector< sc_object* >* child_vec_;
+};
+
+template< typename T, typename MT >
+sc_vector_assembly<T,MT>
+sc_assemble_vector( sc_vector<T> & vec, MT (T::*ptr) )
+{
+ return vec.assemble( ptr );
+}
+
+template< typename T >
+typename sc_vector<T>::element_type *
+sc_vector<T>::create_element( const char* name, size_type /* idx */ )
+{
+ return new T( name );
+}
+
+template< typename T >
+template< typename Creator >
+void
+sc_vector<T>::init( size_type n, Creator c )
+{
+ if ( base_type::check_init(n) )
+ {
+ base_type::reserve( n );
+ try
+ {
+ for ( size_type i = 0; i<n; ++i )
+ {
+ // this workaround is needed for SystemC 2.2/2.3 sc_bind
+ std::string name = make_name( basename(), i );
+ const char* cname = name.c_str();
+
+ void* p = c( cname, i ) ; // call Creator
+ base_type::push_back(p);
+ }
+ }
+ catch ( ... )
+ {
+ clear();
+ throw;
+ }
+ }
+}
+
+template< typename T >
+void
+sc_vector<T>::clear()
+{
+ size_type i = size();
+ while ( i --> 0 )
+ {
+ delete &( (*this)[i] );
+ base_type::at(i) = 0;
+ }
+ base_type::clear();
+}
+
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_bind( Container & cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from )
+{
+ typename Container::iterator end = cont.end();
+
+ if( !cont.size() || from == end || first == last )
+ cont.report_empty_bind( cont.kind(), from == end );
+
+ while( from!=end && first != last )
+ (*from++).bind( *first++ );
+ return from;
+}
+
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_operator_paren( Container& cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from )
+{
+ typename Container::iterator end = cont.end();
+
+ if( !cont.size() || from == end || first == last )
+ cont.report_empty_bind( cont.kind(), from == end );
+
+ while( from!=end && first != last )
+ (*from++)( *first++ );
+ return from;
+}
+
+template< typename T >
+sc_vector<T>::~sc_vector()
+{
+ clear();
+}
+
+template< typename T, typename MT >
+std::vector< sc_object* > const &
+sc_vector_assembly<T,MT>::get_elements() const
+{
+ if( !child_vec_ )
+ child_vec_ = new std::vector< sc_object* >;
+
+ if( child_vec_->size() || !size() )
+ return *child_vec_;
+
+ child_vec_->reserve( size() );
+ for( const_iterator it=begin(); it != end(); ++it )
+ if( sc_object * obj = object_cast( const_cast<MT*>(&*it) ) )
+ child_vec_->push_back( obj );
+
+ return *child_vec_;
+}
+
+} // namespace sc_core
+#undef SC_RPTYPE_
+#undef SC_ENABLE_IF_
+
+// $Log: sc_vector.h,v $
+// Revision 1.17 2011/08/26 20:46:20 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.16 2011/07/25 10:21:17 acg
+// Andy Goodrich: check in aftermath of call to automake.
+//
+// Revision 1.15 2011/04/02 00:04:32 acg
+// Philipp A. Hartmann: fix distance from member iterators, and
+// add iterator conversions.
+//
+// Revision 1.14 2011/04/01 22:35:19 acg
+// Andy Goodrich: spelling fix.
+//
+// Revision 1.13 2011/03/28 13:03:09 acg
+// Andy Goodrich: Philipp's latest update.
+//
+// Revision 1.12 2011/03/23 16:16:28 acg
+// Philipp A. Hartmann: rebase implementation on void*
+// - supports virtual inheritance from sc_object again
+// - build up get_elements result on demand
+// - still requires element type to be derived from sc_object
+//
+// Revision 1.11 2011/02/19 16:46:36 acg
+// Andy Goodrich: finally get the update from Philipp correct!
+//
+
+#endif // SC_VECTOR_H_INCLUDED_
+// Taf!