summaryrefslogtreecommitdiff
path: root/extra/yassl/mySTL/vector.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'extra/yassl/mySTL/vector.hpp')
-rw-r--r--extra/yassl/mySTL/vector.hpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/extra/yassl/mySTL/vector.hpp b/extra/yassl/mySTL/vector.hpp
new file mode 100644
index 00000000000..7f1f99295e4
--- /dev/null
+++ b/extra/yassl/mySTL/vector.hpp
@@ -0,0 +1,154 @@
+/* mySTL vector.hpp
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/* mySTL vector implements simple vector, w/ swap
+ *
+ */
+
+#ifndef mySTL_VECTOR_HPP
+#define mySTL_VECTOR_HPP
+
+
+#include "helpers.hpp" // construct, destory, fill, etc.
+#include "algorithm.hpp" // swap
+#include <new> // ::operator new and delete, placement too
+#include <cassert> // assert
+
+
+namespace mySTL {
+
+
+template <typename T>
+struct vector_base {
+ T* start_;
+ T* finish_;
+ T* end_of_storage_;
+
+ vector_base() : start_(0), finish_(0), end_of_storage_(0) {}
+ vector_base(size_t n)
+ {
+ start_ = static_cast<T*>(::operator new(n * sizeof(T)));
+ if (!start_) abort();
+ finish_ = start_;
+ end_of_storage_ = start_ + n;
+ }
+
+ ~vector_base() { ::operator delete(start_); }
+
+ void Swap(vector_base& that)
+ {
+ swap(start_, that.start_);
+ swap(finish_, that.finish_);
+ swap(end_of_storage_, that.end_of_storage_);
+ }
+};
+
+
+
+template <typename T>
+class vector {
+public:
+ vector() {}
+ explicit vector(size_t n) : vec_(n)
+ {
+ vec_.finish_ = uninit_fill_n(vec_.start_, n, T());
+ }
+
+ ~vector() { destroy(vec_.start_, vec_.finish_); }
+
+ vector(const vector& other) : vec_(other.size())
+ {
+ vec_.finish_ = uninit_copy(other.vec_.start_, other.vec_.finish_,
+ vec_.start_);
+ }
+
+ size_t capacity() const { return vec_.end_of_storage_ - vec_.start_; }
+
+ size_t size() const { return vec_.finish_ - vec_.start_; }
+
+ T& operator[](size_t idx) { return *(vec_.start_ + idx); }
+ const T& operator[](size_t idx) const { return *(vec_.start_ + idx); }
+
+ const T* begin() const { return vec_.start_; }
+ const T* end() const { return vec_.finish_; }
+
+ void push_back(const T& v)
+ {
+ if (vec_.finish_ != vec_.end_of_storage_) {
+ construct(vec_.finish_, v);
+ ++vec_.finish_;
+ }
+ else {
+ vector tmp(size() * 2 + 1, *this);
+ construct(tmp.vec_.finish_, v);
+ ++tmp.vec_.finish_;
+ Swap(tmp);
+ }
+ }
+
+ void resize(size_t n, const T& v)
+ {
+ if (n == size()) return;
+
+ if (n < size()) {
+ T* first = vec_.start_ + n;
+ destroy(first, vec_.finish_);
+ vec_.finish_ -= vec_.finish_ - first;
+ }
+ else {
+ vector tmp(n, *this);
+ tmp.vec_.finish_ = uninit_fill_n(tmp.vec_.finish_, n - size(), v);
+ Swap(tmp);
+ }
+ }
+
+ void reserve(size_t n)
+ {
+ if (capacity() < n) {
+ vector tmp(n, *this);
+ Swap(tmp);
+ }
+ }
+
+ void Swap(vector& that)
+ {
+ vec_.Swap(that.vec_);
+ }
+private:
+ vector_base<T> vec_;
+
+ vector& operator=(const vector&); // hide assign
+
+ // for growing, n must be bigger than other size
+ vector(size_t n, const vector& other) : vec_(n)
+ {
+ assert(n > other.size());
+ vec_.finish_ = uninit_copy(other.vec_.start_, other.vec_.finish_,
+ vec_.start_);
+ }
+};
+
+
+
+} // namespace mySTL
+
+#endif // mySTL_VECTOR_HPP