From f8ad69b3204d5932fe7dd6948219921a8ca20675 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 11 Jun 2018 18:47:49 -0700 Subject: systemc: Fill out some of the sc_vector.hh classes. The iterator class needs to have some operators, etc., defined so that tests written against it can compile correctly. The implementations were heavily influenced by the Accellera implementation. Also it should be noted that the systemc spec is incorrect where it defines these classes. When implemented like they are in the Accellera version, the versions of bind in sc_vector_assembly which take sc_vector::iterator and iterator parameters are different, and so they can overload each other. If implemented as described by the spec however, those types are the same and the code won't compile. Change-Id: I62852adf7e6c0a2f3df076ba4e93d2501859c32d Reviewed-on: https://gem5-review.googlesource.com/11177 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/ext/utils/sc_vector.hh | 434 +++++++++++++++++++++++++++++++------ 1 file changed, 373 insertions(+), 61 deletions(-) diff --git a/src/systemc/ext/utils/sc_vector.hh b/src/systemc/ext/utils/sc_vector.hh index 073b17c88..fea49c296 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 + +/* + * 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 + 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 -- cgit v1.2.3