systemc: Implement sc_vector.
Change-Id: I3cf096c4432fdf310fa1279da32620d5c9f57b5d Reviewed-on: https://gem5-review.googlesource.com/c/13197 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -1,3 +1,22 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
|
||||
more contributor license agreements. See the NOTICE file distributed
|
||||
with this work for additional information regarding copyright ownership.
|
||||
Accellera licenses this file to you under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with the
|
||||
License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
permissions and limitations under the License.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 2018 Google, Inc.
|
||||
*
|
||||
@@ -36,8 +55,8 @@
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include "../core/sc_module.hh"
|
||||
#include "../core/sc_object.hh"
|
||||
#include "warn_unimpl.hh"
|
||||
|
||||
namespace sc_gem5
|
||||
{
|
||||
@@ -147,9 +166,34 @@ class sc_vector_base : public sc_object
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
|
||||
sc_vector_base(const char *_name) : sc_object(_name) {}
|
||||
|
||||
virtual const char *kind() const { return "sc_vector"; }
|
||||
size_type size() const;
|
||||
const std::vector<sc_object *> &get_elements() const;
|
||||
|
||||
protected:
|
||||
std::vector<void *> objs;
|
||||
|
||||
// What's returned by get_elements, which really returns the elemenets
|
||||
// which are also objects.
|
||||
mutable std::vector<sc_object *> elements;
|
||||
|
||||
sc_object *implicitCast(sc_object *p) const { return p; }
|
||||
sc_object *implicitCast(...) const
|
||||
{
|
||||
SC_REPORT_ERROR(
|
||||
"(E808) sc_vector::get_elements called for element type "
|
||||
"not derived from sc_object", name());
|
||||
return nullptr;
|
||||
}
|
||||
virtual sc_object *objectCast(void *) const = 0;
|
||||
|
||||
void checkIndex(size_type index) const;
|
||||
void forceParent() const;
|
||||
void unforceParent() const;
|
||||
|
||||
void reportEmpty(const char *kind_, bool empty_dest) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -403,177 +447,164 @@ class sc_vector : public sc_vector_base
|
||||
typedef sc_vector_iter<T> iterator;
|
||||
typedef sc_vector_iter<const T> const_iterator;
|
||||
|
||||
sc_vector() : sc_vector_base()
|
||||
sc_vector() : sc_vector_base(::sc_core::sc_gen_unique_name("vector")) {}
|
||||
explicit sc_vector(const char *_name) : sc_vector_base(_name) {}
|
||||
sc_vector(const char *_name, size_type _size) : sc_vector_base(_name)
|
||||
{
|
||||
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__);
|
||||
init(_size);
|
||||
}
|
||||
template <typename Creator>
|
||||
sc_vector(const char *, size_type, Creator) : sc_vector_base()
|
||||
sc_vector(const char *_name, size_type _size, Creator creator) :
|
||||
sc_vector_base(_name)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
init(_size, creator);
|
||||
}
|
||||
virtual ~sc_vector() {}
|
||||
virtual ~sc_vector() { clear(); }
|
||||
|
||||
void
|
||||
init(size_type)
|
||||
init(size_type _size)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
init(_size, &sc_vector<T>::create_element);
|
||||
}
|
||||
static T *
|
||||
create_element(const char *, size_type)
|
||||
create_element(const char *_name, size_type index)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return nullptr;
|
||||
return new T(_name);
|
||||
}
|
||||
|
||||
template <typename Creator>
|
||||
void
|
||||
init(size_type, Creator)
|
||||
init(size_type _size, Creator creator)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
forceParent();
|
||||
try {
|
||||
for (size_type i = 0; i < _size; i++) {
|
||||
// XXX The name and scope of these objects needs to be handled
|
||||
// specially.
|
||||
T *p = creator(sc_gen_unique_name(basename()), i);
|
||||
objs.push_back(p);
|
||||
}
|
||||
} catch (...) {
|
||||
unforceParent();
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
unforceParent();
|
||||
}
|
||||
|
||||
T &operator [] (size_type index) { return *static_cast<T *>(objs[index]); }
|
||||
const T &
|
||||
operator [] (size_type index) const
|
||||
{
|
||||
return *static_cast<const T *>(objs[index]);
|
||||
}
|
||||
|
||||
T &
|
||||
operator [] (size_type)
|
||||
at(size_type index)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return *(T *)nullptr;
|
||||
this->checkIndex(index);
|
||||
return *static_cast<T *>(objs[index]);
|
||||
}
|
||||
const T &
|
||||
operator [] (size_type) const
|
||||
at(size_type index) const
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return *(const T *)nullptr;
|
||||
this->checkIndex(index);
|
||||
return *static_cast<const T *>(objs[index]);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
iterator begin() { return objs.begin(); }
|
||||
iterator end() { return objs.end(); }
|
||||
const_iterator begin() const { return objs.begin(); }
|
||||
const_iterator end() const { return objs.end(); }
|
||||
const_iterator cbegin() const { return objs.begin(); }
|
||||
const_iterator cend() const { return objs.end(); }
|
||||
|
||||
template <typename ContainerType, typename ArgumentType>
|
||||
iterator
|
||||
bind(sc_vector_assembly<ContainerType, ArgumentType>)
|
||||
bind(sc_vector_assembly<ContainerType, ArgumentType> c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
return bind(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename BindableContainer>
|
||||
iterator
|
||||
bind(BindableContainer &)
|
||||
bind(BindableContainer &c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
return bind(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename BindableIterator>
|
||||
iterator
|
||||
bind(BindableIterator, BindableIterator)
|
||||
bind(BindableIterator first, BindableIterator last)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
return bind(first, last, this->begin());
|
||||
}
|
||||
|
||||
template <typename BindableIterator>
|
||||
iterator
|
||||
bind(BindableIterator, BindableIterator, iterator)
|
||||
bind(BindableIterator first, BindableIterator last, iterator from)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
if (!size() || from == end() || first == last)
|
||||
reportEmpty(kind(), from == end());
|
||||
|
||||
while (from != end() && first != last)
|
||||
(*from++).bind(*first++);
|
||||
return from;
|
||||
}
|
||||
|
||||
template <typename ContainerType, typename ArgumentType>
|
||||
iterator
|
||||
operator () (sc_vector_assembly<ContainerType, ArgumentType> c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
return (*this)(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename ArgumentContainer>
|
||||
iterator
|
||||
operator () (ArgumentContainer &)
|
||||
operator () (ArgumentContainer &c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
return (*this)(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename ArgumentIterator>
|
||||
iterator
|
||||
operator () (ArgumentIterator, ArgumentIterator)
|
||||
operator () (ArgumentIterator first, ArgumentIterator last)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
return (*this)(first, last, this->begin());
|
||||
}
|
||||
|
||||
template <typename ArgumentIterator>
|
||||
iterator
|
||||
operator () (ArgumentIterator, ArgumentIterator, iterator)
|
||||
operator () (ArgumentIterator first, ArgumentIterator last, iterator from)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return iterator();
|
||||
if (!size() || from == end() || first == last)
|
||||
reportEmpty(kind(), from == end());
|
||||
|
||||
while (from != end() && first != last)
|
||||
(*from++)(*first++);
|
||||
return from;
|
||||
}
|
||||
|
||||
private:
|
||||
// Disabled
|
||||
sc_vector(const sc_vector &) : sc_vector_base() {}
|
||||
sc_vector &operator = (const sc_vector &) { return *this; }
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
for (auto obj: objs)
|
||||
delete static_cast<T *>(obj);
|
||||
}
|
||||
|
||||
template <typename, typename>
|
||||
friend class sc_vector_assembly;
|
||||
|
||||
sc_object *
|
||||
objectCast(void *ptr) const
|
||||
{
|
||||
return implicitCast(static_cast<T *>(ptr));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename MT>
|
||||
@@ -589,10 +620,9 @@ class sc_vector_assembly
|
||||
const T, sc_member_access<const T, const MT> > const_iterator;
|
||||
typedef MT (T::*MemberType);
|
||||
|
||||
sc_vector_assembly(const sc_vector_assembly &)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
}
|
||||
sc_vector_assembly(const sc_vector_assembly &other) :
|
||||
vec_(other.vec_), ptr_(other.ptr_)
|
||||
{}
|
||||
|
||||
iterator begin() { return iterator(vec_->begin().it_, ptr_); }
|
||||
iterator end() { return iterator(vec_->end().it_, ptr_); }
|
||||
@@ -624,8 +654,14 @@ class sc_vector_assembly
|
||||
std::vector<sc_object *>
|
||||
get_elements() const
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return *(std::vector<sc_object *> *)nullptr;
|
||||
std::vector<sc_object *> ret;
|
||||
for (const_iterator it = begin(); it != end(); it++) {
|
||||
sc_object *obj_ptr = vec_->objectCast(const_cast<MT *>(&*it));
|
||||
|
||||
if (obj_ptr)
|
||||
ret.push_back(obj_ptr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
typename iterator::reference
|
||||
@@ -652,83 +688,84 @@ class sc_vector_assembly
|
||||
|
||||
template <typename ContainerType, typename ArgumentType>
|
||||
iterator
|
||||
bind(sc_vector_assembly<ContainerType, ArgumentType>)
|
||||
bind(sc_vector_assembly<ContainerType, ArgumentType> c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return bind(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename BindableContainer>
|
||||
iterator
|
||||
bind(BindableContainer &)
|
||||
bind(BindableContainer &c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return bind(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename BindableIterator>
|
||||
iterator
|
||||
bind(BindableIterator, BindableIterator)
|
||||
bind(BindableIterator first, BindableIterator last)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return bind(first, last, this->begin());
|
||||
}
|
||||
|
||||
template <typename BindableIterator>
|
||||
iterator
|
||||
bind(BindableIterator, BindableIterator, iterator)
|
||||
bind(BindableIterator first, BindableIterator last, iterator from)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
if (!size() || from == end() || first == last)
|
||||
vec_->reportEmpty("sc_vector_assembly", from == end());
|
||||
|
||||
while (from != end() && first != last)
|
||||
(*from++).bind(*first++);
|
||||
return from;
|
||||
}
|
||||
|
||||
template <typename BindableIterator>
|
||||
iterator
|
||||
bind(BindableIterator, BindableIterator, typename sc_vector<T>::iterator)
|
||||
bind(BindableIterator first, BindableIterator last,
|
||||
typename sc_vector<T>::iterator from)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return bind(first, last, iterator(from.it_, ptr_));
|
||||
}
|
||||
|
||||
template <typename ContainerType, typename ArgumentType>
|
||||
iterator
|
||||
operator () (sc_vector_assembly<ContainerType, ArgumentType>)
|
||||
operator () (sc_vector_assembly<ContainerType, ArgumentType> c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return (*this)(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename ArgumentContainer>
|
||||
iterator
|
||||
operator () (ArgumentContainer &)
|
||||
operator () (ArgumentContainer &c)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return (*this)(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template <typename ArgumentIterator>
|
||||
iterator
|
||||
operator () (ArgumentIterator, ArgumentIterator)
|
||||
operator () (ArgumentIterator first, ArgumentIterator last)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return (*this)(first, last, this->begin());
|
||||
}
|
||||
|
||||
template <typename ArgumentIterator>
|
||||
iterator
|
||||
operator () (ArgumentIterator, ArgumentIterator, iterator)
|
||||
operator () (ArgumentIterator first, ArgumentIterator last, iterator from)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
if (!size() || from == end() || first == last)
|
||||
vec_->reportEmpty("sc_vector_assembly", from == end());
|
||||
|
||||
while (from != end() && first != last)
|
||||
(*from++)(*first++);
|
||||
return from;
|
||||
}
|
||||
|
||||
template <typename ArgumentIterator>
|
||||
iterator
|
||||
operator () (ArgumentIterator, ArgumentIterator,
|
||||
typename sc_vector<T>::iterator)
|
||||
operator () (ArgumentIterator first, ArgumentIterator last,
|
||||
typename sc_vector<T>::iterator from)
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return begin();
|
||||
return (*this)(first, last, iterator(from.it_, ptr_));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
|
||||
more contributor license agreements. See the NOTICE file distributed
|
||||
with this work for additional information regarding copyright ownership.
|
||||
Accellera licenses this file to you under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with the
|
||||
License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
permissions and limitations under the License.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 2018 Google, Inc.
|
||||
*
|
||||
@@ -27,23 +46,69 @@
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
#include "systemc/core/object.hh"
|
||||
#include "systemc/ext/utils/sc_report_handler.hh"
|
||||
#include "systemc/ext/utils/sc_vector.hh"
|
||||
|
||||
namespace sc_core
|
||||
{
|
||||
|
||||
sc_vector_base::size_type
|
||||
sc_vector_base::size() const
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
sc_vector_base::size_type sc_vector_base::size() const { return objs.size(); }
|
||||
|
||||
const std::vector<sc_object *> &
|
||||
sc_vector_base::get_elements() const
|
||||
{
|
||||
sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
return *(const std::vector<sc_object *> *)nullptr;
|
||||
elements.clear();
|
||||
for (auto ptr: objs) {
|
||||
sc_object *obj_ptr = objectCast(ptr);
|
||||
if (obj_ptr)
|
||||
elements.push_back(obj_ptr);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
void
|
||||
sc_vector_base::checkIndex(size_type index) const
|
||||
{
|
||||
if (index >= size()) {
|
||||
std::ostringstream ss;
|
||||
ccprintf(ss, "%s[%d] >= size() = %d", name(), index, size());
|
||||
SC_REPORT_ERROR("(E5) out of bounds", ss.str().c_str());
|
||||
sc_abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sc_vector_base::forceParent() const
|
||||
{
|
||||
sc_gem5::pushParentObj(get_parent_object());
|
||||
}
|
||||
|
||||
void
|
||||
sc_vector_base::unforceParent() const
|
||||
{
|
||||
sc_gem5::popParentObj();
|
||||
}
|
||||
|
||||
void
|
||||
sc_vector_base::reportEmpty(const char *kind_, bool empty_dest) const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "target `" << name() << "' " << "(" << kind_ << ") ";
|
||||
|
||||
if (!size())
|
||||
ss << "not initialised yet";
|
||||
else if (empty_dest)
|
||||
ss << "empty range given";
|
||||
else
|
||||
ss << "empty destination range given";
|
||||
|
||||
SC_REPORT_WARNING("(W807) sc_vector::bind called with empty range",
|
||||
ss.str().c_str());
|
||||
}
|
||||
|
||||
} // namespace sc_core
|
||||
|
||||
Reference in New Issue
Block a user