sc_vector.hh revision 13271
113271Sgabeblack@google.com/***************************************************************************** 213271Sgabeblack@google.com 313271Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 413271Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 513271Sgabeblack@google.com with this work for additional information regarding copyright ownership. 613271Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 713271Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 813271Sgabeblack@google.com License. You may obtain a copy of the License at 913271Sgabeblack@google.com 1013271Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1113271Sgabeblack@google.com 1213271Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1313271Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1413271Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1513271Sgabeblack@google.com implied. See the License for the specific language governing 1613271Sgabeblack@google.com permissions and limitations under the License. 1713271Sgabeblack@google.com 1813271Sgabeblack@google.com *****************************************************************************/ 1913271Sgabeblack@google.com 2012852Sgabeblack@google.com/* 2112852Sgabeblack@google.com * Copyright 2018 Google, Inc. 2212852Sgabeblack@google.com * 2312852Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 2412852Sgabeblack@google.com * modification, are permitted provided that the following conditions are 2512852Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 2612852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 2712852Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 2812852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2912852Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 3012852Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 3112852Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 3212852Sgabeblack@google.com * this software without specific prior written permission. 3312852Sgabeblack@google.com * 3412852Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3512852Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3612852Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3712852Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3812852Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3912852Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 4012852Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 4112852Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 4212852Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 4312852Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 4412852Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4512852Sgabeblack@google.com * 4612852Sgabeblack@google.com * Authors: Gabe Black 4712852Sgabeblack@google.com */ 4812852Sgabeblack@google.com 4912852Sgabeblack@google.com#ifndef __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__ 5012852Sgabeblack@google.com#define __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__ 5112852Sgabeblack@google.com 5212852Sgabeblack@google.com#include <stdint.h> 5312852Sgabeblack@google.com 5412852Sgabeblack@google.com#include <exception> 5512872Sgabeblack@google.com#include <iterator> 5612852Sgabeblack@google.com#include <vector> 5712852Sgabeblack@google.com 5813271Sgabeblack@google.com#include "../core/sc_module.hh" 5912852Sgabeblack@google.com#include "../core/sc_object.hh" 6012852Sgabeblack@google.com 6112872Sgabeblack@google.comnamespace sc_gem5 6212872Sgabeblack@google.com{ 6312872Sgabeblack@google.com 6412872Sgabeblack@google.com// Goop for supporting sc_vector_iter, simplified from the Accellera version. 6512872Sgabeblack@google.com 6612872Sgabeblack@google.com#if __cplusplus >= 201103L 6712872Sgabeblack@google.com 6812872Sgabeblack@google.comusing std::enable_if; 6912872Sgabeblack@google.comusing std::remove_const; 7012872Sgabeblack@google.comusing std::is_same; 7112872Sgabeblack@google.comusing std::is_const; 7212872Sgabeblack@google.com 7312872Sgabeblack@google.com#else 7412872Sgabeblack@google.com 7512872Sgabeblack@google.comtemplate<bool Cond, typename T=void> 7612872Sgabeblack@google.comstruct enable_if 7712872Sgabeblack@google.com{}; 7812872Sgabeblack@google.com 7912872Sgabeblack@google.comtemplate<typename T> 8012872Sgabeblack@google.comstruct enable_if<true, T> 8112872Sgabeblack@google.com{ 8212872Sgabeblack@google.com typedef T type; 8312872Sgabeblack@google.com}; 8412872Sgabeblack@google.com 8512872Sgabeblack@google.comtemplate <typename T> 8612872Sgabeblack@google.comstruct remove_const 8712872Sgabeblack@google.com{ 8812872Sgabeblack@google.com typedef T type; 8912872Sgabeblack@google.com}; 9012872Sgabeblack@google.comtemplate <typename T> 9112872Sgabeblack@google.comstruct remove_const<const T> 9212872Sgabeblack@google.com{ 9312872Sgabeblack@google.com typedef T type; 9412872Sgabeblack@google.com}; 9512872Sgabeblack@google.com 9612872Sgabeblack@google.comtemplate <typename T, typename U> 9712872Sgabeblack@google.comstruct is_same 9812872Sgabeblack@google.com{ 9912872Sgabeblack@google.com static const bool value = false; 10012872Sgabeblack@google.com}; 10112872Sgabeblack@google.comtemplate <typename T> 10212872Sgabeblack@google.comstruct is_same<T, T> 10312872Sgabeblack@google.com{ 10412872Sgabeblack@google.com static const bool value = true; 10512872Sgabeblack@google.com}; 10612872Sgabeblack@google.com 10712872Sgabeblack@google.comtemplate <typename T> 10812872Sgabeblack@google.comstruct is_const 10912872Sgabeblack@google.com{ 11012872Sgabeblack@google.com static const bool value = false; 11112872Sgabeblack@google.com}; 11212872Sgabeblack@google.comtemplate <typename T> 11312872Sgabeblack@google.comstruct is_const<const T> 11412872Sgabeblack@google.com{ 11512872Sgabeblack@google.com static const bool value = true; 11612872Sgabeblack@google.com}; 11712872Sgabeblack@google.com 11812872Sgabeblack@google.com#endif 11912872Sgabeblack@google.com 12012872Sgabeblack@google.comtemplate <typename CT, typename T> 12112872Sgabeblack@google.comstruct is_more_const 12212872Sgabeblack@google.com{ 12312872Sgabeblack@google.com static const bool value = 12412872Sgabeblack@google.com is_same<typename remove_const<CT>::type, 12512872Sgabeblack@google.com typename remove_const<T>::type>::value && 12612872Sgabeblack@google.com is_const<CT>::value >= is_const<T>::value; 12712872Sgabeblack@google.com}; 12812872Sgabeblack@google.com 12912872Sgabeblack@google.comstruct special_result 13012872Sgabeblack@google.com{}; 13112872Sgabeblack@google.com 13212872Sgabeblack@google.comtemplate <typename T> 13312872Sgabeblack@google.comstruct remove_special_fptr 13412872Sgabeblack@google.com{}; 13512872Sgabeblack@google.com 13612872Sgabeblack@google.comtemplate <typename T> 13712872Sgabeblack@google.comstruct remove_special_fptr<special_result & (*)(T)> 13812872Sgabeblack@google.com{ 13912872Sgabeblack@google.com typedef T type; 14012872Sgabeblack@google.com}; 14112872Sgabeblack@google.com 14212872Sgabeblack@google.com#define SC_RPTYPE_(Type) \ 14312872Sgabeblack@google.com ::sc_gem5::remove_special_fptr< \ 14412872Sgabeblack@google.com ::sc_gem5::special_result & (*) Type>::type::value 14512872Sgabeblack@google.com 14612872Sgabeblack@google.com#define SC_ENABLE_IF_(Cond) \ 14712872Sgabeblack@google.com typename ::sc_gem5::enable_if<SC_RPTYPE_(Cond)>::type * = NULL 14812872Sgabeblack@google.com 14912872Sgabeblack@google.com} // namespace sc_gem5 15012872Sgabeblack@google.com 15112852Sgabeblack@google.comnamespace sc_core 15212852Sgabeblack@google.com{ 15312852Sgabeblack@google.com 15412852Sgabeblack@google.comtemplate <typename T, typename MT> 15512852Sgabeblack@google.comclass sc_vector_assembly; 15612852Sgabeblack@google.com 15712852Sgabeblack@google.comtemplate <typename T> 15812852Sgabeblack@google.comclass sc_vector; 15912852Sgabeblack@google.com 16012852Sgabeblack@google.comtemplate <typename T, typename MT> 16112852Sgabeblack@google.comsc_vector_assembly<T, MT> sc_assemble_vector( 16212852Sgabeblack@google.com sc_vector<T> &, MT(T::* member_ptr)); 16312852Sgabeblack@google.com 16412852Sgabeblack@google.comclass sc_vector_base : public sc_object 16512852Sgabeblack@google.com{ 16612852Sgabeblack@google.com public: 16712852Sgabeblack@google.com typedef size_t size_type; 16812852Sgabeblack@google.com 16913271Sgabeblack@google.com sc_vector_base(const char *_name) : sc_object(_name) {} 17013271Sgabeblack@google.com 17112852Sgabeblack@google.com virtual const char *kind() const { return "sc_vector"; } 17212852Sgabeblack@google.com size_type size() const; 17312852Sgabeblack@google.com const std::vector<sc_object *> &get_elements() const; 17413271Sgabeblack@google.com 17513271Sgabeblack@google.com protected: 17613271Sgabeblack@google.com std::vector<void *> objs; 17713271Sgabeblack@google.com 17813271Sgabeblack@google.com // What's returned by get_elements, which really returns the elemenets 17913271Sgabeblack@google.com // which are also objects. 18013271Sgabeblack@google.com mutable std::vector<sc_object *> elements; 18113271Sgabeblack@google.com 18213271Sgabeblack@google.com sc_object *implicitCast(sc_object *p) const { return p; } 18313271Sgabeblack@google.com sc_object *implicitCast(...) const 18413271Sgabeblack@google.com { 18513271Sgabeblack@google.com SC_REPORT_ERROR( 18613271Sgabeblack@google.com "(E808) sc_vector::get_elements called for element type " 18713271Sgabeblack@google.com "not derived from sc_object", name()); 18813271Sgabeblack@google.com return nullptr; 18913271Sgabeblack@google.com } 19013271Sgabeblack@google.com virtual sc_object *objectCast(void *) const = 0; 19113271Sgabeblack@google.com 19213271Sgabeblack@google.com void checkIndex(size_type index) const; 19313271Sgabeblack@google.com void forceParent() const; 19413271Sgabeblack@google.com void unforceParent() const; 19513271Sgabeblack@google.com 19613271Sgabeblack@google.com void reportEmpty(const char *kind_, bool empty_dest) const; 19712852Sgabeblack@google.com}; 19812852Sgabeblack@google.com 19912872Sgabeblack@google.com 20012872Sgabeblack@google.com/* 20112872Sgabeblack@google.com * Non-standard iterator access adapters. Without using these, the classes as 20212872Sgabeblack@google.com * defined in the standard won't compile because of redundant bind() overloads. 20312872Sgabeblack@google.com */ 20412872Sgabeblack@google.com 20512872Sgabeblack@google.comtemplate <typename Element> 20612872Sgabeblack@google.comclass sc_direct_access 20712872Sgabeblack@google.com{ 20812872Sgabeblack@google.com public: 20912872Sgabeblack@google.com typedef Element ElementType; 21012872Sgabeblack@google.com typedef ElementType Type; 21112872Sgabeblack@google.com typedef typename sc_gem5::remove_const<ElementType>::type PlainType; 21212872Sgabeblack@google.com 21312872Sgabeblack@google.com typedef sc_direct_access<ElementType> Policy; 21412872Sgabeblack@google.com typedef sc_direct_access<PlainType> NonConstPolicy; 21512872Sgabeblack@google.com typedef sc_direct_access<const PlainType> ConstPolicy; 21612872Sgabeblack@google.com 21712872Sgabeblack@google.com sc_direct_access() {} 21812872Sgabeblack@google.com sc_direct_access(const NonConstPolicy &) {} 21912872Sgabeblack@google.com 22012872Sgabeblack@google.com template <typename U> 22112872Sgabeblack@google.com sc_direct_access(const U &, 22212872Sgabeblack@google.com SC_ENABLE_IF_(( 22312872Sgabeblack@google.com sc_gem5::is_more_const< 22412872Sgabeblack@google.com ElementType, typename U::Policy::ElementType> 22512872Sgabeblack@google.com )) 22612872Sgabeblack@google.com ) 22712872Sgabeblack@google.com {} 22812872Sgabeblack@google.com 22912872Sgabeblack@google.com ElementType * 23012872Sgabeblack@google.com get(ElementType *this_) const 23112872Sgabeblack@google.com { 23212872Sgabeblack@google.com return this_; 23312872Sgabeblack@google.com } 23412872Sgabeblack@google.com}; 23512872Sgabeblack@google.com 23612872Sgabeblack@google.comtemplate <typename Element, typename Access> 23712872Sgabeblack@google.comclass sc_member_access 23812872Sgabeblack@google.com{ 23912872Sgabeblack@google.com public: 24012872Sgabeblack@google.com template <typename, typename> 24112872Sgabeblack@google.com friend class sc_member_access; 24212872Sgabeblack@google.com 24312872Sgabeblack@google.com typedef Element ElementType; 24412872Sgabeblack@google.com typedef Access AccessType; 24512872Sgabeblack@google.com typedef AccessType (ElementType::*MemberType); 24612872Sgabeblack@google.com typedef AccessType Type; 24712872Sgabeblack@google.com typedef typename sc_gem5::remove_const<AccessType>::type PlainType; 24812872Sgabeblack@google.com typedef typename sc_gem5::remove_const<ElementType>::type PlainElemType; 24912872Sgabeblack@google.com 25012872Sgabeblack@google.com typedef sc_member_access<ElementType, AccessType> Policy; 25112872Sgabeblack@google.com typedef sc_member_access<PlainElemType, PlainType> NonConstPolicy; 25212872Sgabeblack@google.com typedef sc_member_access<const PlainElemType, const PlainType> ConstPolicy; 25312872Sgabeblack@google.com 25412872Sgabeblack@google.com sc_member_access(MemberType ptr) : ptr_(ptr) {} 25512872Sgabeblack@google.com sc_member_access(const NonConstPolicy &other) : ptr_(other.ptr_) {} 25612872Sgabeblack@google.com 25712872Sgabeblack@google.com AccessType *get(ElementType *this_) const { return &(this_->*ptr_); } 25812872Sgabeblack@google.com 25912872Sgabeblack@google.com private: 26012872Sgabeblack@google.com MemberType ptr_; 26112872Sgabeblack@google.com}; 26212872Sgabeblack@google.com 26312872Sgabeblack@google.comtemplate <typename Element, 26412872Sgabeblack@google.com typename AccessPolicy=sc_direct_access<Element> > 26512852Sgabeblack@google.comclass sc_vector_iter : 26612872Sgabeblack@google.com public std::iterator<std::random_access_iterator_tag, 26712872Sgabeblack@google.com typename AccessPolicy::Type>, 26812872Sgabeblack@google.com private AccessPolicy 26912852Sgabeblack@google.com{ 27012872Sgabeblack@google.com private: 27112872Sgabeblack@google.com typedef Element ElementType; 27212872Sgabeblack@google.com typedef typename AccessPolicy::Policy Policy; 27312872Sgabeblack@google.com typedef typename AccessPolicy::NonConstPolicy NonConstPolicy; 27412872Sgabeblack@google.com typedef typename AccessPolicy::ConstPolicy ConstPolicy; 27512872Sgabeblack@google.com typedef typename Policy::Type AccessType; 27612872Sgabeblack@google.com 27712872Sgabeblack@google.com typedef typename sc_gem5::remove_const<ElementType>::type PlainType; 27812872Sgabeblack@google.com typedef const PlainType ConstPlainType; 27912872Sgabeblack@google.com typedef typename sc_direct_access<PlainType>::ConstPolicy 28012872Sgabeblack@google.com ConstDirectPolicy; 28112872Sgabeblack@google.com 28212872Sgabeblack@google.com friend class sc_vector<PlainType>; 28312872Sgabeblack@google.com template <typename, typename> 28412872Sgabeblack@google.com friend class sc_vector_assembly; 28512872Sgabeblack@google.com template <typename, typename> 28612872Sgabeblack@google.com friend class sc_vector_iter; 28712872Sgabeblack@google.com 28812872Sgabeblack@google.com typedef std::iterator<std::random_access_iterator_tag, AccessType> 28912872Sgabeblack@google.com BaseType; 29012872Sgabeblack@google.com typedef sc_vector_iter ThisType; 29112872Sgabeblack@google.com typedef sc_vector<PlainType> VectorType; 29212872Sgabeblack@google.com typedef std::vector<void *> StorageType; 29312872Sgabeblack@google.com 29412872Sgabeblack@google.com template <typename U> 29512872Sgabeblack@google.com struct SelectIter 29612872Sgabeblack@google.com { 29712872Sgabeblack@google.com typedef typename std::vector<void *>::iterator type; 29812872Sgabeblack@google.com }; 29912872Sgabeblack@google.com template <typename U> 30012872Sgabeblack@google.com struct SelectIter<const U> 30112872Sgabeblack@google.com { 30212872Sgabeblack@google.com typedef typename std::vector<void *>::const_iterator type; 30312872Sgabeblack@google.com }; 30412872Sgabeblack@google.com typedef typename SelectIter<ElementType>::type RawIterator; 30512872Sgabeblack@google.com typedef sc_vector_iter<ConstPlainType, ConstPolicy> ConstIterator; 30612872Sgabeblack@google.com typedef sc_vector_iter<ConstPlainType, ConstDirectPolicy> 30712872Sgabeblack@google.com ConstDirectIterator; 30812872Sgabeblack@google.com 30912872Sgabeblack@google.com RawIterator it_; 31012872Sgabeblack@google.com 31112872Sgabeblack@google.com sc_vector_iter(RawIterator it, Policy acc=Policy()) : 31212872Sgabeblack@google.com Policy(acc), it_(it) 31312872Sgabeblack@google.com {} 31412872Sgabeblack@google.com 31512872Sgabeblack@google.com Policy const &get_policy() const { return *this; } 31612872Sgabeblack@google.com 31712872Sgabeblack@google.com public: 31812852Sgabeblack@google.com // Conforms to Random Access Iterator category. 31912852Sgabeblack@google.com // See ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements] 32012852Sgabeblack@google.com 32112872Sgabeblack@google.com typedef typename BaseType::difference_type difference_type; 32212872Sgabeblack@google.com typedef typename BaseType::reference reference; 32312872Sgabeblack@google.com typedef typename BaseType::pointer pointer; 32412872Sgabeblack@google.com 32512872Sgabeblack@google.com sc_vector_iter() : Policy(), it_() {} 32612872Sgabeblack@google.com 32712872Sgabeblack@google.com template <typename It> 32812872Sgabeblack@google.com sc_vector_iter(const It &it, 32912872Sgabeblack@google.com SC_ENABLE_IF_(( 33012872Sgabeblack@google.com sc_gem5::is_more_const< 33112872Sgabeblack@google.com ElementType, typename It::Policy::ElementType> 33212872Sgabeblack@google.com )) 33312872Sgabeblack@google.com ) : Policy(it.get_policy()), it_(it.it_) 33412872Sgabeblack@google.com {} 33512872Sgabeblack@google.com 33612872Sgabeblack@google.com ThisType & 33712872Sgabeblack@google.com operator ++ () 33812872Sgabeblack@google.com { 33912872Sgabeblack@google.com ++it_; 34012872Sgabeblack@google.com return *this; 34112872Sgabeblack@google.com } 34212872Sgabeblack@google.com ThisType & 34312872Sgabeblack@google.com operator -- () 34412872Sgabeblack@google.com { 34512872Sgabeblack@google.com --it_; 34612872Sgabeblack@google.com return *this; 34712872Sgabeblack@google.com } 34812872Sgabeblack@google.com ThisType 34912872Sgabeblack@google.com operator ++ (int) 35012872Sgabeblack@google.com { 35112872Sgabeblack@google.com ThisType old(*this); 35212872Sgabeblack@google.com ++it_; 35312872Sgabeblack@google.com return old; 35412872Sgabeblack@google.com } 35512872Sgabeblack@google.com ThisType 35612872Sgabeblack@google.com operator -- (int) 35712872Sgabeblack@google.com { 35812872Sgabeblack@google.com ThisType old(*this); 35912872Sgabeblack@google.com --it_; 36012872Sgabeblack@google.com return old; 36112872Sgabeblack@google.com } 36212872Sgabeblack@google.com 36312872Sgabeblack@google.com ThisType 36412872Sgabeblack@google.com operator + (difference_type n) const 36512872Sgabeblack@google.com { 36612872Sgabeblack@google.com return ThisType(it_ + n, get_policy()); 36712872Sgabeblack@google.com } 36812872Sgabeblack@google.com ThisType 36912872Sgabeblack@google.com operator - (difference_type n) const 37012872Sgabeblack@google.com { 37112872Sgabeblack@google.com return ThisType(it_ - n, get_policy()); 37212872Sgabeblack@google.com } 37312872Sgabeblack@google.com 37412872Sgabeblack@google.com ThisType & 37512872Sgabeblack@google.com operator += (difference_type n) 37612872Sgabeblack@google.com { 37712872Sgabeblack@google.com it_ += n; 37812872Sgabeblack@google.com return *this; 37912872Sgabeblack@google.com } 38012872Sgabeblack@google.com 38112872Sgabeblack@google.com ThisType & 38212872Sgabeblack@google.com operator -= (difference_type n) 38312872Sgabeblack@google.com { 38412872Sgabeblack@google.com it_ -= n; 38512872Sgabeblack@google.com return *this; 38612872Sgabeblack@google.com } 38712872Sgabeblack@google.com 38812872Sgabeblack@google.com bool 38912872Sgabeblack@google.com operator == (const ConstDirectIterator &other) const 39012872Sgabeblack@google.com { 39112872Sgabeblack@google.com return it_ == other.it_; 39212872Sgabeblack@google.com } 39312872Sgabeblack@google.com bool 39412872Sgabeblack@google.com operator != (const ConstDirectIterator &other) const 39512872Sgabeblack@google.com { 39612872Sgabeblack@google.com return it_ != other.it_; 39712872Sgabeblack@google.com } 39812872Sgabeblack@google.com bool 39912872Sgabeblack@google.com operator <= (const ConstDirectIterator &other) const 40012872Sgabeblack@google.com { 40112872Sgabeblack@google.com return it_ <= other.it_; 40212872Sgabeblack@google.com } 40312872Sgabeblack@google.com bool 40412872Sgabeblack@google.com operator >= (const ConstDirectIterator &other) const 40512872Sgabeblack@google.com { 40612872Sgabeblack@google.com return it_ >= other.it_; 40712872Sgabeblack@google.com } 40812872Sgabeblack@google.com bool 40912872Sgabeblack@google.com operator < (const ConstDirectIterator &other) const 41012872Sgabeblack@google.com { 41112872Sgabeblack@google.com return it_ < other.it_; 41212872Sgabeblack@google.com } 41312872Sgabeblack@google.com bool 41412872Sgabeblack@google.com operator > (const ConstDirectIterator &other) const 41512872Sgabeblack@google.com { 41612872Sgabeblack@google.com return it_ > other.it_; 41712872Sgabeblack@google.com } 41812872Sgabeblack@google.com 41912872Sgabeblack@google.com reference 42012872Sgabeblack@google.com operator * () const 42112872Sgabeblack@google.com { 42212872Sgabeblack@google.com return *Policy::get(static_cast<ElementType *>((void *)*it_)); 42312872Sgabeblack@google.com } 42412872Sgabeblack@google.com pointer 42512872Sgabeblack@google.com operator -> () const 42612872Sgabeblack@google.com { 42712872Sgabeblack@google.com return Policy::get(static_cast<ElementType *>((void *)*it_)); 42812872Sgabeblack@google.com } 42912872Sgabeblack@google.com reference 43012872Sgabeblack@google.com operator [] (difference_type n) const 43112872Sgabeblack@google.com { 43212872Sgabeblack@google.com return *Policy::get(static_cast<ElementType *>((void *)it_[n])); 43312872Sgabeblack@google.com } 43412872Sgabeblack@google.com 43512872Sgabeblack@google.com difference_type 43612872Sgabeblack@google.com operator - (ConstDirectIterator const &other) const 43712872Sgabeblack@google.com { 43812872Sgabeblack@google.com return it_ - other.it_; 43912872Sgabeblack@google.com } 44012852Sgabeblack@google.com}; 44112852Sgabeblack@google.com 44212852Sgabeblack@google.comtemplate <typename T> 44312852Sgabeblack@google.comclass sc_vector : public sc_vector_base 44412852Sgabeblack@google.com{ 44512852Sgabeblack@google.com public: 44612852Sgabeblack@google.com using sc_vector_base::size_type; 44712852Sgabeblack@google.com typedef sc_vector_iter<T> iterator; 44812852Sgabeblack@google.com typedef sc_vector_iter<const T> const_iterator; 44912852Sgabeblack@google.com 45013271Sgabeblack@google.com sc_vector() : sc_vector_base(::sc_core::sc_gen_unique_name("vector")) {} 45113271Sgabeblack@google.com explicit sc_vector(const char *_name) : sc_vector_base(_name) {} 45213271Sgabeblack@google.com sc_vector(const char *_name, size_type _size) : sc_vector_base(_name) 45312852Sgabeblack@google.com { 45413271Sgabeblack@google.com init(_size); 45512852Sgabeblack@google.com } 45612852Sgabeblack@google.com template <typename Creator> 45713271Sgabeblack@google.com sc_vector(const char *_name, size_type _size, Creator creator) : 45813271Sgabeblack@google.com sc_vector_base(_name) 45912852Sgabeblack@google.com { 46013271Sgabeblack@google.com init(_size, creator); 46112852Sgabeblack@google.com } 46213271Sgabeblack@google.com virtual ~sc_vector() { clear(); } 46312852Sgabeblack@google.com 46412852Sgabeblack@google.com void 46513271Sgabeblack@google.com init(size_type _size) 46612852Sgabeblack@google.com { 46713271Sgabeblack@google.com init(_size, &sc_vector<T>::create_element); 46812852Sgabeblack@google.com } 46912852Sgabeblack@google.com static T * 47013271Sgabeblack@google.com create_element(const char *_name, size_type index) 47112852Sgabeblack@google.com { 47213271Sgabeblack@google.com return new T(_name); 47312852Sgabeblack@google.com } 47412852Sgabeblack@google.com 47512852Sgabeblack@google.com template <typename Creator> 47612852Sgabeblack@google.com void 47713271Sgabeblack@google.com init(size_type _size, Creator creator) 47812852Sgabeblack@google.com { 47913271Sgabeblack@google.com forceParent(); 48013271Sgabeblack@google.com try { 48113271Sgabeblack@google.com for (size_type i = 0; i < _size; i++) { 48213271Sgabeblack@google.com // XXX The name and scope of these objects needs to be handled 48313271Sgabeblack@google.com // specially. 48413271Sgabeblack@google.com T *p = creator(sc_gen_unique_name(basename()), i); 48513271Sgabeblack@google.com objs.push_back(p); 48613271Sgabeblack@google.com } 48713271Sgabeblack@google.com } catch (...) { 48813271Sgabeblack@google.com unforceParent(); 48913271Sgabeblack@google.com clear(); 49013271Sgabeblack@google.com throw; 49113271Sgabeblack@google.com } 49213271Sgabeblack@google.com unforceParent(); 49313271Sgabeblack@google.com } 49413271Sgabeblack@google.com 49513271Sgabeblack@google.com T &operator [] (size_type index) { return *static_cast<T *>(objs[index]); } 49613271Sgabeblack@google.com const T & 49713271Sgabeblack@google.com operator [] (size_type index) const 49813271Sgabeblack@google.com { 49913271Sgabeblack@google.com return *static_cast<const T *>(objs[index]); 50012852Sgabeblack@google.com } 50112852Sgabeblack@google.com 50212852Sgabeblack@google.com T & 50313271Sgabeblack@google.com at(size_type index) 50412852Sgabeblack@google.com { 50513271Sgabeblack@google.com this->checkIndex(index); 50613271Sgabeblack@google.com return *static_cast<T *>(objs[index]); 50712852Sgabeblack@google.com } 50812852Sgabeblack@google.com const T & 50913271Sgabeblack@google.com at(size_type index) const 51012852Sgabeblack@google.com { 51113271Sgabeblack@google.com this->checkIndex(index); 51213271Sgabeblack@google.com return *static_cast<const T *>(objs[index]); 51312852Sgabeblack@google.com } 51412852Sgabeblack@google.com 51513271Sgabeblack@google.com iterator begin() { return objs.begin(); } 51613271Sgabeblack@google.com iterator end() { return objs.end(); } 51713271Sgabeblack@google.com const_iterator begin() const { return objs.begin(); } 51813271Sgabeblack@google.com const_iterator end() const { return objs.end(); } 51913271Sgabeblack@google.com const_iterator cbegin() const { return objs.begin(); } 52013271Sgabeblack@google.com const_iterator cend() const { return objs.end(); } 52112852Sgabeblack@google.com 52212852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 52312852Sgabeblack@google.com iterator 52413271Sgabeblack@google.com bind(sc_vector_assembly<ContainerType, ArgumentType> c) 52512852Sgabeblack@google.com { 52613271Sgabeblack@google.com return bind(c.begin(), c.end()); 52712852Sgabeblack@google.com } 52812852Sgabeblack@google.com 52912852Sgabeblack@google.com template <typename BindableContainer> 53012852Sgabeblack@google.com iterator 53113271Sgabeblack@google.com bind(BindableContainer &c) 53212852Sgabeblack@google.com { 53313271Sgabeblack@google.com return bind(c.begin(), c.end()); 53412852Sgabeblack@google.com } 53512852Sgabeblack@google.com 53612852Sgabeblack@google.com template <typename BindableIterator> 53712852Sgabeblack@google.com iterator 53813271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last) 53912852Sgabeblack@google.com { 54013271Sgabeblack@google.com return bind(first, last, this->begin()); 54112852Sgabeblack@google.com } 54212852Sgabeblack@google.com 54312852Sgabeblack@google.com template <typename BindableIterator> 54412852Sgabeblack@google.com iterator 54513271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last, iterator from) 54612852Sgabeblack@google.com { 54713271Sgabeblack@google.com if (!size() || from == end() || first == last) 54813271Sgabeblack@google.com reportEmpty(kind(), from == end()); 54913271Sgabeblack@google.com 55013271Sgabeblack@google.com while (from != end() && first != last) 55113271Sgabeblack@google.com (*from++).bind(*first++); 55213271Sgabeblack@google.com return from; 55312852Sgabeblack@google.com } 55412852Sgabeblack@google.com 55512852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 55612852Sgabeblack@google.com iterator 55712852Sgabeblack@google.com operator () (sc_vector_assembly<ContainerType, ArgumentType> c) 55812852Sgabeblack@google.com { 55913271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 56012852Sgabeblack@google.com } 56112852Sgabeblack@google.com 56212852Sgabeblack@google.com template <typename ArgumentContainer> 56312852Sgabeblack@google.com iterator 56413271Sgabeblack@google.com operator () (ArgumentContainer &c) 56512852Sgabeblack@google.com { 56613271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 56712852Sgabeblack@google.com } 56812852Sgabeblack@google.com 56912852Sgabeblack@google.com template <typename ArgumentIterator> 57012852Sgabeblack@google.com iterator 57113271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last) 57212852Sgabeblack@google.com { 57313271Sgabeblack@google.com return (*this)(first, last, this->begin()); 57412852Sgabeblack@google.com } 57512852Sgabeblack@google.com 57612852Sgabeblack@google.com template <typename ArgumentIterator> 57712852Sgabeblack@google.com iterator 57813271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last, iterator from) 57912852Sgabeblack@google.com { 58013271Sgabeblack@google.com if (!size() || from == end() || first == last) 58113271Sgabeblack@google.com reportEmpty(kind(), from == end()); 58213271Sgabeblack@google.com 58313271Sgabeblack@google.com while (from != end() && first != last) 58413271Sgabeblack@google.com (*from++)(*first++); 58513271Sgabeblack@google.com return from; 58612852Sgabeblack@google.com } 58712852Sgabeblack@google.com 58812852Sgabeblack@google.com private: 58912852Sgabeblack@google.com // Disabled 59012852Sgabeblack@google.com sc_vector(const sc_vector &) : sc_vector_base() {} 59112852Sgabeblack@google.com sc_vector &operator = (const sc_vector &) { return *this; } 59213271Sgabeblack@google.com 59313271Sgabeblack@google.com void 59413271Sgabeblack@google.com clear() 59513271Sgabeblack@google.com { 59613271Sgabeblack@google.com for (auto obj: objs) 59713271Sgabeblack@google.com delete static_cast<T *>(obj); 59813271Sgabeblack@google.com } 59913271Sgabeblack@google.com 60013271Sgabeblack@google.com template <typename, typename> 60113271Sgabeblack@google.com friend class sc_vector_assembly; 60213271Sgabeblack@google.com 60313271Sgabeblack@google.com sc_object * 60413271Sgabeblack@google.com objectCast(void *ptr) const 60513271Sgabeblack@google.com { 60613271Sgabeblack@google.com return implicitCast(static_cast<T *>(ptr)); 60713271Sgabeblack@google.com } 60812852Sgabeblack@google.com}; 60912852Sgabeblack@google.com 61012852Sgabeblack@google.comtemplate <typename T, typename MT> 61112852Sgabeblack@google.comclass sc_vector_assembly 61212852Sgabeblack@google.com{ 61312852Sgabeblack@google.com public: 61412852Sgabeblack@google.com friend sc_vector_assembly<T, MT> sc_assemble_vector<>( 61512872Sgabeblack@google.com sc_vector<T> &, MT (T::*)); 61612852Sgabeblack@google.com 61712852Sgabeblack@google.com typedef size_t size_type; 61812872Sgabeblack@google.com typedef sc_vector_iter<T, sc_member_access<T, MT> > iterator; 61912872Sgabeblack@google.com typedef sc_vector_iter< 62012872Sgabeblack@google.com const T, sc_member_access<const T, const MT> > const_iterator; 62112872Sgabeblack@google.com typedef MT (T::*MemberType); 62212852Sgabeblack@google.com 62313271Sgabeblack@google.com sc_vector_assembly(const sc_vector_assembly &other) : 62413271Sgabeblack@google.com vec_(other.vec_), ptr_(other.ptr_) 62513271Sgabeblack@google.com {} 62612852Sgabeblack@google.com 62712872Sgabeblack@google.com iterator begin() { return iterator(vec_->begin().it_, ptr_); } 62812872Sgabeblack@google.com iterator end() { return iterator(vec_->end().it_, ptr_); } 62912852Sgabeblack@google.com 63012852Sgabeblack@google.com const_iterator 63112852Sgabeblack@google.com cbegin() const 63212852Sgabeblack@google.com { 63312872Sgabeblack@google.com return const_iterator(vec_->begin().it_, ptr_); 63412852Sgabeblack@google.com } 63512852Sgabeblack@google.com const_iterator 63612852Sgabeblack@google.com cend() const 63712852Sgabeblack@google.com { 63812872Sgabeblack@google.com return const_iterator(vec_->end().it_, ptr_); 63912852Sgabeblack@google.com } 64012852Sgabeblack@google.com 64112872Sgabeblack@google.com const_iterator 64212872Sgabeblack@google.com begin() const 64312852Sgabeblack@google.com { 64412872Sgabeblack@google.com return const_iterator(vec_->begin().it_, ptr_); 64512852Sgabeblack@google.com } 64612872Sgabeblack@google.com const_iterator 64712872Sgabeblack@google.com end() const 64812872Sgabeblack@google.com { 64912872Sgabeblack@google.com return const_iterator(vec_->end().it_, ptr_); 65012872Sgabeblack@google.com } 65112872Sgabeblack@google.com 65212872Sgabeblack@google.com size_type size() const { return vec_->size(); } 65312872Sgabeblack@google.com 65412852Sgabeblack@google.com std::vector<sc_object *> 65512852Sgabeblack@google.com get_elements() const 65612852Sgabeblack@google.com { 65713271Sgabeblack@google.com std::vector<sc_object *> ret; 65813271Sgabeblack@google.com for (const_iterator it = begin(); it != end(); it++) { 65913271Sgabeblack@google.com sc_object *obj_ptr = vec_->objectCast(const_cast<MT *>(&*it)); 66013271Sgabeblack@google.com 66113271Sgabeblack@google.com if (obj_ptr) 66213271Sgabeblack@google.com ret.push_back(obj_ptr); 66313271Sgabeblack@google.com } 66413271Sgabeblack@google.com return ret; 66512852Sgabeblack@google.com } 66612852Sgabeblack@google.com 66712852Sgabeblack@google.com typename iterator::reference 66812872Sgabeblack@google.com operator [] (size_type i) 66912852Sgabeblack@google.com { 67012872Sgabeblack@google.com return (*vec_)[i].*ptr_; 67112852Sgabeblack@google.com } 67212852Sgabeblack@google.com typename const_iterator::reference 67312872Sgabeblack@google.com operator [] (size_type i) const 67412852Sgabeblack@google.com { 67512872Sgabeblack@google.com return (*vec_)[i].*ptr_; 67612852Sgabeblack@google.com } 67712852Sgabeblack@google.com 67812852Sgabeblack@google.com typename iterator::reference 67912872Sgabeblack@google.com at(size_type i) 68012852Sgabeblack@google.com { 68112872Sgabeblack@google.com return vec_->at(i).*ptr_; 68212852Sgabeblack@google.com } 68312852Sgabeblack@google.com typename const_iterator::reference 68412872Sgabeblack@google.com at(size_type i) const 68512852Sgabeblack@google.com { 68612872Sgabeblack@google.com return vec_->at(i).*ptr_; 68712852Sgabeblack@google.com } 68812852Sgabeblack@google.com 68912852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 69012852Sgabeblack@google.com iterator 69113271Sgabeblack@google.com bind(sc_vector_assembly<ContainerType, ArgumentType> c) 69212852Sgabeblack@google.com { 69313271Sgabeblack@google.com return bind(c.begin(), c.end()); 69412852Sgabeblack@google.com } 69512852Sgabeblack@google.com 69612852Sgabeblack@google.com template <typename BindableContainer> 69712852Sgabeblack@google.com iterator 69813271Sgabeblack@google.com bind(BindableContainer &c) 69912852Sgabeblack@google.com { 70013271Sgabeblack@google.com return bind(c.begin(), c.end()); 70112852Sgabeblack@google.com } 70212852Sgabeblack@google.com 70312852Sgabeblack@google.com template <typename BindableIterator> 70412852Sgabeblack@google.com iterator 70513271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last) 70612852Sgabeblack@google.com { 70713271Sgabeblack@google.com return bind(first, last, this->begin()); 70812852Sgabeblack@google.com } 70912852Sgabeblack@google.com 71012852Sgabeblack@google.com template <typename BindableIterator> 71112852Sgabeblack@google.com iterator 71213271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last, iterator from) 71312852Sgabeblack@google.com { 71413271Sgabeblack@google.com if (!size() || from == end() || first == last) 71513271Sgabeblack@google.com vec_->reportEmpty("sc_vector_assembly", from == end()); 71613271Sgabeblack@google.com 71713271Sgabeblack@google.com while (from != end() && first != last) 71813271Sgabeblack@google.com (*from++).bind(*first++); 71913271Sgabeblack@google.com return from; 72012852Sgabeblack@google.com } 72112852Sgabeblack@google.com 72212852Sgabeblack@google.com template <typename BindableIterator> 72312852Sgabeblack@google.com iterator 72413271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last, 72513271Sgabeblack@google.com typename sc_vector<T>::iterator from) 72612852Sgabeblack@google.com { 72713271Sgabeblack@google.com return bind(first, last, iterator(from.it_, ptr_)); 72812852Sgabeblack@google.com } 72912852Sgabeblack@google.com 73012852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 73112852Sgabeblack@google.com iterator 73213271Sgabeblack@google.com operator () (sc_vector_assembly<ContainerType, ArgumentType> c) 73312852Sgabeblack@google.com { 73413271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 73512852Sgabeblack@google.com } 73612852Sgabeblack@google.com 73712852Sgabeblack@google.com template <typename ArgumentContainer> 73812852Sgabeblack@google.com iterator 73913271Sgabeblack@google.com operator () (ArgumentContainer &c) 74012852Sgabeblack@google.com { 74113271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 74212852Sgabeblack@google.com } 74312852Sgabeblack@google.com 74412852Sgabeblack@google.com template <typename ArgumentIterator> 74512852Sgabeblack@google.com iterator 74613271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last) 74712852Sgabeblack@google.com { 74813271Sgabeblack@google.com return (*this)(first, last, this->begin()); 74912852Sgabeblack@google.com } 75012852Sgabeblack@google.com 75112852Sgabeblack@google.com template <typename ArgumentIterator> 75212852Sgabeblack@google.com iterator 75313271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last, iterator from) 75412852Sgabeblack@google.com { 75513271Sgabeblack@google.com if (!size() || from == end() || first == last) 75613271Sgabeblack@google.com vec_->reportEmpty("sc_vector_assembly", from == end()); 75713271Sgabeblack@google.com 75813271Sgabeblack@google.com while (from != end() && first != last) 75913271Sgabeblack@google.com (*from++)(*first++); 76013271Sgabeblack@google.com return from; 76112852Sgabeblack@google.com } 76212852Sgabeblack@google.com 76312852Sgabeblack@google.com template <typename ArgumentIterator> 76412852Sgabeblack@google.com iterator 76513271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last, 76613271Sgabeblack@google.com typename sc_vector<T>::iterator from) 76712852Sgabeblack@google.com { 76813271Sgabeblack@google.com return (*this)(first, last, iterator(from.it_, ptr_)); 76912852Sgabeblack@google.com } 77012852Sgabeblack@google.com 77112852Sgabeblack@google.com private: 77212872Sgabeblack@google.com sc_vector_assembly(sc_vector<T> &v, MemberType ptr) : 77312872Sgabeblack@google.com vec_(&v), ptr_(ptr) 77412872Sgabeblack@google.com {} 77512872Sgabeblack@google.com 77612872Sgabeblack@google.com sc_vector<T> *vec_; 77712872Sgabeblack@google.com MemberType ptr_; 77812852Sgabeblack@google.com}; 77912852Sgabeblack@google.com 78012852Sgabeblack@google.comtemplate <typename T, typename MT> 78112852Sgabeblack@google.comsc_vector_assembly<T, MT> 78212872Sgabeblack@google.comsc_assemble_vector(sc_vector<T> &v, MT (T::*ptr)) 78312852Sgabeblack@google.com{ 78412872Sgabeblack@google.com return sc_vector_assembly<T, MT>(v, ptr); 78512852Sgabeblack@google.com} 78612852Sgabeblack@google.com 78712852Sgabeblack@google.com} // namespace sc_core 78812852Sgabeblack@google.com 78912852Sgabeblack@google.com#endif //__SYSTEMC_EXT_UTIL_SC_VECTOR_HH__ 790