Skip to content

Instantly share code, notes, and snippets.

@sethprog26
Created May 10, 2021 07:40
Show Gist options
  • Save sethprog26/eb52c5857c8693e2294376de219cf078 to your computer and use it in GitHub Desktop.
Save sethprog26/eb52c5857c8693e2294376de219cf078 to your computer and use it in GitHub Desktop.
Class 12 Drill
#include "std_lib_facilities.h"
template<typename T, typename A = allocator<T>>
class our_vector {
A alloc;
size_t sz;
T* elem;
size_t space;
public:
using iterator = T*;
our_vector() :sz{ 0 }, elem{ nullptr }, space{ 0 } {}; //Default Constructor
explicit our_vector(size_t s) :sz{ s }, elem{ alloc.allocate(s)}, space{ s }{ //Normal Constructor
for (T* p = elem; p != elem + s; p++)
alloc.construct(p, T());
}
our_vector(const our_vector<T, A>& vec); //Copy constructor
our_vector<T, A>& operator=(const our_vector<T, A>& vec); //Copy Assignment
our_vector(our_vector<T, A>&& vec); //Move Constructor
our_vector<T, A>& operator=(our_vector<T, A>&& vec); //Move Assignment
~our_vector() { //Destructor
for (int i = 0; i < sz; ++i)
alloc.destroy(&elem[i]);
alloc.deallocate(elem, space);
}
T& operator[](int n) { return elem[n]; } //For non-const vectors
iterator begin() { return elem; }
iterator end() { return elem + sz; }
iterator back() { return elem + sz - 1;}
iterator insert(iterator p, const T& val) {
int index = p - begin();
if(size() == capacity()) {
reserve(size() == 0 ? 8 : 2 * size());
}
alloc.construct(elem + sz, *back());
++sz;
iterator pp = begin() + index;
for (auto pos = end() - 1; pos != pp; --pos) {
*pos = *(pos - 1);
}
*(begin() + index) = val;
return pp;
}
iterator erase(iterator p) {
if (p == end()) return p;
for (auto pos = p+1; pos != end(); ++pos) {
*(pos-1) = *pos;
}
alloc.destroy(&(end() - 1));
--sz;
return p;
}
int size() const { return sz; };
void print();
void reserve(int newalloc);
int capacity() const { return space; }
void resize(int newsize, T val = T());
void push_back(T& val);
T& at(int n) {
if (n < 0 || sz < n)
throw std::out_of_range("It is out of range access!");
return elem[n];
}
};
template<typename T, typename A> our_vector<T, A>::our_vector(const our_vector<T, A>& vec) : sz{ vec.sz }, elem{ alloc.allocate(sz) }, space{ vec.sz } { //Copy constructor
copy(vec.elem, vec.elem + sz, elem);
}
template<typename T, typename A> our_vector<T, A>& our_vector<T, A>::operator=(const our_vector<T, A>& vec) {
if (this == &vec)
return *this;
if (vec.sz <= space) { //never decrease deallocation
copy(vec.elem, vec.elem + vec.sz, elem);
/*for (int i = 0; i < vec.sz; i++)
elem[i] = vec.elem[i];*/
for (int i = vec.sz; i < sz; ++i)
alloc.destroy(&elem[i]);
sz = vec.sz;
return *this;
}
T* p = alloc.allocate(vec.sz); // allocate new space
copy(vec.elem, vec.elem + vec.sz, p); // copy elements
for (int i = 0; i < sz; ++i) // deallocate old space
alloc.destroy(&elem[i]);
alloc.deallocate(elem, space);
space = sz = vec.sz;
elem = p; // now we can reset elem
return *this; // return a self-reference
}
template<typename T, typename A> our_vector<T,A>::our_vector(our_vector<T, A>&& vec) : sz{ vec.sz }, elem{ vec.elem }, space{ vec.space } { //Move Constructore
vec.sz = 0;
vec.elem = nullptr;
}
template<typename T, typename A> our_vector<T, A>& our_vector<T, A>::operator=(our_vector<T, A>&& vec) { //Move Assignment
for (int i = 0; i < sz; ++i) // deallocate old space
alloc.destroy(&elem[i]);
alloc.deallocate(elem, space);
elem = vec.elem; // copy a’s elem and sz
sz = vec.sz;
space = vec.space;
vec.elem = nullptr; // make a the empty vector
vec.sz = 0;
return *this; // return a self-reference
}
template<typename T, typename A> void our_vector<T, A>::reserve(int newalloc) { //reserve
if (newalloc <= space) return; // never decrease allocation
T* p = alloc.allocate(newalloc); // allocate new space
for (int i = 0; i < sz; ++i)
alloc.construct(&p[i], elem[i]); // copy old elements
for (int i = 0; i < sz; ++i) // deallocate old space
alloc.destroy(&elem[i]);
alloc.deallocate(elem, space);
elem = p;
space = newalloc;
}
template<typename T, typename A> void our_vector<T, A>::resize(int newsize, T val) {
reserve(newsize);
for (int i = sz; i < newsize; i++)
alloc.construct(&elem[i], val);
for (int i = newsize; i < sz; i++)
alloc.destroy(&elem[i]);
sz = newsize;
}
template<typename T, typename A> void our_vector<T, A>::push_back(T& val) { //increase vector size by one; initialize the new element with d
if (space == 0)
reserve(8); // start with space for 8 elements
else if (sz == space)
reserve(2 * space); // get more space
alloc.construct(&elem[sz], val);
++sz; // increase the size (sz is the number of elements)
}
template<typename T, typename A> void our_vector<T, A>::print() {
for (int i = 0; i < sz; i++) {
cout << elem[i] << " ";
}
cout << endl;
}
int main() {
try {
our_vector<string> p(2);
p[0] = "first";
p[1] = "second";
cout << p.at(3)<< endl;
}
catch(out_of_range e){
cout << e.what() << endl;
}
our_vector<double>* n_p = new our_vector<double>();
cout << n_p->size() << endl;
cout << n_p->capacity() << endl;
n_p->resize(10);
cout << n_p->size() << endl;
cout << n_p->capacity() << endl;
double x = 2;
n_p->push_back(x);
cout << n_p->size() << endl;
cout << n_p->capacity() << endl;
n_p->print();
//Copy check
our_vector<double>* copy_p(n_p);
cout << copy_p->size() << endl;
cout << copy_p->capacity() << endl;
copy_p->print();
our_vector<double>* copy_assign = copy_p;
cout << copy_assign->size() << endl;
cout << copy_assign->capacity() << endl;
copy_assign->print();
//Foreach loop ( begin + end )
for (double v : *copy_assign) {
cout << v << " ";
}
cout << endl;
// Insert
cout << "---" << endl;
our_vector<double> insert_vector;
insert_vector.insert(insert_vector.begin(), 1.0);
insert_vector.insert(insert_vector.begin(), 2.0);
for (double v : insert_vector) {
cout << v << " ";
}
cout << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment