#ifndef INTERVALSAMPLET_HPP
#define INTERVALSAMPLET_HPP

#include <iostream>

template <class T> class intervalsample {
	public:
	T inf;
	T sup;

	intervalsample() {
	}

	intervalsample(const T& x) {
		inf = x;
		sup = x;
	}
	intervalsample(const T& x, const T& y) {
		inf = x;
		sup = y;
	}

	friend intervalsample operator+(const intervalsample& x, const intervalsample& y) {
		intervalsample r;

		r.inf = x.inf + y.inf;
		r.sup = x.sup + y.sup;

		return r;
	}

	friend intervalsample operator+(const intervalsample& x, const T& y) {
		intervalsample r;

		r.inf = x.inf + y;
		r.sup = x.sup + y;

		return r;
	}

	friend intervalsample operator+(const T& x, const intervalsample& y) {
		intervalsample r;

		r.inf = x + y.inf;
		r.sup = x + y.sup;

		return r;
	}

	friend intervalsample& operator+=(intervalsample& x, const intervalsample& y) {
		x = x + y;
		return x;
	}

	friend intervalsample& operator+=(intervalsample& x, const T& y) {
		x.inf += y;
		x.sup += y;
		return x;
	}

	friend intervalsample operator-(const intervalsample& x, const intervalsample& y) {
		intervalsample r;

		r.inf = x.inf - y.sup;
		r.sup = x.sup - y.inf;

		return r;
	}

	friend intervalsample operator-(const intervalsample& x, const T& y) {
		intervalsample r;

		r.inf = x.inf - y;
		r.sup = x.sup - y;

		return r;
	}

	friend intervalsample operator-(const T& x, const intervalsample& y) {
		intervalsample r;

		r.inf = x - y.sup;
		r.sup = x - y.inf;

		return r;
	}

	friend intervalsample& operator-=(intervalsample& x, const intervalsample& y) {
		x = x - y;
		return x;
	}

	friend intervalsample& operator-=(intervalsample& x, const T& y) {
		x.inf = x.inf - y;
		x.sup = x.sup - y;
		return x;
	}

	friend intervalsample operator-(const intervalsample& x) {
		intervalsample r;

		r.sup = - x.inf;
		r.inf = - x.sup;

		return r;
	}

	friend intervalsample operator*(const intervalsample& x, const intervalsample& y) {
		intervalsample r;
		T tmp;

		r.inf = r.sup = x.inf * y.inf;

		tmp = x.inf * y.sup;
		if (tmp < r.inf) r.inf = tmp; 
		if (tmp > r.sup) r.sup = tmp; 

		tmp = x.sup * y.inf;
		if (tmp < r.inf) r.inf = tmp; 
		if (tmp > r.sup) r.sup = tmp; 

		tmp = x.sup * y.sup;
		if (tmp < r.inf) r.inf = tmp; 
		if (tmp > r.sup) r.sup = tmp; 

		return r;
	}

	friend intervalsample operator*(const intervalsample& x, const T& y) {
		intervalsample r;
		T tmp;

		r.inf = r.sup = x.inf * y;

		tmp = x.sup * y;
		if (tmp < r.inf) r.inf = tmp; 
		if (tmp > r.sup) r.sup = tmp; 

		return r;
	}

	friend intervalsample operator*(const T& x, const intervalsample& y) {
		intervalsample r;
		T tmp;

		r.inf = r.sup = x * y.inf;

		tmp = x * y.sup;
		if (tmp < r.inf) r.inf = tmp; 
		if (tmp > r.sup) r.sup = tmp; 

		return r;
	}

	friend intervalsample& operator*=(intervalsample& x, const intervalsample& y) {
		x = x * y;
		return x;
	}

	friend intervalsample& operator*=(intervalsample& x, const T& y) {
		x = x * y;
		return x;
	}

	friend std::ostream& operator<<(std::ostream& s, const intervalsample& x) {
		s << '[' << x.inf << ',' << x.sup << "]";
		return s;
	}
};

#endif // INTERVALSAMPLET_HPP
