I haven't really programmed in C++ for about a year, and realised that I should get back into it, and tried my abilities out by remaking the STD vector class. However, my C++ is a bit rusty at the moment, and was wondering if I have made many mistakes in my implementation.
# ifndef VECTOR_H
# define VECTOR_H
# include <memory>
namespace test
{
template
<class T,
class A>
class vector;
template
<class A>
class vector_alloc_types
{
public:
typedef typename A::value_type value_type;
typedef typename A::size_type size_type;
typedef typename A::reference reference;
typedef typename A::const_reference const_reference;
typedef typename A::pointer iterator;
typedef typename A::const_pointer const_iterator;
typedef typename A::const_pointer const_pointer;
typedef A allocator_type;
};
template
<class T,
class A>
class vector_base
{
friend class vector<T, A>;
public:
typedef typename A::pointer pointer;
vector_base()
{
vm_begin = pointer();
value_end = pointer();
memory_end = pointer();
}
private:
pointer vm_begin, value_end, memory_end;
};
template
<class T,
class A = std::allocator<T> >
class vector
: public vector_alloc_types<A>,
public vector_base<T, A>
{
public:
typedef vector<T, A> my_T;
typedef vector_base<T, A> my_base;
vector()
: my_base()
{
}
vector(my_T const &rhs)
{
if (allocate(rhs.size()))
{
try
{
this->value_end = std::uninitialized_copy(rhs.vm_begin, rhs.value_end, this->vm_begin);
}
catch (...)
{
kill();
throw;
}
}
}
vector(pointer first, pointer last)
: my_base()
{
if (allocate(std::distance(first, last)))
{
try
{
this->value_end = std::uninitialized_copy(first, last, this->vm_begin);
}
catch (...)
{
kill();
throw;
}
}
}
template<size_type sz>
vector(T arr[sz])
{
if (allocate(sz))
{
try
{
this->value_end = std::uninitialized_copy_n(arr, sz, this->vm_begin);
}
catch (...)
{
kill();
throw;
}
}
}
vector(size_type sz)
{
if (allocate(sz))
{
try
{
this->value_end = std::uninitialized_fill_n(this->vm_begin, sz, T());
}
catch (...)
{
kill();
throw;
}
}
}
vector(size_type sz, T const &val)
{
if (allocate(sz))
{
try
{
this->value_end = std::uninitialized_fill_n(this->vm_begin, sz, val);
}
catch (...)
{
kill();
throw;
}
}
}
~vector()
{
kill();
}
void operator=(my_T &rhs)
{
if (this != &rhs)
{
assign(rhs);
}
}
template<unsigned sz>
void operator=(T (&arr)[sz])
{
assign(&arr[0], &arr[sz]);
}
void clear()
{
wipe(this->vm_begin, this->value_end);
}
iterator begin()
{
return (this->vm_begin);
}
const_iterator cbegin() const
{
return ((const_iterator)this->vm_begin);
}
iterator end()
{
return (this->value_end);
}
const_iterator cend() const
{
return ((const_iterator)this->value_end);
}
void swap(my_T &rhs)
{
std::swap(this->vm_begin, rhs.vm_begin);
std::swap(this->value_end, rhs.value_end);
std::swap(this->memory_end, rhs.memory_end);
}
void shrink_to_fit()
{
if (has_spare_capacity())
{
my_T tmp(*this);
swap(tmp);
}
}
void erase(iterator iter)
{
pointer tmp;
if (iter == (this->value_end - 1))
{
pop_back();
}
else if (iter == this->vm_begin)
{
pop_front();
}
else if (iterator_in_range(iter))
{
tmp = allocator_type().allocate(size() - 1);
pointer tmp2 = std::uninitialized_copy(this->vm_begin, iter, tmp);
tmp2 = std::uninitialized_copy((iter + 1), this->value_end, tmp2);
assign(tmp, tmp2);
}
}
void erase(iterator first, iterator last)
{
if (last == (this->value_end - 1))
{
while (last-- != first)
{
pop_back();
}
pop_back();
}
else if (first == this->vm_begin)
{
while (first++ != last)
{
pop_front();
}
pop_front();
}
else if (iterator_in_range(first) && iterator_in_range(last))
{
pointer tmp = allocator_type().allocate(size() - std::distance(first, last));
pointer tmp2 = std::uninitialized_copy(this->vm_begin, first, tmp);
tmp2 = std::uninitialized_copy((last + 1), this->value_end, tmp2);
assign(tmp, tmp2);
}
}
void insert(iterator iter, T const &val)
{
T v1 = val;
if (iter == this->vm_begin)
{
push_front(v1);
}
else if (iter == (this->value_end - 1))
{
push_back(v1);
}
else if (iterator_in_range(iter))
{
allocator_type alloc;
pointer tmp = alloc.allocate(realloc_size(size() + 1));
pointer tmp2 = std::uninitialized_copy(this->vm_begin, iter, tmp);
alloc.construct(tmp2++, v1);
tmp2 = std::uninitialized_copy(iter, this->value_end, tmp2);
assign(tmp, tmp2);
}
}
void insert(iterator iter, int count, T const &val)
{
T v1 = val;
if (iter == this->vm_begin)
{
while (count--)
{
push_front(v1);
}
}
else if (iter == (this->value_end - 1))
{
while (count--)
{
push_back(v1);
}
}
else if (iterator_in_range(iter))
{
allocator_type alloc;
pointer tmp = alloc.allocate(realloc_size(size() + 1));
pointer tmp2 = std::uninitialized_copy(this->vm_begin, iter, tmp);
while (count--)
{
alloc.construct(tmp2++, v1);
}
tmp2 = std::uninitialized_copy(iter, this->value_end, tmp2);
assign(tmp, tmp2);
}
}
void insert(iterator iter, iterator first, iterator last)
{
if (iter == this->vm_begin)
{
while (first != last)
{
push_front(*(first++));
}
}
else if (iter == (this->value_end - 1))
{
while (first != last)
{
push_back(*(first++));
}
}
else if (iterator_in_range(iter))
{
allocator_type alloc;
pointer tmp = alloc.allocate(realloc_size(size() + 1));
pointer tmp2 = std::uninitialized_copy(this->vm_begin, iter, tmp);
while (first != last)
{
alloc.construct(tmp2++, *(first++));
}
tmp2 = std::uninitialized_copy(iter, this->value_end, tmp2);
assign(tmp, tmp2);
}
}
void push_back(T const &val)
{
allocator_type alloc;
T v1 = val;
if (has_spare_capacity())
{
this->value_end++;
alloc.construct(this->value_end - 1, v1);
}
else if (reallocate(realloc_size(size() + 1)))
{
this->value_end++;
alloc.construct(this->value_end - 1, v1);
}
}
void pop_back()
{
pointer tmp = allocator_type().allocate(size() - 1);
pointer tmp2 = std::uninitialized_copy(this->vm_begin, this->value_end - 1, tmp);
assign(tmp, tmp2);
}
void push_front(T const &val)
{
allocator_type alloc;
T v1 = val;
vector tmp;
tmp.push_back(v1);
for (iterator it = this->vm_begin; it != this->value_end; ++it)
{
tmp.push_back(*it);
}
swap(tmp);
}
void pop_front()
{
pointer tmp = allocator_type().allocate(size() - 1);
pointer tmp2 = std::uninitialized_copy(this->vm_begin + 1, this->value_end, tmp);
assign(tmp, tmp2);
}
size_type size() const
{
return (this->value_end - this->vm_begin);
}
reference operator[](size_type pos)
{
return (*(this->vm_begin + pos));
}
const_reference operator[](size_type pos) const
{
return (*(this->vm_begin + pos));
}
private:
bool allocate(size_type sz)
{
allocator_type alloc;
if (alloc.max_size() > sz)
{
try
{
this->vm_begin = alloc.allocate(sz);
this->value_end = this->vm_begin;
this->memory_end = this->vm_begin + sz;
}
catch (...)
{
kill();
throw;
}
return (true);
}
return (false);
}
bool reallocate(size_type sz)
{
allocator_type alloc;
if (alloc.max_size() > sz)
{
try
{
pointer nbegin, nvend, nmend;
nbegin = alloc.allocate(sz);
nmend = nbegin + sz;
nvend = std::uninitialized_copy(this->vm_begin, this->value_end, nbegin);
this->vm_begin = nbegin;
this->value_end = nvend;
this->memory_end = nmend;
}
catch (...)
{
kill();
throw;
}
return (true);
}
return (false);
}
size_type realloc_size(size_type sz) const
{
return ((allocator_type().max_size() > (sz * 1.5)) ? (sz * 1.5) : sz);
}
bool iterator_in_range(const_iterator iter) const
{
return (iter >= this->vm_begin && iter < this->value_end);
}
void assign(my_T &rhs)
{
assign(rhs.vm_begin, rhs.value_end);
}
void assign(pointer first, pointer last)
{
size_type sz = std::distance(first, last);
if (sz > capacity())
{
if (reallocate(realloc_size(sz)))
{
wipe(this->vm_begin, this->value_end);
this->value_end = std::uninitialized_copy(first, last, this->vm_begin);
}
}
else
{
wipe(this->vm_begin, this->value_end);
this->value_end = std::uninitialized_copy(first, last, this->vm_begin);
}
}
void wipe(pointer ptr)
{
allocator_type().destroy(ptr);
}
void wipe(pointer first, pointer last)
{
allocator_type alloc;
while (first != last)
{
alloc.destroy(first++);
}
}
void wipe(pointer ptr, size_type dist)
{
allocator_type alloc;
while (dist-- != 0)
{
alloc.destroy(ptr);
}
}
void kill()
{
if (this->vm_begin != pointer())
{
wipe(this->vm_begin, this->value_end);
allocator_type().deallocate(this->vm_begin, capacity());
}
}
inline size_type capacity() const
{
return (this->memory_end - this->vm_begin);
}
inline size_type spare_capacity() const
{
return (this->memory_end - this->value_end);
}
bool has_spare_capacity() const
{
return (spare_capacity() > 0);
}
};
}
# endif
fatal error: unknown type name 'pointer'
on this line:vector(pointer first, pointer last)
Where is your type "pointer" defined? The compiler does not know and I do not know. \$\endgroup\$