/* * Copyright 2018 Google, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Gabe Black */ #ifndef __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__ #define __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__ #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 { template class sc_vector_assembly; template class sc_vector; template sc_vector_assembly sc_assemble_vector( sc_vector &, MT(T::* member_ptr)); class sc_vector_base : public sc_object { public: typedef size_t size_type; virtual const char *kind() const { return "sc_vector"; } size_type size() const; const std::vector &get_elements() const; }; /* * 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] 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 class sc_vector : public sc_vector_base { public: using sc_vector_base::size_type; typedef sc_vector_iter iterator; typedef sc_vector_iter const_iterator; sc_vector() : sc_vector_base() { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); } explicit sc_vector(const char *) : sc_vector_base() { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); } sc_vector(const char *, size_type) : sc_vector_base() { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); } template sc_vector(const char *, size_type, Creator) : sc_vector_base() { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); } virtual ~sc_vector() {} void init(size_type) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); } static T * create_element(const char *, size_type) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return nullptr; } template void init(size_type, Creator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); } T & operator [] (size_type) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return *(T *)nullptr; } const T & operator [] (size_type) const { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return *(const T *)nullptr; } T & at(size_type) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return *(T *)nullptr; } const T & at(size_type) const { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return *(const T *)nullptr; } iterator begin() { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } iterator end() { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } const_iterator begin() const { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return const_iterator(); } const_iterator end() const { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return const_iterator(); } const_iterator cbegin() const { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return const_iterator(); } const_iterator cend() const { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return const_iterator(); } template iterator bind(sc_vector_assembly) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } template iterator bind(BindableContainer &) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } template iterator bind(BindableIterator, BindableIterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } template iterator bind(BindableIterator, BindableIterator, iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } template iterator operator () (sc_vector_assembly c) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } template iterator operator () (ArgumentContainer &) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } template iterator operator () (ArgumentIterator, ArgumentIterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } template iterator operator () (ArgumentIterator, ArgumentIterator, iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return iterator(); } private: // Disabled sc_vector(const sc_vector &) : sc_vector_base() {} sc_vector &operator = (const sc_vector &) { return *this; } }; template class sc_vector_assembly { public: friend sc_vector_assembly sc_assemble_vector<>( sc_vector &, MT (T::*)); typedef size_t size_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() { return iterator(vec_->begin().it_, ptr_); } iterator end() { return iterator(vec_->end().it_, ptr_); } const_iterator cbegin() const { return const_iterator(vec_->begin().it_, ptr_); } const_iterator cend() const { return const_iterator(vec_->end().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(); } std::vector get_elements() const { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return *(std::vector *)nullptr; } typename iterator::reference operator [] (size_type i) { return (*vec_)[i].*ptr_; } typename const_iterator::reference operator [] (size_type i) const { return (*vec_)[i].*ptr_; } typename iterator::reference at(size_type i) { return vec_->at(i).*ptr_; } typename const_iterator::reference at(size_type i) const { return vec_->at(i).*ptr_; } template iterator bind(sc_vector_assembly) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator bind(BindableContainer &) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator bind(BindableIterator, BindableIterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator bind(BindableIterator, BindableIterator, iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator bind(BindableIterator, BindableIterator, typename sc_vector::iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator operator () (sc_vector_assembly) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator operator () (ArgumentContainer &) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator operator () (ArgumentIterator, ArgumentIterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator operator () (ArgumentIterator, ArgumentIterator, iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } template iterator operator () (ArgumentIterator, ArgumentIterator, typename sc_vector::iterator) { sc_utils_warn_unimpl(__PRETTY_FUNCTION__); return begin(); } private: 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 &v, MT (T::*ptr)) { return sc_vector_assembly(v, ptr); } } // namespace sc_core #endif //__SYSTEMC_EXT_UTIL_SC_VECTOR_HH__