src/containers.h

changeset 72
03e4d9db3fd9
child 73
1ee9b312dc18
equal deleted inserted replaced
71:11f23fabf8a6 72:03e4d9db3fd9
1 #ifndef LIBCOBALT_CONTAINERS_H
2 #define LIBCOBALT_CONTAINERS_H
3
4 #include <cassert>
5 #include <algorithm>
6 #include <deque>
7 #include <initializer_list>
8
9 template<class T> class list
10 {
11 public:
12 typedef typename ::std::deque<T> list_type;
13 typedef typename list_type::iterator it;
14 typedef typename list_type::const_iterator c_it;
15 typedef typename list_type::reverse_iterator r_it;
16 typedef typename list_type::const_reverse_iterator cr_it;
17 typedef T element_type;
18 typedef list<T> self_type;
19
20 list() {}
21 list (std::initializer_list<element_type> vals)
22 {
23 m_data = vals;
24 }
25
26 list (const list_type& a) : m_data (a) {}
27
28 it begin()
29 {
30 return m_data.begin();
31 }
32
33 c_it begin() const
34 {
35 return m_data.cbegin();
36 }
37
38 it end()
39 {
40 return m_data.end();
41 }
42
43 c_it end() const
44 {
45 return m_data.cend();
46 }
47
48 r_it rbegin()
49 {
50 return m_data.rbegin();
51 }
52
53 cr_it crbegin() const
54 {
55 return m_data.crbegin();
56 }
57
58 r_it rend()
59 {
60 return m_data.rend();
61 }
62
63 cr_it crend() const
64 {
65 return m_data.crend();
66 }
67
68 void erase (int pos)
69 {
70 assert (pos < size());
71 m_data.erase (m_data.begin() + pos);
72 }
73
74 element_type& push_front (const element_type& value)
75 {
76 m_data.push_front (value);
77 return m_data[0];
78 }
79
80 element_type& push_back (const element_type& value)
81 {
82 m_data.push_back (value);
83 return m_data[m_data.size() - 1];
84 }
85
86 void push_back (const self_type& vals)
87 {
88 for (const T & val : vals)
89 push_back (val);
90 }
91
92 bool pop (T& val)
93 {
94 if (size() == 0)
95 return false;
96
97 val = m_data[size() - 1];
98 erase (size() - 1);
99 return true;
100 }
101
102 T& operator<< (const T& value)
103 {
104 return push_back (value);
105 }
106
107 void operator<< (const self_type& vals)
108 {
109 push_back (vals);
110 }
111
112 bool operator>> (T& value)
113 {
114 return pop (value);
115 }
116
117 self_type reverse() const
118 {
119 self_type rev;
120
121 for (const T & val : *this)
122 val >> rev;
123
124 return rev;
125 }
126
127 void clear()
128 {
129 m_data.clear();
130 }
131
132 void insert (int pos, const element_type& value)
133 {
134 m_data.insert (m_data.begin() + pos, value);
135 }
136
137 void makeUnique()
138 {
139 // Remove duplicate entries. For this to be effective, the vector must be
140 // sorted first.
141 sort();
142 it pos = std::unique (begin(), end());
143 resize (std::distance (begin(), pos));
144 }
145
146 int size() const
147 {
148 return m_data.size();
149 }
150
151 element_type& operator[] (int n)
152 {
153 assert (n < size());
154 return m_data[n];
155 }
156
157 const element_type& operator[] (int n) const
158 {
159 assert (n < size());
160 return m_data[n];
161 }
162
163 void resize (std::ptrdiff_t size)
164 {
165 m_data.resize (size);
166 }
167
168 void sort()
169 {
170 std::sort (begin(), end());
171 }
172
173 int find (const element_type& needle)
174 {
175 int i = 0;
176
177 for (const element_type & hay : *this)
178 {
179 if (hay == needle)
180 return i;
181
182 i++;
183 }
184
185 return -1;
186 }
187
188 void remove (const element_type& it)
189 {
190 int idx;
191
192 if ( (idx = find (it)) != -1)
193 erase (idx);
194 }
195
196 inline bool is_empty() const
197 {
198 return size() == 0;
199 }
200
201 self_type mid (int a, int b) const
202 {
203 assert (a >= 0 && b >= 0 && a < size() && b < size() && a <= b);
204 self_type result;
205
206 for (int i = a; i <= b; ++i)
207 result << operator[] (i);
208
209 return result;
210 }
211
212 inline const list_type& std_deque() const
213 {
214 return m_data;
215 }
216
217 private:
218 list_type m_data;
219 };
220
221 template<class T> list<T>& operator>> (const T& value, list<T>& haystack)
222 {
223 haystack.push_front (value);
224 return haystack;
225 }
226
227 #endif // LIBCOBALT_CONTAINERS_H

mercurial