Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Ashley Vu PIC 10B Intermediate Programming
- ID: 704341775 Spring 2016
- Email: avu5@ucla.edu Assignment #4
- Section: 4C
- */
- #ifndef templated_vector_h
- #define templated_vector_h
- #include <iostream>
- #include <vector>
- #include <string>
- #include <cassert>
- #include <iomanip>
- #include <cmath>
- // Interface
- template<typename T>
- class MyVector {
- public:
- // 1. Default constructor
- MyVector(){
- std::cout << "Standard constructor called..." << std::endl;
- currentCapacity = INITIAL_SIZE;
- numItems = 0;
- theData = new T[INITIAL_SIZE];
- }
- // 2. Destructor
- ~MyVector(){
- std::cout << "Destructor called. Releasing memory..." << std::endl;
- delete[] theData;
- theData = NULL ;
- }
- // 3. Copy constructor
- MyVector( const MyVector& b ){
- std::cout << "Copy constructor called..." << std::endl;
- // shallow copy non-pointers
- currentCapacity = b.currentCapacity;
- numItems = b.numItems;
- // deep copy pointers
- if ( b.theData ){ // same as if ( b.theData != NULL )
- theData = new T[b.currentCapacity];
- for (int i=0 ; i < b.numItems ; i++ )
- theData[i] = b.theData[i];
- }
- else
- theData = NULL;
- }
- // 4. Operator=. The return is by reference to allow for chaining.
- MyVector& operator=( const MyVector& b ){
- std::cout << "Operator= called..." << std::endl;
- // check for self-assignment
- if ( this == &b )
- return *this;
- // de-allocate memory in current object
- delete[] this->theData;
- // shallow copy non-pointers
- currentCapacity = b.currentCapacity;
- numItems = b.numItems;
- // deep copy pointers (if necessary)
- if ( b.theData ){ // same as if ( b.theData != NULL )
- theData = new T[b.currentCapacity];
- for ( int i=0 ; i < b.numItems ; i++ )
- theData[i] = b.theData[i];
- }
- else
- theData = NULL;
- return *this;
- }
- // OTHER MEMBER FUNCTIONS
- // Pushes back paramater into vector
- void push_back( T newValue ){
- // make sure there is enough space
- if ( numItems == currentCapacity )
- reserve( currentCapacity + 1 );
- theData[numItems] = newValue; // same as *(theData + numItems) = newValue
- numItems++; //updates numItems
- return;
- }
- // Returns number of items in vector
- int size() const{
- return numItems;
- }
- // Setter for operator[] -- sets value of index in vector
- T& operator[](int index){
- assert((index>=0) && (index < numItems));
- return theData[index];
- }
- // Getter for operator[] -- returns value of index in vector
- const T& operator[](int index) const{
- assert((index>=0) && (index < numItems));
- return theData[index];
- }
- // Sums value of index i in LHS vector with value of index i in RHS vector
- MyVector operator+( const MyVector& b) {
- assert(b.size() == size());
- MyVector<T> newVec; //create new vector to store sum values
- for (int i=0; i <b.size() ; i++)
- newVec.push_back( theData[i] + b[i] );
- return newVec;
- }
- // Sums values of index i in LHS vector with value of index i in RHS vector; updates implicit vector with sums
- MyVector& operator+=( const MyVector& b) {
- assert(b.size() == size());
- for (int i=0; i <b.size() ; i++)
- theData[i] += b[i];
- return *this;
- }
- // Normalization function
- T normal() const
- {
- return sqrt((*this) * (*this)); //prevents negatives
- }
- // Dot Product Operator Friend Declaration -- do I need??
- template<typename Tx>
- friend Tx operator*(const MyVector<Tx>& a, const MyVector<Tx>& b);
- private:
- // Requests memory from heap and copies old data to new location
- void reserve(int newCapacity){
- if ( newCapacity > currentCapacity ){
- // Make sure we at least double the current capacity
- if ( newCapacity > 2*currentCapacity )
- currentCapacity = newCapacity;
- else
- currentCapacity *= 2;
- // request more space in the heap
- T* newData = new T[currentCapacity];
- //copy the data
- for ( int i=0 ; i < numItems ; i++ )
- newData[i] = theData[i]; // same as *(newData + i) = *(theData + i)
- // free memory from old location. The pointer survives
- delete[] theData;
- // update memory address
- theData = newData;
- }
- return;
- }
- // Use static to avoid having to make unnecessary copies of INITIAL_SIZE
- static const int INITIAL_SIZE=10;
- int currentCapacity;
- int numItems;
- T* theData;
- };
- /*******************************************************
- FRIEND FUNCTIONS
- *******************************************************/
- // Dot Product
- template<typename T>
- T operator*(const MyVector<T>& a, const MyVector<T>& b) {
- assert(a.size() == b.size());
- T sum = 0;
- for (int i=0 ; i<b.size() ; i++)
- sum += a[i] * b[i];
- return sum;
- }
- /**************************************************
- NON MEMBER OPERATORS
- ************************************************* */
- /*
- Dot Product for String (TEMPLATE SPECIALIZATION)
- Operator* acting on two objects of type MyVector<string>
- Should return a string constructed by
- 1) concatenate the 1st entry of the left operand with the 1st entry of the right operand
- 2) add " + " to the string
- 3) repeat steps 1 and 2 with the next entries of both operands for as long as there are unprocessed entries.
- 4) before returning the string, the last " + " should be removed.
- E.g:
- cout << v * v; // displays: entry_1entry_1 + entry_2entry_2
- */
- template <>
- std::string operator* (const MyVector<std::string>& a, const MyVector<std::string>& b) {
- assert(a.size() == b.size());
- std::string ret;
- for( int i=0; i<b.size(); i++){
- ret += a[i] + b[i];
- if (i != b.size()-1) // dont add a + for the last string
- {
- ret += " + ";
- }
- }
- return ret;
- }
- std::string sqrt(std::string a){
- std::string b;
- b = "sqrt( " + a + " )";
- return b;
- }
- // Scalar Product Operator *
- template<typename T>
- MyVector<T> operator*( T a, MyVector<T> v){
- for ( int i=0 ; i < v.size() ; i++ ){
- v[i] = a * v[i];
- }
- return v; // v is a local copy of the vector
- }
- template<typename T>
- MyVector<T> operator*( MyVector<T> v , T a){
- return a * v;
- }
- /* STRING TEMPLATE SPECIALIZATION
- operator* acting on two objects of type string and MyVector<string>.
- Should return a MyVector<string> object where the i-th entry of this object is the concatenation ( string addition ) of s and the i-th entry of the MyVector<string> parameter. The concatenation should preserve the order in which the parameters were passed.
- E.g:
- cout << a * v; // displays: This is: entry_1 This is: entry_2
- cout << v * b; // displays: entry_1, this is. entry_2, this is.
- */
- template <>
- MyVector<std::string> operator* (std::string a, MyVector<std::string> v){
- MyVector<std::string> newVec;
- for (int i=0; i < v.size(); i++){
- newVec.push_back(a + v[i]);
- }
- return newVec;
- }
- template <>
- MyVector<std::string> operator* (MyVector<std::string> v, std::string a){
- MyVector<std::string> newVec;
- for (int i=0; i < v.size(); i++){
- newVec.push_back(v[i] + a );
- }
- return newVec;
- }
- // >
- template<typename T>
- bool operator>( const MyVector<T>& a, const MyVector<T>& b ) {
- return a.normal() > b.normal() ;
- }
- template <>
- bool operator> (const MyVector<std::string>& a, const MyVector<std::string>& b){
- for (int i=0; i < b.size(); i++){
- if (a[i] != b[i]){
- return a[i] > b[i];
- }
- }
- return false; //equal
- }
- // >=
- template<typename T>
- bool operator>=( const MyVector<T>&a, const MyVector<T>& b ) {
- return a.normal() >= b.normal();
- }
- template <>
- bool operator>=( const MyVector<std::string>& a, const MyVector<std::string>& b){
- for (int i=0; i < b.size(); i++){
- if (a[i] >= b[i]){
- return true;
- }
- }
- return false; //equal
- }
- // <
- template<typename T>
- bool operator<( const MyVector<T>&a, const MyVector<T>& b ){
- return a.normal() < b.normal();
- }
- template <>
- bool operator<( const MyVector<std::string>& a, const MyVector<std::string>& b){
- for (int i=0; i < b.size(); i++){
- if (a[i] < b[i]){
- return true;
- }
- }
- return false; //equal
- }
- // <=
- template<typename T>
- bool operator<=( const MyVector<T>&a, const MyVector<T>& b ){
- return a.normal() <= b.normal();
- }
- template <>
- bool operator<=( const MyVector<std::string>& a, const MyVector<std::string>& b){
- for (int i=0; i < b.size(); i++){
- if (a[i] <= b[i]){
- return true;
- }
- }
- return false; //equal
- }
- // ==
- template<typename T>
- bool operator==( const MyVector<T>&a, const MyVector<T>& b ) {
- // False if different sizes
- if( a.size() != b.size() )
- return false;
- else{
- // False if at least one entry does not match
- for (int i=0 ; i<a.size() ; i++){
- if ( a[i] != b[i] )
- return false;
- }
- // True if all entries match
- return true;
- }
- }
- template <>
- bool operator== (const MyVector<std::string>& a, const MyVector<std::string>& b){
- for (int i=0; i < b.size(); i++){
- if (a[i] != b[i]){
- return false;
- }
- }
- return true; //equal
- }
- // !=
- template<typename T>
- bool operator!=( const MyVector<T>& a, const MyVector<T>& b ) {
- return !( a == b );
- }
- template <>
- bool operator!=( const MyVector<std::string>& a, const MyVector<std::string>& b){
- for (int i=0; i < b.size(); i++){
- if (a[i] != b[i]){
- return true;
- }
- }
- return false; //equal
- }
- template<typename T>
- std::ostream& operator<<( std::ostream& out, const MyVector<T>& v ){
- for ( int i=0 ; i < v.size() ; i++ )
- out << std::setw(8) << v[i] ;
- out << std::endl;
- return out;
- }
- template <>
- std::ostream& operator<<( std::ostream& out, const MyVector<std::string>& v )
- {
- for (int i=0; i < v.size(); i++)
- out << v[i] << " ";
- out << std::endl;
- return out;
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement