mariadb/extra/yassl/mySTL/vector.hpp
svoj@mysql.com 01f4036989 WL#2286 - Compile MySQL w/YASSL support
merge with latest yaSSL, move templates instantiation into separate file where it is possible
2005-05-31 20:56:32 +05:00

153 lines
3.8 KiB
C++

/* 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 <assert.h> // assert
#include <stdlib.h> // malloc
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*>(malloc(n * sizeof(T)));
if (!start_) abort();
finish_ = start_;
end_of_storage_ = start_ + n;
}
~vector_base() { if (start_) free(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