[Mesa-dev] [PATCH 2/3] clover: stdify compat::vector a little more

EdB edb+mesa at sigluy.net
Thu Aug 7 22:02:08 PDT 2014


make resize work like std::vector
reserve take advantage of capacity
rename members to be uniform with other class
---
 src/gallium/state_trackers/clover/core/module.cpp |   2 +-
 src/gallium/state_trackers/clover/util/compat.hpp | 113 +++++++++++++++-------
 2 files changed, 78 insertions(+), 37 deletions(-)

diff --git a/src/gallium/state_trackers/clover/core/module.cpp b/src/gallium/state_trackers/clover/core/module.cpp
index 55ed91a..2a595d1 100644
--- a/src/gallium/state_trackers/clover/core/module.cpp
+++ b/src/gallium/state_trackers/clover/core/module.cpp
@@ -94,7 +94,7 @@ namespace {
 
       static void
       proc(compat::istream &is, compat::vector<T> &v) {
-         v.reserve(_proc<uint32_t>(is));
+         v.resize(_proc<uint32_t>(is));
 
          for (size_t i = 0; i < v.size(); i++)
             new(&v[i]) T(_proc<T>(is));
diff --git a/src/gallium/state_trackers/clover/util/compat.hpp b/src/gallium/state_trackers/clover/util/compat.hpp
index 50e1c7d..6f0f7cc 100644
--- a/src/gallium/state_trackers/clover/util/compat.hpp
+++ b/src/gallium/state_trackers/clover/util/compat.hpp
@@ -40,11 +40,14 @@ namespace clover {
       class vector {
       protected:
          static T *
-         alloc(int n, const T *q, int m) {
-            T *p = reinterpret_cast<T *>(std::malloc(n * sizeof(T)));
-
-            for (int i = 0; i < m; ++i)
-               new(&p[i]) T(q[i]);
+         alloc(size_t n, const T *q) {
+            T *p = 0;
+            if (n > 0) {
+               p = reinterpret_cast<T *>(std::malloc(n * sizeof(T)));
+               if (!p) throw;
+               for (size_t i = 0; i < n; ++i)
+                  new(&p[i]) T(q[i]);
+            }
 
             return p;
          }
@@ -66,100 +69,138 @@ namespace clover {
          typedef std::ptrdiff_t difference_type;
          typedef std::size_t size_type;
 
-         vector() : p(NULL), n(0) {
+         vector() : _p(0), _s(0), _c(0) {
          }
 
-         vector(const vector &v) : p(alloc(v.n, v.p, v.n)), n(v.n) {
+         vector(const vector &v) :
+           _p(alloc(v.size(), v.begin())), _s(v.size()), _c(_s) {
          }
 
-         vector(const_iterator p, size_type n) : p(alloc(n, p, n)), n(n) {
+         vector(const_iterator v, size_type n) : _p(alloc(n, v)), _s(n), _c(n) {
          }
 
          template<typename C>
          vector(const C &v) :
-            p(alloc(v.size(), &*v.begin(), v.size())), n(v.size()) {
+            _p(alloc(v.size(), &*v.begin())), _s(v.size()), _c(_s) {
          }
 
          ~vector() {
-            free(n, p);
+            free(_s, _p);
          }
 
          vector &
          operator=(const vector &v) {
-            free(n, p);
-
-            p = alloc(v.n, v.p, v.n);
-            n = v.n;
+            size_type old_s = _s;
+            _s = v.size();
+            T *n_p = alloc(_s, v.begin());
+            free(old_s, _p);
+            _p = n_p;
+            _c = _s;
 
             return *this;
          }
 
          void
          reserve(size_type m) {
-            if (n < m) {
-               T *q = alloc(m, p, n);
-               free(n, p);
-
-               p = q;
-               n = m;
+            if (m > _c) {
+               T *n_p = reinterpret_cast<T *>(std::malloc(m * sizeof(T)));
+               for (size_type i = 0; i < _s; ++i) {
+                  new(&n_p[i]) T(_p[i]);
+                  _p[i].~T();
+               }
+               std::free(_p);
+               _p = n_p;
+               _c = m;
             }
          }
 
          void
          resize(size_type m, T x = T()) {
-            size_type n = size();
+            if (_s == m)
+               return;
+
+            //delete extra elements and keep capacity
+            if (m < _s) {
+               size_type old_s = _s;
+               _s = m;
+               for (size_type i = m; i < old_s; ++i)
+                  _p[i].~T();
+
+               return;
+            }
+
+            //fill with x
+            if (m <= _c) {
+               for (size_type i = _s; i < m; ++i)
+                 new(&_p[i]) T(x);
+
+               _s = m;
+               return;
+            }
+
+            if (m > _c) {
+               reserve(m);
 
-            reserve(m);
+               //fill the extended part
+               for (size_type i = _s; i < m; ++i)
+                 new(&_p[i]) T(x);
 
-            for (size_type i = n; i < m; ++i)
-               new(&p[i]) T(x);
+               _s = m;
+               return;
+            }
          }
 
          void
          push_back(const T &x) {
-            size_type n = size();
-            reserve(n + 1);
-            new(&p[n]) T(x);
+            reserve(_s + 1);
+            new(&_p[_s]) T(x);
+            ++_s;
          }
 
          size_type
          size() const {
-            return n;
+            return _s;
+         }
+
+         size_type
+         capacity() const {
+            return _c;
          }
 
          iterator
          begin() {
-            return p;
+            return _p;
          }
 
          const_iterator
          begin() const {
-            return p;
+            return _p;
          }
 
          iterator
          end() {
-            return p + n;
+            return _p + _s;
          }
 
          const_iterator
          end() const {
-            return p + n;
+            return _p + _s;
          }
 
          reference
          operator[](size_type i) {
-            return p[i];
+            return _p[i];
          }
 
          const_reference
          operator[](size_type i) const {
-            return p[i];
+            return _p[i];
          }
 
       private:
-         iterator p;
-         size_type n;
+         iterator _p;  //memory array
+         size_type _s; //size
+         size_type _c; //capacity
       };
 
       template<typename T>
-- 
2.0.4



More information about the mesa-dev mailing list