//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// Cost.h -- 
//
// Author           : Richard C. Bilson
// Created On       : Sun May 17 09:39:50 2015
// Last Modified By : Rob Schluntz
// Last Modified On : Wed Jul 22 16:43:10 2015
// Update Count     : 4
//

#ifndef COST_H
#define COST_H

#include <iostream>

namespace ResolvExpr {
	class Cost {
	  public:
		Cost();
		Cost( int unsafe, int poly, int safe );
  
		void incUnsafe( int inc = 1 );
		void incPoly( int inc = 1 );
		void incSafe( int inc = 1 );
  
		Cost operator+( const Cost &other ) const;
		Cost operator-( const Cost &other ) const;
		Cost &operator+=( const Cost &other );
		bool operator<( const Cost &other ) const;
		bool operator==( const Cost &other ) const;
		bool operator!=( const Cost &other ) const;
		friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
  
		static const Cost zero;
		static const Cost infinity;
	  private:
		int compare( const Cost &other ) const;

		int unsafe;
		int poly;
		int safe;
	};

	inline Cost::Cost() : unsafe( 0 ), poly( 0 ), safe( 0 ) {}

	inline Cost::Cost( int unsafe, int poly, int safe ) : unsafe( unsafe ), poly( poly ), safe( safe ) {}

	inline void Cost::incUnsafe( int inc ) {
		unsafe += inc;
	}

	inline void Cost::incPoly( int inc ) {
		poly += inc;
	}

	inline void Cost::incSafe( int inc ) {
		safe += inc;
	}

	inline Cost Cost::operator+( const Cost &other ) const {
		return Cost( unsafe + other.unsafe, poly + other.poly, safe + other.safe );
	}

	inline Cost Cost::operator-( const Cost &other ) const {
		return Cost( unsafe - other.unsafe, poly - other.poly, safe - other.safe );
	}

	inline Cost &Cost::operator+=( const Cost &other ) {
		unsafe += other.unsafe;
		poly += other.poly;
		safe += other.safe;
		return *this;
	}

	inline bool Cost::operator<( const Cost &other ) const {
	    if ( *this == infinity ) return false;
	    if ( other == infinity ) return true;
	    if ( unsafe > other.unsafe ) {
			return false;
	    } else if ( unsafe < other.unsafe ) {
			return true;
	    } else if ( poly > other.poly ) {
			return false;
	    } else if ( poly < other.poly ) {
			return true;
	    } else if ( safe > other.safe ) {
			return false;
	    } else if ( safe < other.safe ) {
			return true;
	    } else {
			return false;
	    } // if
	}

	inline bool Cost::operator==( const Cost &other ) const {
		return unsafe == other.unsafe
			&& poly == other.poly
			&& safe == other.safe;
	}

	inline bool Cost::operator!=( const Cost &other ) const {
		return !( *this == other );
	}

	inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
		os << "( " << cost.unsafe << ", " << cost.poly << ", " << cost.safe << " )";
		return os;
	}
} // namespace ResolvExpr

#endif // COST_H

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
