#ifndef VECTOR
#define VECTOR
template<typename T>
struct vector
{
private:
T *buffer;
unsigned long sz;
unsigned long cap;
public:
typedef T value_type;
typedef value_type& reference;
typedef const reference const_reference;
typedef value_type* pointer;
typedef const pointer const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef unsigned long size_type;
typedef ptrdiff_t difference_type;
vector() : buffer(new int[10]), sz(0), cap(10) {}
vector(size_t s) : buffer(new int[sz]), sz(s), cap(s){}
vector(size_t s, const T& initial) : buffer(new int[sz]), sz(s), cap(s) { for(size_t i = 0; i < sz; i++) buffer[i] = initial; }
template<typename container, typename It>
vector(typename container::It beg, typename container::It end)
{
It iter(beg);
sz = ptrdiff_t(beg-end);
cap = sz;
for(int i = 0; i < sz; i++)
{
buffer[i] = iter++;
}
}
~vector() {delete [] buffer;}
iterator begin() {return buffer;}
const_iterator begin() const {return buffer;}
iterator end() {return buffer+sz;}
const_iterator end() const {return buffer+sz;}
void reserve(size_t newCap)
{
if(newCap <= cap) return;
T *oldBuffer = buffer;
buffer = new T[newCap];
for(int i = 0; i < cap; i++)
{
buffer[i] = oldBuffer[i];
}
cap = newCap;
delete [] oldBuffer;
}
void resize(size_t newSz, const T& initial = T())
{
if(newSz > cap)
reserve((newSz*2+1)%(max_size()+1));
if(newSz > sz)
{
for(int i = sz; i < newSz; i++)
buffer[i] = initial;
}
sz = newSz;
}
size_t size() const {return sz;}
size_t capacity() const {return cap;}
bool empty() const {return sz == 0;}
size_t max_size() const {return 1073741823;}
void push_back(T toP)
{
if(sz >= cap)
reserve((cap*2+1)%(max_size()+1));
buffer[sz++] = toP;
}
T pop_back()
{
T ret = buffer[sz-1];
buffer[sz-1] = T();
sz--;
return ret;
}
reference front() { return buffer[0]; }
const_reference front() const { return buffer[0]; }
reference back() { return buffer[sz-1]; }
const_reference back() const { return buffer[sz-1]; }
T& operator[](size_t index) {if(index >= sz) throw std::out_of_range("out_of_rane"); return buffer[index]; }
const T& operator[] (size_t index) const {if(index >= sz) throw std::out_of_range("out_of_rane"); return buffer[index];}
T& at(size_t index) { return (*this)[index]; }
const T& at(size_t index) const { return (*this)[index]; }
};
#endif
This is an implementation of the vector class. It uses a dynamic array of type T, which grows bigger with the function reserve(). How it would be like if I used the allocator class to implement it? (the whole vector class, not just the reserve function)
template<class T, class Allocator = allocator<T> >
This is how it looks like on the file stl_vector.h
The default allocator of the STL effectively calls the new operator to do its work. So I assume that won’t change much. But, performance questions can never be sufficiently answered by looking at the code. Instead you should implement both versions and measure with some typical test data.