Advertisement
Guest User

vector.cc

a guest
May 29th, 2015
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.30 KB | None | 0 0
  1. //--------------------------------------------
  2. // NAME: Ivo Stratev
  3. // CLASS: XIb
  4. // NUMBER: 16
  5. // PROBLEM: #2
  6. // FILE NAME: vector.cc
  7. // FILE PURPOSE:
  8. // Make an implementation of the abstract class Vector.
  9. //---------------------------------------------
  10. #include <iostream>  // In order to use the standart input, outupt and error streams of c++.
  11. #include <stdexcept> // In order to throw standart exceptions such as the base class exception and the class out_of_range
  12. // wich inherites from exception.
  13. #include <cstdlib>  // In order to conver command line arguments from strings to integers.
  14. using namespace std; // Using std in order to avoid writing std:: before cout, out_of_range
  15. // and all other things defined under the std scope.
  16.  
  17. template<typename T> class Vector {
  18.     T* data_; // A private member that stores the Vector value in the heap (the dynamic memory)
  19.     // wich allows the value to change it's size.
  20.     size_t capacity_; // A private member used to hold the size of memory block of the template argument
  21.     // currrently alocated for the coresponding instance.
  22.     size_t size_; // A private member used to indicate the current size of the coresponding instance.
  23.     template <typename Type> friend ostream& operator<<(ostream&, const Vector<Type>&);
  24. public:
  25.     //--------------------------------------------
  26.     // FUNCTION: VEctor
  27.     // Inicializate new blank instance of the class by inicializating capacity_ with capacity,
  28.     // size_ with 0 and allocates new memory block of the template argument, capacity for data_.
  29.     // Also used as default constructor of the class with the default value of the argument equal 1
  30.     // so memory blocks of the class can be created wich requires a default constructor to be done.
  31.     // PARAMETERS:
  32.     // capacity
  33.     // capacity is used to determinate the memory block size.
  34.     //----------------------------------------------
  35.     Vector(size_t capacity = 1)
  36.     : size_(0), capacity_(capacity), data_(new T[capacity]) // Inicializating capacity_ with capacity (not with capacity_
  37.     // since if it was with capacity_ it would throw bad_alloc simply because the inicializating order is the one in wich
  38.     // non static members are declared),
  39.     // size_ with 0 and allocates new memory block of the tempalte argument for data_ capacity long.
  40.     {}
  41.     //--------------------------------------------
  42.     // FUNCTION: Vecotr (overloaded constructor)
  43.     // Creates ne instance of the class with values in the range [first, last), inicializates size_ with the size of the range
  44.     // and capacity with one more than size_, data_ with new memory block of the tempalte argument, capacity_ long and inicializate it.
  45.     // PARAMETERS:
  46.     // first and last
  47.     // first is used as starting value and last is used to indicate the alst value for the object.
  48.     //----------------------------------------------
  49.     Vector(const T& first, const T& last)
  50.     : size_(0), capacity_(0) { // Seting starting values for size_ adn capacity_ = 0 so they can be change later..
  51.         for(T count = first;count < last;++count) // Loop througth first and last the template argument must have
  52.         // valid prefix operator++!
  53.             size_++; // Increment size_ for each element.
  54.         capacity_ = size_ + 1; // Seting capacity_ to one more than size_.
  55.         data_ = new T[capacity_]; // Allocating new memory block, capacity_ long for data_ from the template argment type.
  56.         size_t i = 0; // Defining a counter i and inicializating it with 0.
  57.         for(T count = first;count < last;++count)  // Looping once again througth first and last.
  58.             data_[i++] = count; //Inicializating the element with ofset i from data_.
  59.     }  
  60.     //--------------------------------------------
  61.     // FUNCTION: Vector (overloaded constructor wich is also the copy-constructor of the class)
  62.     // Defining valid copy-constructor for the class, because it's using dinamyc memory to store the value
  63.     // and if it's not a valid one when inicializating new instance of the class with allready created one
  64.     // both will point the same memory block.
  65.     // PARAMETERS:
  66.     // vector
  67.     // A read-only reference to an object of the class wich is going to be used
  68.     // to inicializate new instance as a copy of the passed object.
  69.     //----------------------------------------------
  70.     Vector(const Vector& vector)
  71.     : capacity_(vector.capacity_), size_(vector.size_), data_(new T[vector.capacity_]) { // Inicializates capacity_ and size_
  72.     // with  the passed object capacity_ and size_ and allocates capacity_ long memory block of the tempalte argument for data_.
  73.  
  74.         for(size_t i = 0;i < size_;++i) // Copying the value of the passed argument into newly created instance.
  75.             data_[i] = vector.data_[i];
  76.     }
  77.     //--------------------------------------------
  78.     // FUNCTION: ~Vector (destructor)
  79.     // Used to destory an instance of the class when is no longer needed or goes out of scope by deallocating
  80.     // he memory used for data_ because the destructor generated by the compilator isn't valid since dynamic memory
  81.     // is used for storing data_.
  82.     // PARAMETERS:
  83.     // None.
  84.     //----------------------------------------------
  85.     ~Vector() {
  86.         delete [] data_; // Dealocating the memory used to store the instance value into data_.
  87.     }
  88.     //--------------------------------------------
  89.     // FUNCTION: size
  90.     // Returns size_ value.
  91.     // PARAMETERS:
  92.     // None.
  93.     //----------------------------------------------
  94.     size_t size() const {
  95.         return size_; // Returning size_.
  96.     }
  97.     //--------------------------------------------
  98.     // FUNCTION: capacity
  99.     // Returns capacity_ value.
  100.     // PARAMETERS:
  101.     // None.
  102.     //----------------------------------------------
  103.     size_t capacity() const {
  104.         return capacity_; // Returning capacity_.
  105.     }
  106.     //--------------------------------------------
  107.     // FUNCTION: empty
  108.     // Returns true if the insance of the class is empty (with size_ that equals 0) else returns false.
  109.     // PARAMETERS:
  110.     // None.
  111.     //----------------------------------------------
  112.     bool empty() const {
  113.         return (size_ == 0); // Returning does size_ equals 0.
  114.     }
  115. //--------------------------------------------
  116.     // FUNCTION: clear
  117.     // Clears the instance by setting size_ to 0, capacity_ to 1 and making data_ point to new dynamic char.
  118.     // PARAMETERS:
  119.     // None.
  120.     //----------------------------------------------
  121.     void clear() {
  122.         delete [] data_; // Deallocating the memory block used for storing data_.
  123.         size_ = 0;  // Resets size_.
  124.         capacity_ = 1;  // Setting capacity_ to one.
  125.         data_ = new T;   // Allocate new type of the tempalte argument for data_.
  126.     }
  127.     //--------------------------------------------
  128.     // FUNCTION: operator=
  129.     // If the operand on the left side is defirent than the one on the rigth assigns
  130.     // the value of the one on the rigth to the one on the left because the class is using
  131.     // dynamic memory block to store it's value and the operator generated by the compilator isn't valid.
  132.     // PARAMETERS:
  133.     // vector.
  134.     // vector is used for the assigment.
  135.     //----------------------------------------------
  136.     Vector& operator=(const Vector& vector) {
  137.         if(this != &vector) { //If the operant on the left is deferent from the one on the rigth
  138.         // (avoiding string = string) simply because if this check inst' perfore the data_ will be
  139.         // dealocated and afther a try for copying htat same data_ will be made and an error will ocure.
  140.             delete [] data_; // Deallocating the meomory block that stores the value of the class in data_.
  141.             size_ = vector.size_; // Copying the argument's size_.
  142.             capacity_ = vector.capacity_; // Alse copying it's capacity_ since a direct copy is requested.
  143.             data_ = new T[capacity_]; // Allocating new memory block for data_ capacity_ long.
  144.             for(size_t i = 0;i < size_;++i) // Coppying the values for the argument to the current instance.
  145.                 data_[i] = vector.data_[i];
  146.         }
  147.         return *this; // And returning reference to the current object.
  148.     }
  149.     //--------------------------------------------
  150.     // FUNCTION: operator[]
  151.     // Return the value with ofset the argument index from data_ if index is less than size_ else throws
  152.     // standtart out_of_range exception.
  153.     // PARAMETERS:
  154.     // index
  155.     // index is used to return the element on that index.
  156.     //----------------------------------------------
  157.     T& operator[](size_t index) {
  158.         if(index >= size_)  // If index isn't valid index throws standart out_of_range exception.
  159.             throw out_of_range("Invalid index"); // Throws standart out_of_range exception.
  160.         return data_[index]; // If the program control isn't redirected to out_of_range returns data_[index].
  161.     }
  162.     //--------------------------------------------
  163.     // FUNCTION: operator[] (overloaded)
  164.     // Return the value with ofset the argument index from data_ if index is less than size_ else throws
  165.     // standtart out_of_range exception this is and overloaded version of operator[] that returns constandt reference
  166.     // and it's used to constant instances of the class only (the desision is made by the compilator during compilation time).
  167.     // PARAMETERS:
  168.     // index
  169.     // index is used to return the element on that index.
  170.     //----------------------------------------------
  171.     const T& operator[](size_t index) const{
  172.         return operator[](index);
  173.     }
  174.     //--------------------------------------------
  175.     // FUNCTION: front
  176.     // Returns reference to the first element of an instance.
  177.     // PARAMETERS:
  178.     // None.
  179.     //--------------------------------------------
  180.     T& front() {
  181.         return *data_;  // Dereferencing the memory that data_ points to.
  182.     }
  183.     //--------------------------------------------
  184.     // FUNCTION: front (overloaded)
  185.     // Returns  constant reference to the first element of an instance this method is used only on
  186.     // constant objects.
  187.     // PARAMETERS:
  188.     // None.
  189.     //--------------------------------------------
  190.     const T& front() const{
  191.         return front(); // Retrunting a constant reference to what the non-cosnt variant returns
  192.         // the magic is this that if the object is cosntant the non-const method will get a constant
  193.         // value and it will return a reference to that wich will than be converted to constant reference.
  194.     }
  195.     //--------------------------------------------
  196.     // FUNCTION: back
  197.     // Returns reference to the last element of an instance.
  198.     // PARAMETERS:
  199.     // None.
  200.     //--------------------------------------------
  201.     T& back() {
  202.         return *(data_ + size_ - 1); // Dereferencing the memory that data_ with an ofset (size_ + 1) points to.
  203.     }
  204.     //--------------------------------------------
  205.     // FUNCTION: back (overloaded)
  206.     // Returns  constant reference to the first element of an instance this method is used only on
  207.     // constant objects.
  208.     // PARAMETERS:
  209.     // None.
  210.     //--------------------------------------------
  211.     const T& back() const{
  212.         return back(); //Same trick made as front() but returning a constant reference to the last element.
  213.     }
  214.     //--------------------------------------------
  215.     // FUNCTION: ensure_capacity
  216.     // Checks if the requested increase of the block is avalible or not and if isn't it makes it.
  217.     // number
  218.     // number is used to request the increasment.
  219.     //----------------------------------------------
  220.     void ensure_capacity(size_t number = 1) {
  221.         int check = capacity_ - (size_ + number); // Performing a calcolation to see how much space isn't avalible.
  222.         if(check < 0) { // Performing a check to see if some space isn't avalible.
  223.             T* old_data = data_; // Copy the starting adress of data_.
  224.             capacity_ += (check *= -1); // Increase capacity with the space  that isn't avalible.
  225.             data_ = new T[capacity_]; // Allocating new momory block for data_ capacity_ long.
  226.             for(size_t i = 0; i < size_;++i) // Saving the old value again to data_.
  227.                 data_[i] = old_data[i];
  228.             delete [] old_data; // Deallocating the old memory block used to store data_.
  229.         }
  230.     }
  231.     // FUNCTION: push_back
  232.     // Adding an element at the end of the trace of data_ by efectivly incrising the container size with 1.
  233.     // PARAMETERS:
  234.     // val
  235.     // val is the value that's gonna be added to the current object.
  236.     //----------------------------------------------
  237.     void push_back(const T& val) {
  238.         ensure_capacity(); // Check does 1 space is avalible if not add one.
  239.         data_[size_++] = val; // Add val at the end and increment size_.
  240.     }
  241.     // FUNCTION: push_back
  242.     // Removing the last element by efectivly decrasing the container size with 1.
  243.     // PARAMETERS:
  244.     // None
  245.     void pop_back() {
  246.         if(empty()) // If no values can be poped throws a standart base class from wich all other
  247.         // eception classes inherit from: exception.
  248.             throw exception();
  249.         size_--; // Reduce size with one.
  250.     }
  251.     class Iterator {
  252.     protected:  T* pos_; // A protected member (protected so other iterator classes can inherit Iterator and still have acces to pos_), pointer that's gonna points to a single element of an instance.
  253.     public:
  254.         //--------------------------------------------
  255.         // FUNCTION: Iterator (constructor and default constructor of the class)
  256.         // Inicializates where to point pos_ default value is NULL ptr or 0.
  257.         // PARAMETERS:
  258.         // pos
  259.         // position is used as the position to where pos_ needs to point to.
  260.         //----------------------------------------------
  261.         Iterator(T* pos = 0)
  262.         : pos_(pos) // Inicializating pos_.
  263.         {}
  264.         //--------------------------------------------
  265.         // FUNCTION: operator++ (prefix)
  266.         // Makes pos_ point to one afther where currently is pointing to.
  267.         // PARAMETERS:
  268.         // None.
  269.         //----------------------------------------------
  270.         Iterator operator++() {
  271.             pos_++; // Increment pos_.
  272.             return *this; // and returning the current object afther the repostition.
  273.         }
  274.         //--------------------------------------------
  275.         // FUNCTION: operator++ (postfix)
  276.         // Makes pos_ point to one afther where currently is pointing to but returning
  277.         // the current position by memory copying the object.
  278.         // PARAMETERS:
  279.         // None (a fictive one just so the compilator knows wich one operator to predifine).
  280.         //----------------------------------------------
  281.         Iterator operator++(int) {
  282.             Iterator result(pos_); // Memory copying the current instance.
  283.             pos_++; // Increment pos_.
  284.             return result; // Returning the copy.
  285.         }
  286.         //--------------------------------------------
  287.         // FUNCTION: operator==
  288.         // Compeare two instances and returns does they are equal.
  289.         // PARAMETERS:
  290.         // iterator
  291.         // iterator is the object with wich the comparearsion is made.
  292.         //----------------------------------------------
  293.         bool operator==(const Iterator& iterator) const{
  294.             return (pos_ == iterator.pos_); // Returning does the operand on left is equal to
  295.             // the one on rigth.
  296.         }
  297.         //--------------------------------------------
  298.         // FUNCTION: operator!=
  299.         // Compear two instances and returns does they aren't equal.
  300.         // PARAMETERS:
  301.         // iterator
  302.         // iterator is the object with wich the comparearsion is made.
  303.         //----------------------------------------------
  304.         bool operator!=(const Iterator& iterator) const{
  305.             return !(operator==(iterator)); // Returning does the operand on left isn't equal to
  306.             // the one on rigth by inverting the result from performing operator==.
  307.         }
  308.         //--------------------------------------------
  309.         // FUNCTION: operator*
  310.         // Returns the value at wich the instance is pointing to at an instance of Vector.
  311.         // PARAMETERS:
  312.         // None
  313.         //----------------------------------------------
  314.         char& operator*() {
  315.             return *pos_; // Return the value by dereferencing position_.
  316.         }
  317.         //--------------------------------------------
  318.         // FUNCTION: operator->
  319.         // Returns the pointer at wich the instance is pointing to at an instance of Vector.
  320.         // PARAMETERS:
  321.         // None
  322.         //----------------------------------------------
  323.         T* operator->() {
  324.             return pos_; // Return pos_.
  325.         }
  326.     };
  327.     class Const_Iterator: public Vector::Iterator {
  328.     public:
  329.         //--------------------------------------------
  330.         // FUNCTION: Const_Iterator (constructor and default constructor of the class)
  331.         // Inicializates where to point pos_ default value is NULL ptr or 0 by using Iterator's constructor.
  332.         // PARAMETERS:
  333.         // pos
  334.         // position is used as the position to where pos_ needs to point to.
  335.         //----------------------------------------------
  336.         Const_Iterator(T* pos = 0)
  337.         : Iterator(pos)
  338.         {}
  339.         const T& operator*() {
  340.             return *(Iterator::pos_);
  341.         }
  342.         const T* operator->() {
  343.             return *(Iterator::pos_);
  344.         }
  345.     };
  346.     class Reverse_Iterator: public Vector::Iterator {
  347.     public:
  348.          //--------------------------------------------
  349.         // FUNCTION: Reverse_Iterator (constructor and default constructor of the class)
  350.         // Inicializates where to point pos_ default value is NULL ptr or 0 by using Iterator's constructor.
  351.         // PARAMETERS:
  352.         // pos
  353.         // position is used as the position to where pos_ needs to point to.
  354.         //----------------------------------------------
  355.         Reverse_Iterator(T* pos = 0)
  356.         : Iterator(pos)
  357.         {}
  358.         Reverse_Iterator operator++() {
  359.             Iterator::pos_--;
  360.             return *this;
  361.         }
  362.         Reverse_Iterator operator++(int) {
  363.             Reverse_Iterator res(Iterator::pos_);
  364.             Iterator::pos_--;
  365.             return res;
  366.         }
  367.     };
  368.     class Const_Reverse_Iterator: public Vector::Const_Iterator, public Vector::Reverse_Iterator {
  369.     public:
  370.         //--------------------------------------------
  371.         // FUNCTION: Const_Reverse_Iterator (constructor and default constructor of the class)
  372.         // Inicializates where to point pos_ default value is NULL ptr or 0 by using Reverse_Iterator's and Const_Iterator's constructors.
  373.         // PARAMETERS:
  374.         // pos
  375.         // position is used as the position to where pos_ needs to point to.
  376.         //----------------------------------------------
  377.         Const_Reverse_Iterator(T* pos)
  378.         : Reverse_Iterator(pos), Const_Iterator(pos)
  379.         {} 
  380.         using Const_Iterator::operator*;
  381.         using Const_Iterator::operator->;
  382.     };
  383.     Iterator begin() {
  384.         return Iterator(data_);
  385.     }
  386.     Iterator end() {
  387.         return Iterator(data_ + size_);
  388.     }
  389.     Const_Iterator begin() const{
  390.         return Const_Iterator(data_);
  391.     }
  392.     Const_Iterator end() const{
  393.         return Const_Iterator(data_ + size_);
  394.     }
  395.     Reverse_Iterator rbegin() {
  396.         return Reverse_Iterator(data_ + (size_ - 1));
  397.     }
  398.     Reverse_Iterator rend() {
  399.         return Reverse_Iterator(data_ - 1);
  400.     }
  401.     Const_Reverse_Iterator rbegin() const{
  402.         return Const_Reverse_Iterator(data_ + (size_ - 1));
  403.     }
  404.     Const_Reverse_Iterator rend() const{
  405.         return Const_Reverse_Iterator(data_ - 1);
  406.     }
  407.     Iterator insert(Iterator pos, const T& val) {
  408.         T* old_data = data_;
  409.         if(capacity_ == size_)
  410.             capacity_++;
  411.         data_ = new T[capacity_];
  412.         size_t i;
  413.         for(i = 0;old_data + i != pos.operator->();++i)
  414.             data_[i] = old_data[i];
  415.         data_[i] = val;
  416.         Iterator res(data_ + i);
  417.         for(;i < size_;++i)
  418.             data_[i + 1] = old_data[i];
  419.         size_++;
  420.         delete [] old_data;
  421.         return res;
  422.     }
  423.     Iterator erase(Iterator pos) {
  424.          size_t i = 0;
  425.          int new_pos = -1;
  426.         for(Iterator it = begin();it != end();++it) {
  427.             if(it != pos) {
  428.                 data_[i] = *it;
  429.                 ++i;
  430.            } else
  431.                 new_pos = i;
  432.        }
  433.        size_--;
  434.        if(new_pos == -1)
  435.         return end();
  436.         return Iterator(data_ + new_pos);
  437.     }
  438.     Iterator erase(Iterator first, Iterator last) {
  439.         size_t i = 0;
  440.         for(Iterator it = begin();it != first;++it) {
  441.             data_[i] = *it;
  442.             ++i;
  443.        }
  444.        size_t pos = i;
  445.        for(Iterator it2(last.operator->());it2 != end;++it2) {
  446.             data_[i] = *it2;
  447.             ++i;
  448.        }
  449.        size_ = i;
  450.         return Iterator(data_ + pos);
  451.     }
  452. };
  453.  
  454. template <typename Type> ostream& operator<<(ostream& out, const Vector<Type>& vector) {
  455.     cout << '{';
  456.     for(size_t i = 0;i < vector.size_;++i)
  457.         cout << vector.data_[i] << ", ";
  458.     cout << '}';
  459.     return out;
  460. }
  461.  
  462. int main(int argc, char** argv) {
  463.     Vector<int> v1(atoi(argv[1]), atoi(argv[2]));
  464.     Vector<int> v2(atoi(argv[3]), atoi(argv[4]));
  465.     cout << "v1: " << v1 << endl;
  466.     cout << "v2: " << v2 << endl;
  467.     size_t count = 0;
  468.     for(Vector<int>::Iterator it1 = v1.begin();it1 != v1.end();++it1) {
  469.         for(Vector<int>::Iterator it2 = v2.begin();it2 != v2.end();++it2) {
  470.             if(*it1 == *it2) {
  471.                 count++;
  472.                 break;
  473.             }
  474.         }
  475.     }
  476.     cout << "equal element in v1 and v2: " << count << endl;
  477.     v1.push_back(-100);
  478.     v2.push_back(-100);
  479.     cout << "v1: " << v1 << endl;
  480.     cout << "v2: " << v2 << endl;
  481.     Vector<int> v(v2);
  482.     cout << "v: " << v << endl;
  483.     for(Vector<int>::Reverse_Iterator rit = v1.rbegin();rit != v1.rend();++rit)
  484.         v.insert(v.begin(), *rit);
  485.     cout << "v: " << v << endl;
  486.     Vector<int>::Iterator bit = v.begin();
  487.     for(;bit != v.end();++bit) {
  488.         if(*bit == -100)
  489.             break;
  490.     }
  491.     v.erase(bit, v.end());
  492.     v.erase(++++v.begin());
  493.     cout << "v: " << v << endl;
  494.     return 0;
  495. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement