| 27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ |
29 */ |
| 30 |
30 |
| 31 #pragma once |
31 #pragma once |
| |
32 #include <vector> |
| 32 #include "basics.h" |
33 #include "basics.h" |
| 33 #include <algorithm> |
|
| 34 #include <deque> |
|
| 35 #include <functional> |
|
| 36 #include <cassert> |
|
| 37 #include <vector> |
|
| 38 #include "range.h" |
34 #include "range.h" |
| 39 BEGIN_ZFC_NAMESPACE |
35 BEGIN_ZFC_NAMESPACE |
| 40 |
36 |
| 41 // ------------------------------------------------------------------------------------------------- |
37 template<typename T> |
| 42 // |
38 using Vector = std::vector<T>; |
| 43 template<typename T, typename C> |
|
| 44 class Container |
|
| 45 { |
|
| 46 public: |
|
| 47 typedef typename C::iterator Iterator; |
|
| 48 typedef typename C::const_iterator ConstIterator; |
|
| 49 typedef typename C::reverse_iterator ReverseIterator; |
|
| 50 typedef typename C::const_reverse_iterator ConstReverseIterator; |
|
| 51 typedef Container<T, C> Self; |
|
| 52 |
|
| 53 Container(){} |
|
| 54 |
|
| 55 Container (int numvalues) : |
|
| 56 m_container (numvalues) {} |
|
| 57 |
|
| 58 Container (const C& other) : |
|
| 59 m_container (other) {} |
|
| 60 |
|
| 61 Container(std::initializer_list<T> initializerList) : |
|
| 62 m_container(initializerList) {} |
|
| 63 |
|
| 64 T& append (const T& value) |
|
| 65 { |
|
| 66 m_container.push_back (value); |
|
| 67 return m_container[m_container.size() - 1]; |
|
| 68 } |
|
| 69 |
|
| 70 void append(const T* values, size_t numValues) |
|
| 71 { |
|
| 72 size_t i0 = size(); |
|
| 73 resize(size() + numValues); |
|
| 74 |
|
| 75 for (size_t i : range(numValues)) |
|
| 76 (*this)[i0 + i] = values[i]; |
|
| 77 } |
|
| 78 |
|
| 79 Iterator begin() |
|
| 80 { |
|
| 81 return m_container.begin(); |
|
| 82 } |
|
| 83 |
|
| 84 ConstIterator begin() const |
|
| 85 { |
|
| 86 return m_container.begin(); |
|
| 87 } |
|
| 88 |
|
| 89 void clear() |
|
| 90 { |
|
| 91 m_container.clear(); |
|
| 92 } |
|
| 93 |
|
| 94 bool contains (const T& a) const |
|
| 95 { |
|
| 96 return std::find (m_container.begin(), m_container.end(), a) != m_container.end(); |
|
| 97 } |
|
| 98 |
|
| 99 ConstReverseIterator crbegin() const |
|
| 100 { |
|
| 101 return m_container.rbegin(); |
|
| 102 } |
|
| 103 |
|
| 104 ConstReverseIterator crend() const |
|
| 105 { |
|
| 106 return m_container.rend(); |
|
| 107 } |
|
| 108 |
|
| 109 const C& container() const |
|
| 110 { |
|
| 111 return m_container; |
|
| 112 } |
|
| 113 |
|
| 114 Iterator end() |
|
| 115 { |
|
| 116 return m_container.end(); |
|
| 117 } |
|
| 118 |
|
| 119 ConstIterator end() const |
|
| 120 { |
|
| 121 return m_container.end(); |
|
| 122 } |
|
| 123 |
|
| 124 Iterator find (const T& needle) |
|
| 125 { |
|
| 126 auto it = std::find (m_container.begin(), m_container.end(), needle); |
|
| 127 |
|
| 128 if (it == m_container.end()) |
|
| 129 return end(); |
|
| 130 |
|
| 131 return it; |
|
| 132 } |
|
| 133 |
|
| 134 ConstIterator find (const T& needle) const |
|
| 135 { |
|
| 136 auto it = std::find (m_container.begin(), m_container.end(), needle); |
|
| 137 |
|
| 138 if (it == m_container.end()) |
|
| 139 return end(); |
|
| 140 |
|
| 141 return it; |
|
| 142 } |
|
| 143 |
|
| 144 Iterator find (bool (*func)(T const&)) |
|
| 145 { |
|
| 146 for (Iterator it = begin(); it != end(); ++it) |
|
| 147 { |
|
| 148 if (func (*it)) |
|
| 149 return it; |
|
| 150 } |
|
| 151 |
|
| 152 return end(); |
|
| 153 } |
|
| 154 |
|
| 155 ConstIterator find (bool (*func)(T const&)) const |
|
| 156 { |
|
| 157 for (ConstIterator it = begin(); it != end(); ++it) |
|
| 158 { |
|
| 159 if (func (*it)) |
|
| 160 return it; |
|
| 161 } |
|
| 162 |
|
| 163 return end(); |
|
| 164 } |
|
| 165 |
|
| 166 T& first() |
|
| 167 { |
|
| 168 return *begin(); |
|
| 169 } |
|
| 170 |
|
| 171 const T& first() const |
|
| 172 { |
|
| 173 return *begin(); |
|
| 174 } |
|
| 175 |
|
| 176 void insert (int pos, const T& value) |
|
| 177 { |
|
| 178 m_container.insert (m_container.begin() + pos, value); |
|
| 179 } |
|
| 180 |
|
| 181 bool is_empty() const |
|
| 182 { |
|
| 183 return size() == 0; |
|
| 184 } |
|
| 185 |
|
| 186 T& last() |
|
| 187 { |
|
| 188 return *(end() - 1); |
|
| 189 } |
|
| 190 |
|
| 191 const T& last() const |
|
| 192 { |
|
| 193 return *(end() - 1); |
|
| 194 } |
|
| 195 |
|
| 196 void merge (const Self& other) |
|
| 197 { |
|
| 198 int oldsize = size(); |
|
| 199 resize (size() + other.size()); |
|
| 200 std::copy (other.begin(), other.end(), begin() + oldsize); |
|
| 201 } |
|
| 202 |
|
| 203 bool pop (T& val) |
|
| 204 { |
|
| 205 if (is_empty()) |
|
| 206 return false; |
|
| 207 |
|
| 208 val = m_container[size() - 1]; |
|
| 209 m_container.erase (m_container.end() - 1); |
|
| 210 return true; |
|
| 211 } |
|
| 212 |
|
| 213 T& prepend (const T& value) |
|
| 214 { |
|
| 215 m_container.push_front (value); |
|
| 216 return m_container[0]; |
|
| 217 } |
|
| 218 |
|
| 219 ReverseIterator rbegin() |
|
| 220 { |
|
| 221 return m_container.rbegin(); |
|
| 222 } |
|
| 223 |
|
| 224 void remove_at (int pos) |
|
| 225 { |
|
| 226 assert (pos < size()); |
|
| 227 m_container.erase (m_container.begin() + pos); |
|
| 228 } |
|
| 229 |
|
| 230 void remove_duplicates() |
|
| 231 { |
|
| 232 sort(); |
|
| 233 resize (std::distance (begin(), std::unique (begin(), end()))); |
|
| 234 } |
|
| 235 |
|
| 236 void remove_one (const T& valueToRemove) |
|
| 237 { |
|
| 238 auto it = std::find (m_container.begin(), m_container.end(), valueToRemove); |
|
| 239 |
|
| 240 if (it != m_container.end()) |
|
| 241 m_container.erase (it); |
|
| 242 } |
|
| 243 |
|
| 244 ReverseIterator rend() |
|
| 245 { |
|
| 246 return m_container.rend(); |
|
| 247 } |
|
| 248 |
|
| 249 void resize (int size) |
|
| 250 { |
|
| 251 m_container.resize (size); |
|
| 252 } |
|
| 253 |
|
| 254 Self reverse() const |
|
| 255 { |
|
| 256 Self rev; |
|
| 257 std::copy (rbegin(), rend(), rev.begin()); |
|
| 258 return rev; |
|
| 259 } |
|
| 260 |
|
| 261 int size() const |
|
| 262 { |
|
| 263 return m_container.size(); |
|
| 264 } |
|
| 265 |
|
| 266 void sort() |
|
| 267 { |
|
| 268 std::sort (begin(), end()); |
|
| 269 } |
|
| 270 |
|
| 271 Self splice(int start, int end, int step = 1) const |
|
| 272 { |
|
| 273 start = clamp(start, 0, size()); |
|
| 274 end = clamp(end, 0, size()); |
|
| 275 |
|
| 276 if (end <= start) |
|
| 277 { |
|
| 278 return Self(); |
|
| 279 } |
|
| 280 else |
|
| 281 { |
|
| 282 Self result; |
|
| 283 |
|
| 284 for (int i : range(start, end, step)) |
|
| 285 result << operator[] (i); |
|
| 286 |
|
| 287 return result; |
|
| 288 } |
|
| 289 } |
|
| 290 |
|
| 291 Self splice(Range<int>& range) const |
|
| 292 { |
|
| 293 return splice(range.min(), range.max(), range.step()); |
|
| 294 } |
|
| 295 |
|
| 296 Self& operator<< (const T& value) |
|
| 297 { |
|
| 298 append (value); |
|
| 299 return *this; |
|
| 300 } |
|
| 301 |
|
| 302 Self& operator<< (const Self& vals) |
|
| 303 { |
|
| 304 merge (vals); |
|
| 305 return *this; |
|
| 306 } |
|
| 307 |
|
| 308 T& operator[] (int n) |
|
| 309 { |
|
| 310 assert (n < size()); |
|
| 311 return m_container[n]; |
|
| 312 } |
|
| 313 |
|
| 314 const T& operator[] (int n) const |
|
| 315 { |
|
| 316 assert (n < size()); |
|
| 317 return m_container[n]; |
|
| 318 } |
|
| 319 |
|
| 320 Self operator[] (Range<int> const& n) const |
|
| 321 { |
|
| 322 return splice (n); |
|
| 323 } |
|
| 324 |
|
| 325 Self operator+ (const Self& other) const |
|
| 326 { |
|
| 327 Self out (*this); |
|
| 328 out.merge (other); |
|
| 329 return out; |
|
| 330 } |
|
| 331 |
|
| 332 protected: |
|
| 333 C m_container; |
|
| 334 }; |
|
| 335 |
|
| 336 // ------------------------------------------------------------------------------------------------- |
|
| 337 // |
|
| 338 template<typename T, typename C> |
|
| 339 Container<T, C>& operator>> (const T& value, Container<T, C>& haystack) |
|
| 340 { |
|
| 341 haystack.prepend (value); |
|
| 342 return haystack; |
|
| 343 } |
|
| 344 |
|
| 345 // ------------------------------------------------------------------------------------------------- |
|
| 346 // |
|
| 347 |
39 |
| 348 template<typename T> |
40 template<typename T> |
| 349 class Vector : public Container<T, std::vector<T> > |
41 auto& last(T& container) |
| 350 { |
42 { |
| 351 public: |
43 return *(container.begin() + container.size() - 1); |
| 352 typedef Container<T, std::vector<T> > Super; |
44 } |
| 353 |
|
| 354 Vector(){} |
|
| 355 |
|
| 356 Vector(int numvalues) : |
|
| 357 Super(numvalues){} |
|
| 358 |
|
| 359 Vector (T* data, size_t length) : |
|
| 360 Super (std::vector<T> (data, data + length)) {} |
|
| 361 |
|
| 362 Vector(std::initializer_list<T> initializerList) : |
|
| 363 Super(initializerList) {} |
|
| 364 |
|
| 365 Vector(const Super& other) : |
|
| 366 Super(other) {} |
|
| 367 |
|
| 368 T* data() |
|
| 369 { |
|
| 370 return Super::m_container.data(); |
|
| 371 } |
|
| 372 |
|
| 373 const T* data() const |
|
| 374 { |
|
| 375 return Super::m_container.data(); |
|
| 376 } |
|
| 377 |
|
| 378 operator const T*() const |
|
| 379 { |
|
| 380 return data(); |
|
| 381 } |
|
| 382 }; |
|
| 383 |
45 |
| 384 using ByteArray = std::vector<unsigned char>; |
46 using ByteArray = std::vector<unsigned char>; |
| 385 class String quote(const ByteArray& bytes); |
47 class String quote(const ByteArray& bytes); |
| 386 |
48 |
| 387 template<typename T> |
49 template<typename T> |