diff --git a/src/systemc/ext/utils/sc_vector.hh b/src/systemc/ext/utils/sc_vector.hh index 073b17c88d..fea49c2967 100644 --- a/src/systemc/ext/utils/sc_vector.hh +++ b/src/systemc/ext/utils/sc_vector.hh @@ -33,11 +33,102 @@ #include #include +#include #include #include "../core/sc_object.hh" #include "warn_unimpl.hh" +namespace sc_gem5 +{ + +// Goop for supporting sc_vector_iter, simplified from the Accellera version. + +#if __cplusplus >= 201103L + +using std::enable_if; +using std::remove_const; +using std::is_same; +using std::is_const; + +#else + +template +struct enable_if +{}; + +template +struct enable_if +{ + typedef T type; +}; + +template +struct remove_const +{ + typedef T type; +}; +template +struct remove_const +{ + typedef T type; +}; + +template +struct is_same +{ + static const bool value = false; +}; +template +struct is_same +{ + static const bool value = true; +}; + +template +struct is_const +{ + static const bool value = false; +}; +template +struct is_const +{ + static const bool value = true; +}; + +#endif + +template +struct is_more_const +{ + static const bool value = + is_same::type, + typename remove_const::type>::value && + is_const::value >= is_const::value; +}; + +struct special_result +{}; + +template +struct remove_special_fptr +{}; + +template +struct remove_special_fptr +{ + typedef T type; +}; + +#define SC_RPTYPE_(Type) \ + ::sc_gem5::remove_special_fptr< \ + ::sc_gem5::special_result & (*) Type>::type::value + +#define SC_ENABLE_IF_(Cond) \ + typename ::sc_gem5::enable_if::type * = NULL + +} // namespace sc_gem5 + namespace sc_core { @@ -61,14 +152,247 @@ class sc_vector_base : public sc_object const std::vector &get_elements() const; }; -template -class sc_vector_iter : - public std::iterator + +/* + * Non-standard iterator access adapters. Without using these, the classes as + * defined in the standard won't compile because of redundant bind() overloads. + */ + +template +class sc_direct_access { + public: + typedef Element ElementType; + typedef ElementType Type; + typedef typename sc_gem5::remove_const::type PlainType; + + typedef sc_direct_access Policy; + typedef sc_direct_access NonConstPolicy; + typedef sc_direct_access ConstPolicy; + + sc_direct_access() {} + sc_direct_access(const NonConstPolicy &) {} + + template + sc_direct_access(const U &, + SC_ENABLE_IF_(( + sc_gem5::is_more_const< + ElementType, typename U::Policy::ElementType> + )) + ) + {} + + ElementType * + get(ElementType *this_) const + { + return this_; + } +}; + +template +class sc_member_access +{ + public: + template + friend class sc_member_access; + + typedef Element ElementType; + typedef Access AccessType; + typedef AccessType (ElementType::*MemberType); + typedef AccessType Type; + typedef typename sc_gem5::remove_const::type PlainType; + typedef typename sc_gem5::remove_const::type PlainElemType; + + typedef sc_member_access Policy; + typedef sc_member_access NonConstPolicy; + typedef sc_member_access ConstPolicy; + + sc_member_access(MemberType ptr) : ptr_(ptr) {} + sc_member_access(const NonConstPolicy &other) : ptr_(other.ptr_) {} + + AccessType *get(ElementType *this_) const { return &(this_->*ptr_); } + + private: + MemberType ptr_; +}; + +template > +class sc_vector_iter : + public std::iterator, + private AccessPolicy +{ + private: + typedef Element ElementType; + typedef typename AccessPolicy::Policy Policy; + typedef typename AccessPolicy::NonConstPolicy NonConstPolicy; + typedef typename AccessPolicy::ConstPolicy ConstPolicy; + typedef typename Policy::Type AccessType; + + typedef typename sc_gem5::remove_const::type PlainType; + typedef const PlainType ConstPlainType; + typedef typename sc_direct_access::ConstPolicy + ConstDirectPolicy; + + friend class sc_vector; + template + friend class sc_vector_assembly; + template + friend class sc_vector_iter; + + typedef std::iterator + BaseType; + typedef sc_vector_iter ThisType; + typedef sc_vector VectorType; + typedef std::vector StorageType; + + template + struct SelectIter + { + typedef typename std::vector::iterator type; + }; + template + struct SelectIter + { + typedef typename std::vector::const_iterator type; + }; + typedef typename SelectIter::type RawIterator; + typedef sc_vector_iter ConstIterator; + typedef sc_vector_iter + ConstDirectIterator; + + RawIterator it_; + + sc_vector_iter(RawIterator it, Policy acc=Policy()) : + Policy(acc), it_(it) + {} + + Policy const &get_policy() const { return *this; } + + public: // Conforms to Random Access Iterator category. // See ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements] - // Implementation-defined + typedef typename BaseType::difference_type difference_type; + typedef typename BaseType::reference reference; + typedef typename BaseType::pointer pointer; + + sc_vector_iter() : Policy(), it_() {} + + template + sc_vector_iter(const It &it, + SC_ENABLE_IF_(( + sc_gem5::is_more_const< + ElementType, typename It::Policy::ElementType> + )) + ) : Policy(it.get_policy()), it_(it.it_) + {} + + ThisType & + operator ++ () + { + ++it_; + return *this; + } + ThisType & + operator -- () + { + --it_; + return *this; + } + ThisType + operator ++ (int) + { + ThisType old(*this); + ++it_; + return old; + } + ThisType + operator -- (int) + { + ThisType old(*this); + --it_; + return old; + } + + ThisType + operator + (difference_type n) const + { + return ThisType(it_ + n, get_policy()); + } + ThisType + operator - (difference_type n) const + { + return ThisType(it_ - n, get_policy()); + } + + ThisType & + operator += (difference_type n) + { + it_ += n; + return *this; + } + + ThisType & + operator -= (difference_type n) + { + it_ -= n; + return *this; + } + + bool + operator == (const ConstDirectIterator &other) const + { + return it_ == other.it_; + } + bool + operator != (const ConstDirectIterator &other) const + { + return it_ != other.it_; + } + bool + operator <= (const ConstDirectIterator &other) const + { + return it_ <= other.it_; + } + bool + operator >= (const ConstDirectIterator &other) const + { + return it_ >= other.it_; + } + bool + operator < (const ConstDirectIterator &other) const + { + return it_ < other.it_; + } + bool + operator > (const ConstDirectIterator &other) const + { + return it_ > other.it_; + } + + reference + operator * () const + { + return *Policy::get(static_cast((void *)*it_)); + } + pointer + operator -> () const + { + return Policy::get(static_cast((void *)*it_)); + } + reference + operator [] (difference_type n) const + { + return *Policy::get(static_cast((void *)it_[n])); + } + + difference_type + operator - (ConstDirectIterator const &other) const + { + return it_ - other.it_; + } }; template @@ -257,53 +581,46 @@ class sc_vector_assembly { public: friend sc_vector_assembly sc_assemble_vector<>( - sc_vector &, MT(T::* member_ptr)); + sc_vector &, MT (T::*)); typedef size_t size_type; - // These next two types are supposed to be implementation defined. We'll - // just stick in a substitute for now, but these should probably not just - // be STL vector iterators. - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; - typedef MT (T::* member_type); + typedef sc_vector_iter > iterator; + typedef sc_vector_iter< + const T, sc_member_access > const_iterator; + typedef MT (T::*MemberType); sc_vector_assembly(const sc_vector_assembly &) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); } - iterator - begin() - { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); - } - iterator - end() - { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); - } + iterator begin() { return iterator(vec_->begin().it_, ptr_); } + iterator end() { return iterator(vec_->end().it_, ptr_); } const_iterator cbegin() const { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return const_iterator(); + return const_iterator(vec_->begin().it_, ptr_); } const_iterator cend() const { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return const_iterator(); + return const_iterator(vec_->end().it_, ptr_); } - size_type - size() const + const_iterator + begin() const { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return 0; + 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(); } + std::vector get_elements() const { @@ -312,29 +629,25 @@ class sc_vector_assembly } typename iterator::reference - operator [] (size_type) + operator [] (size_type i) { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return typename iterator::reference(); + return (*vec_)[i].*ptr_; } typename const_iterator::reference - operator [] (size_type) const + operator [] (size_type i) const { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return typename iterator::reference(); + return (*vec_)[i].*ptr_; } typename iterator::reference - at(size_type) + at(size_type i) { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return typename iterator::reference(); + return vec_->at(i).*ptr_; } typename const_iterator::reference - at(size_type) const + at(size_type i) const { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return typename iterator::reference(); + return vec_->at(i).*ptr_; } template @@ -342,7 +655,7 @@ class sc_vector_assembly bind(sc_vector_assembly) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -350,7 +663,7 @@ class sc_vector_assembly bind(BindableContainer &) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -358,7 +671,7 @@ class sc_vector_assembly bind(BindableIterator, BindableIterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -366,7 +679,7 @@ class sc_vector_assembly bind(BindableIterator, BindableIterator, iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -374,7 +687,7 @@ class sc_vector_assembly bind(BindableIterator, BindableIterator, typename sc_vector::iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -382,7 +695,7 @@ class sc_vector_assembly operator () (sc_vector_assembly) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -390,7 +703,7 @@ class sc_vector_assembly operator () (ArgumentContainer &) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -398,7 +711,7 @@ class sc_vector_assembly operator () (ArgumentIterator, ArgumentIterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -406,7 +719,7 @@ class sc_vector_assembly operator () (ArgumentIterator, ArgumentIterator, iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } template @@ -415,24 +728,23 @@ class sc_vector_assembly typename sc_vector::iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return iterator(); + return begin(); } private: - // Temporary constructor which will (eventually) actually bind an - // sc_vector_assembly instance to an sc_vector. - sc_vector_assembly() - { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - } + sc_vector_assembly(sc_vector &v, MemberType ptr) : + vec_(&v), ptr_(ptr) + {} + + sc_vector *vec_; + MemberType ptr_; }; template sc_vector_assembly -sc_assemble_vector(sc_vector &, MT(T::* member_ptr)) +sc_assemble_vector(sc_vector &v, MT (T::*ptr)) { - sc_utils_warn_unimpl(__PRETTY_FUNCTION__); - return sc_vector_assembly(); + return sc_vector_assembly(v, ptr); } } // namespace sc_core