#include <iostream>
using namespace std;

template<typename T>
class Rectangle
{
private:
    T width;
    T height;
    
public:
    Rectangle()
    {
        width = 1;
        height = 1;
    }

    Rectangle(T w, T h)
    {
        width = w;
        height = h;
    }

    int getWidth() const
    {
        return width;
    }

    int getHeight() const
    {
        return height;
    }

    // binary - (as method): "this - rect2"
    Rectangle<T> operator-(const Rectangle<T>& rect2) const
    {
    	T width = this->getWidth() - rect2.getWidth();
    	T height = this->getHeight() - rect2.getHeight();

    	Rectangle<T> result = { width, height };
    	return result;
    }

    // unary - (as method): "-this" , see below for implementation as standalone function
    Rectangle<T> operator-() const
    {
    	T width = -this->width;
    	T height = -this->height;

    	Rectangle<T> result = { width, height };
    	return result;
    }
	
    Rectangle<T>& operator+=(const Rectangle<T>& rect2)
    {
        width = width + rect2.getWidth();
    	height = height + rect2.getHeight();

        return *this;
    }
};


template<typename T>
Rectangle<T> operator+(const Rectangle<T>& rect1, const Rectangle<T>& rect2)
{
    T width = rect1.getWidth() + rect2.getWidth();
    T height = rect1.getHeight() + rect2.getHeight();

    Rectangle<T> result = { width, height };
    return result;
}

/*
// unary - implemented as standalone function  
template<typename T>
Rectangle<T> operator-(const Rectangle<T>& rect)
{
    T width = -rect.getWidth();
    T height = -rect.getHeight();

    Rectangle<T> result = { width, height };
    return result;
}
*/


template<typename T>
void print(const Rectangle<T>& rect)
{
    cout << rect.getWidth() << ", " << rect.getHeight() << endl;
}


int main()
{
    Rectangle<int> r1 = { 10, 20 };
    Rectangle<int> r2 = { 50, 30 };

    Rectangle<int> r3 = r1 + r2;  // ~ operator+(rect1, rect2), ~ add(r1, r2)

    print(r3);

    Rectangle<double> r4 = { 15.73, 29.48 };
    Rectangle<double> r5 = -r4;   // the unary -
    
    print(r5);

    return 0;
}