Vec.h
#ifndef GUARD_Vec_h
#define GUARD_Vec_h
// Vec.h
#include <cstddef> // define size_t and ptrdiff_t
#include <memory> // define allocator
#include <algorithm>
template <class T>
class Vec {
public:
typedef T* iterator;
typedef const T* const_iterator;
typedef size_t size_type;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
Vec() { create(); }
explicit Vec(std::size_t n, const T& val = T()) { create(n, val); }
Vec(const Vec& v) { create(v.begin(), v.end()); } // copy constructor
Vec& operator=(const Vec&);
~Vec() { uncreate(); }
size_type size() const { return avail - data; }
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i) const { return data[i]; }
void push_back(const T& t) {
if (avail == limit)
grow();
unchecked_append(t);
}
iterator erase(iterator p) { return erase(p, p + 1); }
iterator erase(iterator, iterator);
void clear() { erase(data, avail); }
iterator begin() { return data; }
const_iterator begin() const { return data; }
iterator end() { return avail; }
const_iterator end() const { return avail; }
private:
iterator data;
iterator avail;
iterator limit;
// facilities for memory allocation
std::allocator<T> alloc; // object to handle memory allocation
// allocate and initialize the underlying arry
void create();
void create(size_type, const T&);
void create(const_iterator, const_iterator);
// destroy the element in the array and free the memory
void uncreate();
// support function for push_back
void grow();
void unchecked_append(const T&);
};
template <class T> void Vec<T>::create() {
data = avail = limit = 0;
}
template <class T> void Vec<T>::create(size_type n, const T& val) {
data = alloc.allocate(n);
limit = avail = data + n;
uninitialized_fill(data, avail, val);
}
template <class T> void Vec<T>::create(const_iterator i, const_iterator j) {
data = alloc.allocate(j - i);
limit = avail = uninitialized_copy(i, j, data);
}
template <class T> void Vec<T>::uncreate() {
if (data) {
iterator it = avail;
while (data != it)
alloc.destroy(--it);
alloc.deallocate(data, avail - data);
}
// reset pointer to indicate that the Vec is empty again
data = avail = limit = 0;
}
template <class T> void Vec<T>::grow() {
size_type new_size = std:: max(2 * (limit - data), ptrdiff_t(1));
iterator new_data = alloc.allocate(new_size);
iterator new_avail = uninitialized_copy(data, avail, new_data);
uncreate();
data = new_data;
avail = new_avail;
limit = new_data + new_size;
}
template <class T> void Vec<T>::unchecked_append(const T& val) {
alloc.construct(avail++, val);
}
template <class T> Vec<T>& Vec<T>::operator=(const Vec& rhs) {
// check for the self-assignment
if (&rhs != this) {
// free the array in the left-hand side
uncreate();
// copy elements from the right-hand side to the left-hand side
create(rhs.begin(), rhs.end());
}
return *this;
}
template <class T> typename Vec<T>::iterator Vec<T>::erase(iterator b, iterator e) {
iterator ret = b;
while (e < avail) {
alloc.destroy(b);
alloc.construct(b, *e);
++b;
++e;
}
iterator new_avail = b;
while (b < avail)
alloc.destroy(b++);
avail = new_avail;
// if (data)
// alloc.deallocate(avail, limit - avail);
// the vector is empty
if (data == avail) {
data = avail = limit = 0;
return 0;
}
return ret;
}
#endif
main.cpp
#include "Vec.h"
#include <iostream>
#include <string>
using std::string; using std::cout; using std::endl;
using std::max;
int main() {
Vec<string> names;
names.push_back("ruihuank");
Vec<string> names2(names);
names2.push_back("lzj");
names2.push_back("wjy");
names2.push_back("hxd");
cout << "putout the vector names2" << endl;
for (Vec<string>::const_iterator it = names2.begin(); it != names2.end(); ++it) {
cout << *it << endl;
}
names2.erase(names2.begin());
// names2.erase(names2.end());
cout << "putout the vector names2 after erasing" << endl;
for (Vec<string>::iterator it = names2.begin(); it != names2.end(); ++it) {
cout << *it << endl;
}
Vec<string> names3 = names2;
cout << "putout the vector names3" << endl;
for (Vec<string>::size_type i = 0; i != names3.size(); ++i) {
cout << names3[i] << endl;
}
}