Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/13197

Change subject: systemc: Implement sc_Vector.
......................................................................

systemc: Implement sc_Vector.

Change-Id: I3cf096c4432fdf310fa1279da32620d5c9f57b5d
---
M src/systemc/ext/utils/sc_vector.hh
M src/systemc/utils/sc_vector.cc
2 files changed, 248 insertions(+), 146 deletions(-)



diff --git a/src/systemc/ext/utils/sc_vector.hh b/src/systemc/ext/utils/sc_vector.hh
index fea49c2..c04a04c 100644
--- a/src/systemc/ext/utils/sc_vector.hh
+++ b/src/systemc/ext/utils/sc_vector.hh
@@ -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 @@
   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 @@
     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();
+        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 @@
         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 @@
     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 @@

     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:
diff --git a/src/systemc/utils/sc_vector.cc b/src/systemc/utils/sc_vector.cc
index ed59b73..9852539 100644
--- a/src/systemc/utils/sc_vector.cc
+++ b/src/systemc/utils/sc_vector.cc
@@ -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

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/13197
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I3cf096c4432fdf310fa1279da32620d5c9f57b5d
Gerrit-Change-Number: 13197
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to