1 // OpenSTA, Static Timing Analyzer
2 // Copyright (c) 2020, Parallax Software, Inc.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 
17 #pragma once
18 
19 #include <vector>
20 #include <algorithm>
21 
22 namespace sta {
23 
24 // Add convenience functions around STL container.
25 template <class OBJ>
26 class Vector : public std::vector<OBJ>
27 {
28 public:
Vector()29   Vector() : std::vector<OBJ>() {}
Vector(size_t n)30   Vector(size_t n) : std::vector<OBJ>(n) {}
Vector(size_t n,const OBJ & obj)31   Vector(size_t n, const OBJ &obj) : std::vector<OBJ>(n, obj) {}
32 
33   // Erase an object from the vector (slow).
34   void
eraseObject(OBJ obj)35   eraseObject(OBJ obj)
36   {
37     auto find_iter = std::find(this->begin(), this->end(), obj);
38     if (find_iter != this->end())
39       this->erase(find_iter);
40   }
41 
42   void
deleteContents()43   deleteContents()
44   {
45     Iterator iter(this);
46     while (iter.hasNext())
47       delete iter.next();
48   }
49 
50   void
deleteContentsClear()51   deleteContentsClear()
52   {
53     deleteContents();
54     this->clear();
55   }
56 
57   void
deleteArrayContentsClear()58   deleteArrayContentsClear()
59   {
60     Iterator iter(this);
61     while (iter.hasNext())
62       delete [] iter.next();
63     this->clear();
64   }
65 
66   // Java style container itererator
67   //  Vector::Iterator<Object*> iter(vector);
68   //  while (iter.hasNext()) {
69   //    Object *v = iter.next();
70   //  }
71   class Iterator
72   {
73   public:
Iterator()74     Iterator() : container_(nullptr) {}
Iterator(std::vector<OBJ> * container)75     Iterator(std::vector<OBJ> *container) :
76       container_(container)
77     { if (container) iter_ = container->begin(); }
Iterator(std::vector<OBJ> & container)78     Iterator(std::vector<OBJ> &container) :
79       container_(&container)
80     { if (container_) iter_ = container_->begin(); }
init()81     void init() { iter_ = container_->begin(); }
init(std::vector<OBJ> * container)82     void init(std::vector<OBJ> *container)
83     { container_ = container; if (container_) iter_=container_->begin(); }
init(std::vector<OBJ> & container)84     void init(std::vector<OBJ> &container)
85     { container_ = &container; iter_ = container_->begin(); }
hasNext()86     bool hasNext() { return container_ && iter_ != container_->end(); }
next()87     OBJ& next() { return *iter_++; }
container()88     std::vector<OBJ> *container() { return container_; }
89 
90   private:
91     std::vector<OBJ> *container_;
92     typename std::vector<OBJ>::iterator iter_;
93   };
94 
95   class ConstIterator
96   {
97   public:
ConstIterator()98     ConstIterator() : container_(nullptr) {}
ConstIterator(const std::vector<OBJ> * container)99     ConstIterator(const std::vector<OBJ> *container) :
100       container_(container)
101     { if (container_) iter_ = container_->begin(); }
ConstIterator(const std::vector<OBJ> & container)102     ConstIterator(const std::vector<OBJ> &container) :
103       container_(&container)
104     { iter_ = container_->begin(); }
init()105     void init() { iter_ = container_->begin(); }
init(const std::vector<OBJ> * container)106     void init(const std::vector<OBJ> *container)
107     { container_ = container; if (container_) iter_=container_->begin();}
init(const std::vector<OBJ> & container)108     void init(const std::vector<OBJ> &container)
109     { container_ = &container; if (container_) iter_=container_->begin();}
hasNext()110     bool hasNext() { return container_ && iter_ != container_->end(); }
next()111     const OBJ& next() { return *iter_++; }
container()112     const std::vector<OBJ> *container() { return container_; }
113 
114   private:
115     const std::vector<OBJ> *container_;
116     typename std::vector<OBJ>::const_iterator iter_;
117   };
118 };
119 
120 template <class OBJ, class SortCmp>
121 void
sort(Vector<OBJ> & seq,SortCmp cmp)122 sort(Vector<OBJ> &seq, SortCmp cmp)
123 {
124   // For some strange reason std::sort goes off into never never land
125   // when optimization is turned on in gcc.
126   std::stable_sort(seq.begin(), seq.end(), cmp);
127 }
128 
129 template <class OBJ, class SortCmp>
130 void
sort(Vector<OBJ> * seq,SortCmp cmp)131 sort(Vector<OBJ> *seq, SortCmp cmp)
132 {
133   // For some strange reason std::sort goes off into never never land
134   // when optimization is turned on in gcc.
135   std::stable_sort(seq->begin(), seq->end(), cmp);
136 }
137 
138 } // namespace sta
139