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" 6013322Sgabeblack@google.com#include "messages.hh" 6112852Sgabeblack@google.com 6212872Sgabeblack@google.comnamespace sc_gem5 6312872Sgabeblack@google.com{ 6412872Sgabeblack@google.com 6512872Sgabeblack@google.com// Goop for supporting sc_vector_iter, simplified from the Accellera version. 6612872Sgabeblack@google.com 6712872Sgabeblack@google.com#if __cplusplus >= 201103L 6812872Sgabeblack@google.com 6912872Sgabeblack@google.comusing std::enable_if; 7012872Sgabeblack@google.comusing std::remove_const; 7112872Sgabeblack@google.comusing std::is_same; 7212872Sgabeblack@google.comusing std::is_const; 7312872Sgabeblack@google.com 7412872Sgabeblack@google.com#else 7512872Sgabeblack@google.com 7612872Sgabeblack@google.comtemplate<bool Cond, typename T=void> 7712872Sgabeblack@google.comstruct enable_if 7812872Sgabeblack@google.com{}; 7912872Sgabeblack@google.com 8012872Sgabeblack@google.comtemplate<typename T> 8112872Sgabeblack@google.comstruct enable_if<true, T> 8212872Sgabeblack@google.com{ 8312872Sgabeblack@google.com typedef T type; 8412872Sgabeblack@google.com}; 8512872Sgabeblack@google.com 8612872Sgabeblack@google.comtemplate <typename T> 8712872Sgabeblack@google.comstruct remove_const 8812872Sgabeblack@google.com{ 8912872Sgabeblack@google.com typedef T type; 9012872Sgabeblack@google.com}; 9112872Sgabeblack@google.comtemplate <typename T> 9212872Sgabeblack@google.comstruct remove_const<const T> 9312872Sgabeblack@google.com{ 9412872Sgabeblack@google.com typedef T type; 9512872Sgabeblack@google.com}; 9612872Sgabeblack@google.com 9712872Sgabeblack@google.comtemplate <typename T, typename U> 9812872Sgabeblack@google.comstruct is_same 9912872Sgabeblack@google.com{ 10012872Sgabeblack@google.com static const bool value = false; 10112872Sgabeblack@google.com}; 10212872Sgabeblack@google.comtemplate <typename T> 10312872Sgabeblack@google.comstruct is_same<T, T> 10412872Sgabeblack@google.com{ 10512872Sgabeblack@google.com static const bool value = true; 10612872Sgabeblack@google.com}; 10712872Sgabeblack@google.com 10812872Sgabeblack@google.comtemplate <typename T> 10912872Sgabeblack@google.comstruct is_const 11012872Sgabeblack@google.com{ 11112872Sgabeblack@google.com static const bool value = false; 11212872Sgabeblack@google.com}; 11312872Sgabeblack@google.comtemplate <typename T> 11412872Sgabeblack@google.comstruct is_const<const T> 11512872Sgabeblack@google.com{ 11612872Sgabeblack@google.com static const bool value = true; 11712872Sgabeblack@google.com}; 11812872Sgabeblack@google.com 11912872Sgabeblack@google.com#endif 12012872Sgabeblack@google.com 12112872Sgabeblack@google.comtemplate <typename CT, typename T> 12212872Sgabeblack@google.comstruct is_more_const 12312872Sgabeblack@google.com{ 12412872Sgabeblack@google.com static const bool value = 12512872Sgabeblack@google.com is_same<typename remove_const<CT>::type, 12612872Sgabeblack@google.com typename remove_const<T>::type>::value && 12712872Sgabeblack@google.com is_const<CT>::value >= is_const<T>::value; 12812872Sgabeblack@google.com}; 12912872Sgabeblack@google.com 13012872Sgabeblack@google.comstruct special_result 13112872Sgabeblack@google.com{}; 13212872Sgabeblack@google.com 13312872Sgabeblack@google.comtemplate <typename T> 13412872Sgabeblack@google.comstruct remove_special_fptr 13512872Sgabeblack@google.com{}; 13612872Sgabeblack@google.com 13712872Sgabeblack@google.comtemplate <typename T> 13812872Sgabeblack@google.comstruct remove_special_fptr<special_result & (*)(T)> 13912872Sgabeblack@google.com{ 14012872Sgabeblack@google.com typedef T type; 14112872Sgabeblack@google.com}; 14212872Sgabeblack@google.com 14312872Sgabeblack@google.com#define SC_RPTYPE_(Type) \ 14412872Sgabeblack@google.com ::sc_gem5::remove_special_fptr< \ 14512872Sgabeblack@google.com ::sc_gem5::special_result & (*) Type>::type::value 14612872Sgabeblack@google.com 14712872Sgabeblack@google.com#define SC_ENABLE_IF_(Cond) \ 14812872Sgabeblack@google.com typename ::sc_gem5::enable_if<SC_RPTYPE_(Cond)>::type * = NULL 14912872Sgabeblack@google.com 15012872Sgabeblack@google.com} // namespace sc_gem5 15112872Sgabeblack@google.com 15212852Sgabeblack@google.comnamespace sc_core 15312852Sgabeblack@google.com{ 15412852Sgabeblack@google.com 15512852Sgabeblack@google.comtemplate <typename T, typename MT> 15612852Sgabeblack@google.comclass sc_vector_assembly; 15712852Sgabeblack@google.com 15812852Sgabeblack@google.comtemplate <typename T> 15912852Sgabeblack@google.comclass sc_vector; 16012852Sgabeblack@google.com 16112852Sgabeblack@google.comtemplate <typename T, typename MT> 16212852Sgabeblack@google.comsc_vector_assembly<T, MT> sc_assemble_vector( 16312852Sgabeblack@google.com sc_vector<T> &, MT(T::* member_ptr)); 16412852Sgabeblack@google.com 16512852Sgabeblack@google.comclass sc_vector_base : public sc_object 16612852Sgabeblack@google.com{ 16712852Sgabeblack@google.com public: 16812852Sgabeblack@google.com typedef size_t size_type; 16912852Sgabeblack@google.com 17013271Sgabeblack@google.com sc_vector_base(const char *_name) : sc_object(_name) {} 17113271Sgabeblack@google.com 17212852Sgabeblack@google.com virtual const char *kind() const { return "sc_vector"; } 17312852Sgabeblack@google.com size_type size() const; 17412852Sgabeblack@google.com const std::vector<sc_object *> &get_elements() const; 17513271Sgabeblack@google.com 17613271Sgabeblack@google.com protected: 17713271Sgabeblack@google.com std::vector<void *> objs; 17813271Sgabeblack@google.com 17913271Sgabeblack@google.com // What's returned by get_elements, which really returns the elemenets 18013271Sgabeblack@google.com // which are also objects. 18113271Sgabeblack@google.com mutable std::vector<sc_object *> elements; 18213271Sgabeblack@google.com 18313271Sgabeblack@google.com sc_object *implicitCast(sc_object *p) const { return p; } 18413271Sgabeblack@google.com sc_object *implicitCast(...) const 18513271Sgabeblack@google.com { 18613322Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_VECTOR_NONOBJECT_ELEMENTS_, name()); 18713271Sgabeblack@google.com return nullptr; 18813271Sgabeblack@google.com } 18913271Sgabeblack@google.com virtual sc_object *objectCast(void *) const = 0; 19013271Sgabeblack@google.com 19113271Sgabeblack@google.com void checkIndex(size_type index) const; 19213271Sgabeblack@google.com void forceParent() const; 19313271Sgabeblack@google.com void unforceParent() const; 19413271Sgabeblack@google.com 19513271Sgabeblack@google.com void reportEmpty(const char *kind_, bool empty_dest) const; 19612852Sgabeblack@google.com}; 19712852Sgabeblack@google.com 19812872Sgabeblack@google.com 19912872Sgabeblack@google.com/* 20012872Sgabeblack@google.com * Non-standard iterator access adapters. Without using these, the classes as 20112872Sgabeblack@google.com * defined in the standard won't compile because of redundant bind() overloads. 20212872Sgabeblack@google.com */ 20312872Sgabeblack@google.com 20412872Sgabeblack@google.comtemplate <typename Element> 20512872Sgabeblack@google.comclass sc_direct_access 20612872Sgabeblack@google.com{ 20712872Sgabeblack@google.com public: 20812872Sgabeblack@google.com typedef Element ElementType; 20912872Sgabeblack@google.com typedef ElementType Type; 21012872Sgabeblack@google.com typedef typename sc_gem5::remove_const<ElementType>::type PlainType; 21112872Sgabeblack@google.com 21212872Sgabeblack@google.com typedef sc_direct_access<ElementType> Policy; 21312872Sgabeblack@google.com typedef sc_direct_access<PlainType> NonConstPolicy; 21412872Sgabeblack@google.com typedef sc_direct_access<const PlainType> ConstPolicy; 21512872Sgabeblack@google.com 21612872Sgabeblack@google.com sc_direct_access() {} 21712872Sgabeblack@google.com sc_direct_access(const NonConstPolicy &) {} 21812872Sgabeblack@google.com 21912872Sgabeblack@google.com template <typename U> 22012872Sgabeblack@google.com sc_direct_access(const U &, 22112872Sgabeblack@google.com SC_ENABLE_IF_(( 22212872Sgabeblack@google.com sc_gem5::is_more_const< 22312872Sgabeblack@google.com ElementType, typename U::Policy::ElementType> 22412872Sgabeblack@google.com )) 22512872Sgabeblack@google.com ) 22612872Sgabeblack@google.com {} 22712872Sgabeblack@google.com 22812872Sgabeblack@google.com ElementType * 22912872Sgabeblack@google.com get(ElementType *this_) const 23012872Sgabeblack@google.com { 23112872Sgabeblack@google.com return this_; 23212872Sgabeblack@google.com } 23312872Sgabeblack@google.com}; 23412872Sgabeblack@google.com 23512872Sgabeblack@google.comtemplate <typename Element, typename Access> 23612872Sgabeblack@google.comclass sc_member_access 23712872Sgabeblack@google.com{ 23812872Sgabeblack@google.com public: 23912872Sgabeblack@google.com template <typename, typename> 24012872Sgabeblack@google.com friend class sc_member_access; 24112872Sgabeblack@google.com 24212872Sgabeblack@google.com typedef Element ElementType; 24312872Sgabeblack@google.com typedef Access AccessType; 24412872Sgabeblack@google.com typedef AccessType (ElementType::*MemberType); 24512872Sgabeblack@google.com typedef AccessType Type; 24612872Sgabeblack@google.com typedef typename sc_gem5::remove_const<AccessType>::type PlainType; 24712872Sgabeblack@google.com typedef typename sc_gem5::remove_const<ElementType>::type PlainElemType; 24812872Sgabeblack@google.com 24912872Sgabeblack@google.com typedef sc_member_access<ElementType, AccessType> Policy; 25012872Sgabeblack@google.com typedef sc_member_access<PlainElemType, PlainType> NonConstPolicy; 25112872Sgabeblack@google.com typedef sc_member_access<const PlainElemType, const PlainType> ConstPolicy; 25212872Sgabeblack@google.com 25312872Sgabeblack@google.com sc_member_access(MemberType ptr) : ptr_(ptr) {} 25412872Sgabeblack@google.com sc_member_access(const NonConstPolicy &other) : ptr_(other.ptr_) {} 25512872Sgabeblack@google.com 25612872Sgabeblack@google.com AccessType *get(ElementType *this_) const { return &(this_->*ptr_); } 25712872Sgabeblack@google.com 25812872Sgabeblack@google.com private: 25912872Sgabeblack@google.com MemberType ptr_; 26012872Sgabeblack@google.com}; 26112872Sgabeblack@google.com 26212872Sgabeblack@google.comtemplate <typename Element, 26312872Sgabeblack@google.com typename AccessPolicy=sc_direct_access<Element> > 26412852Sgabeblack@google.comclass sc_vector_iter : 26512872Sgabeblack@google.com public std::iterator<std::random_access_iterator_tag, 26612872Sgabeblack@google.com typename AccessPolicy::Type>, 26712872Sgabeblack@google.com private AccessPolicy 26812852Sgabeblack@google.com{ 26912872Sgabeblack@google.com private: 27012872Sgabeblack@google.com typedef Element ElementType; 27112872Sgabeblack@google.com typedef typename AccessPolicy::Policy Policy; 27212872Sgabeblack@google.com typedef typename AccessPolicy::NonConstPolicy NonConstPolicy; 27312872Sgabeblack@google.com typedef typename AccessPolicy::ConstPolicy ConstPolicy; 27412872Sgabeblack@google.com typedef typename Policy::Type AccessType; 27512872Sgabeblack@google.com 27612872Sgabeblack@google.com typedef typename sc_gem5::remove_const<ElementType>::type PlainType; 27712872Sgabeblack@google.com typedef const PlainType ConstPlainType; 27812872Sgabeblack@google.com typedef typename sc_direct_access<PlainType>::ConstPolicy 27912872Sgabeblack@google.com ConstDirectPolicy; 28012872Sgabeblack@google.com 28112872Sgabeblack@google.com friend class sc_vector<PlainType>; 28212872Sgabeblack@google.com template <typename, typename> 28312872Sgabeblack@google.com friend class sc_vector_assembly; 28412872Sgabeblack@google.com template <typename, typename> 28512872Sgabeblack@google.com friend class sc_vector_iter; 28612872Sgabeblack@google.com 28712872Sgabeblack@google.com typedef std::iterator<std::random_access_iterator_tag, AccessType> 28812872Sgabeblack@google.com BaseType; 28912872Sgabeblack@google.com typedef sc_vector_iter ThisType; 29012872Sgabeblack@google.com typedef sc_vector<PlainType> VectorType; 29112872Sgabeblack@google.com typedef std::vector<void *> StorageType; 29212872Sgabeblack@google.com 29312872Sgabeblack@google.com template <typename U> 29412872Sgabeblack@google.com struct SelectIter 29512872Sgabeblack@google.com { 29612872Sgabeblack@google.com typedef typename std::vector<void *>::iterator type; 29712872Sgabeblack@google.com }; 29812872Sgabeblack@google.com template <typename U> 29912872Sgabeblack@google.com struct SelectIter<const U> 30012872Sgabeblack@google.com { 30112872Sgabeblack@google.com typedef typename std::vector<void *>::const_iterator type; 30212872Sgabeblack@google.com }; 30312872Sgabeblack@google.com typedef typename SelectIter<ElementType>::type RawIterator; 30412872Sgabeblack@google.com typedef sc_vector_iter<ConstPlainType, ConstPolicy> ConstIterator; 30512872Sgabeblack@google.com typedef sc_vector_iter<ConstPlainType, ConstDirectPolicy> 30612872Sgabeblack@google.com ConstDirectIterator; 30712872Sgabeblack@google.com 30812872Sgabeblack@google.com RawIterator it_; 30912872Sgabeblack@google.com 31012872Sgabeblack@google.com sc_vector_iter(RawIterator it, Policy acc=Policy()) : 31112872Sgabeblack@google.com Policy(acc), it_(it) 31212872Sgabeblack@google.com {} 31312872Sgabeblack@google.com 31412872Sgabeblack@google.com Policy const &get_policy() const { return *this; } 31512872Sgabeblack@google.com 31612872Sgabeblack@google.com public: 31712852Sgabeblack@google.com // Conforms to Random Access Iterator category. 31812852Sgabeblack@google.com // See ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements] 31912852Sgabeblack@google.com 32012872Sgabeblack@google.com typedef typename BaseType::difference_type difference_type; 32112872Sgabeblack@google.com typedef typename BaseType::reference reference; 32212872Sgabeblack@google.com typedef typename BaseType::pointer pointer; 32312872Sgabeblack@google.com 32412872Sgabeblack@google.com sc_vector_iter() : Policy(), it_() {} 32512872Sgabeblack@google.com 32612872Sgabeblack@google.com template <typename It> 32712872Sgabeblack@google.com sc_vector_iter(const It &it, 32812872Sgabeblack@google.com SC_ENABLE_IF_(( 32912872Sgabeblack@google.com sc_gem5::is_more_const< 33012872Sgabeblack@google.com ElementType, typename It::Policy::ElementType> 33112872Sgabeblack@google.com )) 33212872Sgabeblack@google.com ) : Policy(it.get_policy()), it_(it.it_) 33312872Sgabeblack@google.com {} 33412872Sgabeblack@google.com 33512872Sgabeblack@google.com ThisType & 33612872Sgabeblack@google.com operator ++ () 33712872Sgabeblack@google.com { 33812872Sgabeblack@google.com ++it_; 33912872Sgabeblack@google.com return *this; 34012872Sgabeblack@google.com } 34112872Sgabeblack@google.com ThisType & 34212872Sgabeblack@google.com operator -- () 34312872Sgabeblack@google.com { 34412872Sgabeblack@google.com --it_; 34512872Sgabeblack@google.com return *this; 34612872Sgabeblack@google.com } 34712872Sgabeblack@google.com ThisType 34812872Sgabeblack@google.com operator ++ (int) 34912872Sgabeblack@google.com { 35012872Sgabeblack@google.com ThisType old(*this); 35112872Sgabeblack@google.com ++it_; 35212872Sgabeblack@google.com return old; 35312872Sgabeblack@google.com } 35412872Sgabeblack@google.com ThisType 35512872Sgabeblack@google.com operator -- (int) 35612872Sgabeblack@google.com { 35712872Sgabeblack@google.com ThisType old(*this); 35812872Sgabeblack@google.com --it_; 35912872Sgabeblack@google.com return old; 36012872Sgabeblack@google.com } 36112872Sgabeblack@google.com 36212872Sgabeblack@google.com ThisType 36312872Sgabeblack@google.com operator + (difference_type n) const 36412872Sgabeblack@google.com { 36512872Sgabeblack@google.com return ThisType(it_ + n, get_policy()); 36612872Sgabeblack@google.com } 36712872Sgabeblack@google.com ThisType 36812872Sgabeblack@google.com operator - (difference_type n) const 36912872Sgabeblack@google.com { 37012872Sgabeblack@google.com return ThisType(it_ - n, get_policy()); 37112872Sgabeblack@google.com } 37212872Sgabeblack@google.com 37312872Sgabeblack@google.com ThisType & 37412872Sgabeblack@google.com operator += (difference_type n) 37512872Sgabeblack@google.com { 37612872Sgabeblack@google.com it_ += n; 37712872Sgabeblack@google.com return *this; 37812872Sgabeblack@google.com } 37912872Sgabeblack@google.com 38012872Sgabeblack@google.com ThisType & 38112872Sgabeblack@google.com operator -= (difference_type n) 38212872Sgabeblack@google.com { 38312872Sgabeblack@google.com it_ -= n; 38412872Sgabeblack@google.com return *this; 38512872Sgabeblack@google.com } 38612872Sgabeblack@google.com 38712872Sgabeblack@google.com bool 38812872Sgabeblack@google.com operator == (const ConstDirectIterator &other) const 38912872Sgabeblack@google.com { 39012872Sgabeblack@google.com return it_ == other.it_; 39112872Sgabeblack@google.com } 39212872Sgabeblack@google.com bool 39312872Sgabeblack@google.com operator != (const ConstDirectIterator &other) const 39412872Sgabeblack@google.com { 39512872Sgabeblack@google.com return it_ != other.it_; 39612872Sgabeblack@google.com } 39712872Sgabeblack@google.com bool 39812872Sgabeblack@google.com operator <= (const ConstDirectIterator &other) const 39912872Sgabeblack@google.com { 40012872Sgabeblack@google.com return it_ <= other.it_; 40112872Sgabeblack@google.com } 40212872Sgabeblack@google.com bool 40312872Sgabeblack@google.com operator >= (const ConstDirectIterator &other) const 40412872Sgabeblack@google.com { 40512872Sgabeblack@google.com return it_ >= other.it_; 40612872Sgabeblack@google.com } 40712872Sgabeblack@google.com bool 40812872Sgabeblack@google.com operator < (const ConstDirectIterator &other) const 40912872Sgabeblack@google.com { 41012872Sgabeblack@google.com return it_ < other.it_; 41112872Sgabeblack@google.com } 41212872Sgabeblack@google.com bool 41312872Sgabeblack@google.com operator > (const ConstDirectIterator &other) const 41412872Sgabeblack@google.com { 41512872Sgabeblack@google.com return it_ > other.it_; 41612872Sgabeblack@google.com } 41712872Sgabeblack@google.com 41812872Sgabeblack@google.com reference 41912872Sgabeblack@google.com operator * () const 42012872Sgabeblack@google.com { 42112872Sgabeblack@google.com return *Policy::get(static_cast<ElementType *>((void *)*it_)); 42212872Sgabeblack@google.com } 42312872Sgabeblack@google.com pointer 42412872Sgabeblack@google.com operator -> () const 42512872Sgabeblack@google.com { 42612872Sgabeblack@google.com return Policy::get(static_cast<ElementType *>((void *)*it_)); 42712872Sgabeblack@google.com } 42812872Sgabeblack@google.com reference 42912872Sgabeblack@google.com operator [] (difference_type n) const 43012872Sgabeblack@google.com { 43112872Sgabeblack@google.com return *Policy::get(static_cast<ElementType *>((void *)it_[n])); 43212872Sgabeblack@google.com } 43312872Sgabeblack@google.com 43412872Sgabeblack@google.com difference_type 43512872Sgabeblack@google.com operator - (ConstDirectIterator const &other) const 43612872Sgabeblack@google.com { 43712872Sgabeblack@google.com return it_ - other.it_; 43812872Sgabeblack@google.com } 43912852Sgabeblack@google.com}; 44012852Sgabeblack@google.com 44112852Sgabeblack@google.comtemplate <typename T> 44212852Sgabeblack@google.comclass sc_vector : public sc_vector_base 44312852Sgabeblack@google.com{ 44412852Sgabeblack@google.com public: 44512852Sgabeblack@google.com using sc_vector_base::size_type; 44612852Sgabeblack@google.com typedef sc_vector_iter<T> iterator; 44712852Sgabeblack@google.com typedef sc_vector_iter<const T> const_iterator; 44812852Sgabeblack@google.com 44913271Sgabeblack@google.com sc_vector() : sc_vector_base(::sc_core::sc_gen_unique_name("vector")) {} 45013271Sgabeblack@google.com explicit sc_vector(const char *_name) : sc_vector_base(_name) {} 45113271Sgabeblack@google.com sc_vector(const char *_name, size_type _size) : sc_vector_base(_name) 45212852Sgabeblack@google.com { 45313271Sgabeblack@google.com init(_size); 45412852Sgabeblack@google.com } 45512852Sgabeblack@google.com template <typename Creator> 45613271Sgabeblack@google.com sc_vector(const char *_name, size_type _size, Creator creator) : 45713271Sgabeblack@google.com sc_vector_base(_name) 45812852Sgabeblack@google.com { 45913271Sgabeblack@google.com init(_size, creator); 46012852Sgabeblack@google.com } 46113271Sgabeblack@google.com virtual ~sc_vector() { clear(); } 46212852Sgabeblack@google.com 46312852Sgabeblack@google.com void 46413271Sgabeblack@google.com init(size_type _size) 46512852Sgabeblack@google.com { 46613271Sgabeblack@google.com init(_size, &sc_vector<T>::create_element); 46712852Sgabeblack@google.com } 46812852Sgabeblack@google.com static T * 46913271Sgabeblack@google.com create_element(const char *_name, size_type index) 47012852Sgabeblack@google.com { 47113271Sgabeblack@google.com return new T(_name); 47212852Sgabeblack@google.com } 47312852Sgabeblack@google.com 47412852Sgabeblack@google.com template <typename Creator> 47512852Sgabeblack@google.com void 47613271Sgabeblack@google.com init(size_type _size, Creator creator) 47712852Sgabeblack@google.com { 47813271Sgabeblack@google.com forceParent(); 47913271Sgabeblack@google.com try { 48013271Sgabeblack@google.com for (size_type i = 0; i < _size; i++) { 48113271Sgabeblack@google.com // XXX The name and scope of these objects needs to be handled 48213271Sgabeblack@google.com // specially. 48313271Sgabeblack@google.com T *p = creator(sc_gen_unique_name(basename()), i); 48413271Sgabeblack@google.com objs.push_back(p); 48513271Sgabeblack@google.com } 48613271Sgabeblack@google.com } catch (...) { 48713271Sgabeblack@google.com unforceParent(); 48813271Sgabeblack@google.com clear(); 48913271Sgabeblack@google.com throw; 49013271Sgabeblack@google.com } 49113271Sgabeblack@google.com unforceParent(); 49213271Sgabeblack@google.com } 49313271Sgabeblack@google.com 49413271Sgabeblack@google.com T &operator [] (size_type index) { return *static_cast<T *>(objs[index]); } 49513271Sgabeblack@google.com const T & 49613271Sgabeblack@google.com operator [] (size_type index) const 49713271Sgabeblack@google.com { 49813271Sgabeblack@google.com return *static_cast<const T *>(objs[index]); 49912852Sgabeblack@google.com } 50012852Sgabeblack@google.com 50112852Sgabeblack@google.com T & 50213271Sgabeblack@google.com at(size_type index) 50312852Sgabeblack@google.com { 50413271Sgabeblack@google.com this->checkIndex(index); 50513271Sgabeblack@google.com return *static_cast<T *>(objs[index]); 50612852Sgabeblack@google.com } 50712852Sgabeblack@google.com const T & 50813271Sgabeblack@google.com at(size_type index) const 50912852Sgabeblack@google.com { 51013271Sgabeblack@google.com this->checkIndex(index); 51113271Sgabeblack@google.com return *static_cast<const T *>(objs[index]); 51212852Sgabeblack@google.com } 51312852Sgabeblack@google.com 51413271Sgabeblack@google.com iterator begin() { return objs.begin(); } 51513271Sgabeblack@google.com iterator end() { return objs.end(); } 51613271Sgabeblack@google.com const_iterator begin() const { return objs.begin(); } 51713271Sgabeblack@google.com const_iterator end() const { return objs.end(); } 51813271Sgabeblack@google.com const_iterator cbegin() const { return objs.begin(); } 51913271Sgabeblack@google.com const_iterator cend() const { return objs.end(); } 52012852Sgabeblack@google.com 52112852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 52212852Sgabeblack@google.com iterator 52313271Sgabeblack@google.com bind(sc_vector_assembly<ContainerType, ArgumentType> c) 52412852Sgabeblack@google.com { 52513271Sgabeblack@google.com return bind(c.begin(), c.end()); 52612852Sgabeblack@google.com } 52712852Sgabeblack@google.com 52812852Sgabeblack@google.com template <typename BindableContainer> 52912852Sgabeblack@google.com iterator 53013271Sgabeblack@google.com bind(BindableContainer &c) 53112852Sgabeblack@google.com { 53213271Sgabeblack@google.com return bind(c.begin(), c.end()); 53312852Sgabeblack@google.com } 53412852Sgabeblack@google.com 53512852Sgabeblack@google.com template <typename BindableIterator> 53612852Sgabeblack@google.com iterator 53713271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last) 53812852Sgabeblack@google.com { 53913271Sgabeblack@google.com return bind(first, last, this->begin()); 54012852Sgabeblack@google.com } 54112852Sgabeblack@google.com 54212852Sgabeblack@google.com template <typename BindableIterator> 54312852Sgabeblack@google.com iterator 54413271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last, iterator from) 54512852Sgabeblack@google.com { 54613271Sgabeblack@google.com if (!size() || from == end() || first == last) 54713271Sgabeblack@google.com reportEmpty(kind(), from == end()); 54813271Sgabeblack@google.com 54913271Sgabeblack@google.com while (from != end() && first != last) 55013271Sgabeblack@google.com (*from++).bind(*first++); 55113271Sgabeblack@google.com return from; 55212852Sgabeblack@google.com } 55312852Sgabeblack@google.com 55412852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 55512852Sgabeblack@google.com iterator 55612852Sgabeblack@google.com operator () (sc_vector_assembly<ContainerType, ArgumentType> c) 55712852Sgabeblack@google.com { 55813271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 55912852Sgabeblack@google.com } 56012852Sgabeblack@google.com 56112852Sgabeblack@google.com template <typename ArgumentContainer> 56212852Sgabeblack@google.com iterator 56313271Sgabeblack@google.com operator () (ArgumentContainer &c) 56412852Sgabeblack@google.com { 56513271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 56612852Sgabeblack@google.com } 56712852Sgabeblack@google.com 56812852Sgabeblack@google.com template <typename ArgumentIterator> 56912852Sgabeblack@google.com iterator 57013271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last) 57112852Sgabeblack@google.com { 57213271Sgabeblack@google.com return (*this)(first, last, this->begin()); 57312852Sgabeblack@google.com } 57412852Sgabeblack@google.com 57512852Sgabeblack@google.com template <typename ArgumentIterator> 57612852Sgabeblack@google.com iterator 57713271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last, iterator from) 57812852Sgabeblack@google.com { 57913271Sgabeblack@google.com if (!size() || from == end() || first == last) 58013271Sgabeblack@google.com reportEmpty(kind(), from == end()); 58113271Sgabeblack@google.com 58213271Sgabeblack@google.com while (from != end() && first != last) 58313271Sgabeblack@google.com (*from++)(*first++); 58413271Sgabeblack@google.com return from; 58512852Sgabeblack@google.com } 58612852Sgabeblack@google.com 58712852Sgabeblack@google.com private: 58812852Sgabeblack@google.com // Disabled 58913381Sgabeblack@google.com sc_vector(const sc_vector &); 59013381Sgabeblack@google.com sc_vector &operator = (const sc_vector &); 59113271Sgabeblack@google.com 59213271Sgabeblack@google.com void 59313271Sgabeblack@google.com clear() 59413271Sgabeblack@google.com { 59513271Sgabeblack@google.com for (auto obj: objs) 59613271Sgabeblack@google.com delete static_cast<T *>(obj); 59713271Sgabeblack@google.com } 59813271Sgabeblack@google.com 59913271Sgabeblack@google.com template <typename, typename> 60013271Sgabeblack@google.com friend class sc_vector_assembly; 60113271Sgabeblack@google.com 60213271Sgabeblack@google.com sc_object * 60313271Sgabeblack@google.com objectCast(void *ptr) const 60413271Sgabeblack@google.com { 60513271Sgabeblack@google.com return implicitCast(static_cast<T *>(ptr)); 60613271Sgabeblack@google.com } 60712852Sgabeblack@google.com}; 60812852Sgabeblack@google.com 60912852Sgabeblack@google.comtemplate <typename T, typename MT> 61012852Sgabeblack@google.comclass sc_vector_assembly 61112852Sgabeblack@google.com{ 61212852Sgabeblack@google.com public: 61312852Sgabeblack@google.com friend sc_vector_assembly<T, MT> sc_assemble_vector<>( 61412872Sgabeblack@google.com sc_vector<T> &, MT (T::*)); 61512852Sgabeblack@google.com 61612852Sgabeblack@google.com typedef size_t size_type; 61712872Sgabeblack@google.com typedef sc_vector_iter<T, sc_member_access<T, MT> > iterator; 61812872Sgabeblack@google.com typedef sc_vector_iter< 61912872Sgabeblack@google.com const T, sc_member_access<const T, const MT> > const_iterator; 62012872Sgabeblack@google.com typedef MT (T::*MemberType); 62112852Sgabeblack@google.com 62213271Sgabeblack@google.com sc_vector_assembly(const sc_vector_assembly &other) : 62313271Sgabeblack@google.com vec_(other.vec_), ptr_(other.ptr_) 62413271Sgabeblack@google.com {} 62512852Sgabeblack@google.com 62612872Sgabeblack@google.com iterator begin() { return iterator(vec_->begin().it_, ptr_); } 62712872Sgabeblack@google.com iterator end() { return iterator(vec_->end().it_, ptr_); } 62812852Sgabeblack@google.com 62912852Sgabeblack@google.com const_iterator 63012852Sgabeblack@google.com cbegin() const 63112852Sgabeblack@google.com { 63212872Sgabeblack@google.com return const_iterator(vec_->begin().it_, ptr_); 63312852Sgabeblack@google.com } 63412852Sgabeblack@google.com const_iterator 63512852Sgabeblack@google.com cend() const 63612852Sgabeblack@google.com { 63712872Sgabeblack@google.com return const_iterator(vec_->end().it_, ptr_); 63812852Sgabeblack@google.com } 63912852Sgabeblack@google.com 64012872Sgabeblack@google.com const_iterator 64112872Sgabeblack@google.com begin() const 64212852Sgabeblack@google.com { 64312872Sgabeblack@google.com return const_iterator(vec_->begin().it_, ptr_); 64412852Sgabeblack@google.com } 64512872Sgabeblack@google.com const_iterator 64612872Sgabeblack@google.com end() const 64712872Sgabeblack@google.com { 64812872Sgabeblack@google.com return const_iterator(vec_->end().it_, ptr_); 64912872Sgabeblack@google.com } 65012872Sgabeblack@google.com 65112872Sgabeblack@google.com size_type size() const { return vec_->size(); } 65212872Sgabeblack@google.com 65312852Sgabeblack@google.com std::vector<sc_object *> 65412852Sgabeblack@google.com get_elements() const 65512852Sgabeblack@google.com { 65613271Sgabeblack@google.com std::vector<sc_object *> ret; 65713271Sgabeblack@google.com for (const_iterator it = begin(); it != end(); it++) { 65813271Sgabeblack@google.com sc_object *obj_ptr = vec_->objectCast(const_cast<MT *>(&*it)); 65913271Sgabeblack@google.com 66013271Sgabeblack@google.com if (obj_ptr) 66113271Sgabeblack@google.com ret.push_back(obj_ptr); 66213271Sgabeblack@google.com } 66313271Sgabeblack@google.com return ret; 66412852Sgabeblack@google.com } 66512852Sgabeblack@google.com 66612852Sgabeblack@google.com typename iterator::reference 66712872Sgabeblack@google.com operator [] (size_type i) 66812852Sgabeblack@google.com { 66912872Sgabeblack@google.com return (*vec_)[i].*ptr_; 67012852Sgabeblack@google.com } 67112852Sgabeblack@google.com typename const_iterator::reference 67212872Sgabeblack@google.com operator [] (size_type i) const 67312852Sgabeblack@google.com { 67412872Sgabeblack@google.com return (*vec_)[i].*ptr_; 67512852Sgabeblack@google.com } 67612852Sgabeblack@google.com 67712852Sgabeblack@google.com typename iterator::reference 67812872Sgabeblack@google.com at(size_type i) 67912852Sgabeblack@google.com { 68012872Sgabeblack@google.com return vec_->at(i).*ptr_; 68112852Sgabeblack@google.com } 68212852Sgabeblack@google.com typename const_iterator::reference 68312872Sgabeblack@google.com at(size_type i) const 68412852Sgabeblack@google.com { 68512872Sgabeblack@google.com return vec_->at(i).*ptr_; 68612852Sgabeblack@google.com } 68712852Sgabeblack@google.com 68812852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 68912852Sgabeblack@google.com iterator 69013271Sgabeblack@google.com bind(sc_vector_assembly<ContainerType, ArgumentType> c) 69112852Sgabeblack@google.com { 69213271Sgabeblack@google.com return bind(c.begin(), c.end()); 69312852Sgabeblack@google.com } 69412852Sgabeblack@google.com 69512852Sgabeblack@google.com template <typename BindableContainer> 69612852Sgabeblack@google.com iterator 69713271Sgabeblack@google.com bind(BindableContainer &c) 69812852Sgabeblack@google.com { 69913271Sgabeblack@google.com return bind(c.begin(), c.end()); 70012852Sgabeblack@google.com } 70112852Sgabeblack@google.com 70212852Sgabeblack@google.com template <typename BindableIterator> 70312852Sgabeblack@google.com iterator 70413271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last) 70512852Sgabeblack@google.com { 70613271Sgabeblack@google.com return bind(first, last, this->begin()); 70712852Sgabeblack@google.com } 70812852Sgabeblack@google.com 70912852Sgabeblack@google.com template <typename BindableIterator> 71012852Sgabeblack@google.com iterator 71113271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last, iterator from) 71212852Sgabeblack@google.com { 71313271Sgabeblack@google.com if (!size() || from == end() || first == last) 71413271Sgabeblack@google.com vec_->reportEmpty("sc_vector_assembly", from == end()); 71513271Sgabeblack@google.com 71613271Sgabeblack@google.com while (from != end() && first != last) 71713271Sgabeblack@google.com (*from++).bind(*first++); 71813271Sgabeblack@google.com return from; 71912852Sgabeblack@google.com } 72012852Sgabeblack@google.com 72112852Sgabeblack@google.com template <typename BindableIterator> 72212852Sgabeblack@google.com iterator 72313271Sgabeblack@google.com bind(BindableIterator first, BindableIterator last, 72413271Sgabeblack@google.com typename sc_vector<T>::iterator from) 72512852Sgabeblack@google.com { 72613271Sgabeblack@google.com return bind(first, last, iterator(from.it_, ptr_)); 72712852Sgabeblack@google.com } 72812852Sgabeblack@google.com 72912852Sgabeblack@google.com template <typename ContainerType, typename ArgumentType> 73012852Sgabeblack@google.com iterator 73113271Sgabeblack@google.com operator () (sc_vector_assembly<ContainerType, ArgumentType> c) 73212852Sgabeblack@google.com { 73313271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 73412852Sgabeblack@google.com } 73512852Sgabeblack@google.com 73612852Sgabeblack@google.com template <typename ArgumentContainer> 73712852Sgabeblack@google.com iterator 73813271Sgabeblack@google.com operator () (ArgumentContainer &c) 73912852Sgabeblack@google.com { 74013271Sgabeblack@google.com return (*this)(c.begin(), c.end()); 74112852Sgabeblack@google.com } 74212852Sgabeblack@google.com 74312852Sgabeblack@google.com template <typename ArgumentIterator> 74412852Sgabeblack@google.com iterator 74513271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last) 74612852Sgabeblack@google.com { 74713271Sgabeblack@google.com return (*this)(first, last, this->begin()); 74812852Sgabeblack@google.com } 74912852Sgabeblack@google.com 75012852Sgabeblack@google.com template <typename ArgumentIterator> 75112852Sgabeblack@google.com iterator 75213271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last, iterator from) 75312852Sgabeblack@google.com { 75413271Sgabeblack@google.com if (!size() || from == end() || first == last) 75513271Sgabeblack@google.com vec_->reportEmpty("sc_vector_assembly", from == end()); 75613271Sgabeblack@google.com 75713271Sgabeblack@google.com while (from != end() && first != last) 75813271Sgabeblack@google.com (*from++)(*first++); 75913271Sgabeblack@google.com return from; 76012852Sgabeblack@google.com } 76112852Sgabeblack@google.com 76212852Sgabeblack@google.com template <typename ArgumentIterator> 76312852Sgabeblack@google.com iterator 76413271Sgabeblack@google.com operator () (ArgumentIterator first, ArgumentIterator last, 76513271Sgabeblack@google.com typename sc_vector<T>::iterator from) 76612852Sgabeblack@google.com { 76713271Sgabeblack@google.com return (*this)(first, last, iterator(from.it_, ptr_)); 76812852Sgabeblack@google.com } 76912852Sgabeblack@google.com 77012852Sgabeblack@google.com private: 77112872Sgabeblack@google.com sc_vector_assembly(sc_vector<T> &v, MemberType ptr) : 77212872Sgabeblack@google.com vec_(&v), ptr_(ptr) 77312872Sgabeblack@google.com {} 77412872Sgabeblack@google.com 77512872Sgabeblack@google.com sc_vector<T> *vec_; 77612872Sgabeblack@google.com MemberType ptr_; 77712852Sgabeblack@google.com}; 77812852Sgabeblack@google.com 77912852Sgabeblack@google.comtemplate <typename T, typename MT> 78012852Sgabeblack@google.comsc_vector_assembly<T, MT> 78112872Sgabeblack@google.comsc_assemble_vector(sc_vector<T> &v, MT (T::*ptr)) 78212852Sgabeblack@google.com{ 78312872Sgabeblack@google.com return sc_vector_assembly<T, MT>(v, ptr); 78412852Sgabeblack@google.com} 78512852Sgabeblack@google.com 78612852Sgabeblack@google.com} // namespace sc_core 78712852Sgabeblack@google.com 78812852Sgabeblack@google.com#endif //__SYSTEMC_EXT_UTIL_SC_VECTOR_HH__ 789