// // 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 : Aaron B. Moss // Last Modified On : Mon Jun 11 16:04:00 2018 // Update Count : 6 // #pragma once #include namespace ResolvExpr { class Cost { private: Cost( int unsafeCost, int polyCost, int varCost, int specCost, int safeCost, int referenceCost ); public: Cost & incUnsafe( int inc = 1 ); Cost & incPoly( int inc = 1 ); Cost & incVar( int inc = 1 ); Cost & decSpec( int dec = 1 ); Cost & incSafe( int inc = 1 ); Cost & incReference( int inc = 1 ); int get_unsafeCost() const { return unsafeCost; } int get_polyCost() const { return polyCost; } int get_varCost() const { return varCost; } int get_specCost() const { return specCost; } int get_safeCost() const { return safeCost; } int get_referenceCost() const { return referenceCost; } 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; static const Cost unsafe; static const Cost poly; static const Cost var; static const Cost spec; static const Cost safe; static const Cost reference; private: int unsafeCost; ///< Unsafe (narrowing) conversions int polyCost; ///< Count of parameters and return values bound to some poly type int varCost; ///< Count of polymorphic type variables int specCost; ///< Polymorphic type specializations (type assertions), negative cost int safeCost; ///< Safe (widening) conversions int referenceCost; ///< reference conversions }; inline Cost::Cost( int unsafeCost, int polyCost, int varCost, int specCost, int safeCost, int referenceCost ) : unsafeCost( unsafeCost ), polyCost( polyCost ), varCost( varCost ), specCost( specCost ), safeCost( safeCost ), referenceCost( referenceCost ) {} inline Cost & Cost::incUnsafe( int inc ) { if ( *this == infinity ) return *this; unsafeCost += inc; return *this; } inline Cost & Cost::incPoly( int inc ) { if ( *this == infinity ) return *this; polyCost += inc; return *this; } inline Cost & Cost::incVar( int inc ) { if ( *this == infinity ) return *this; varCost += inc; return *this; } inline Cost& Cost::decSpec( int dec ) { if ( *this == infinity ) return *this; specCost -= dec; return *this; } inline Cost & Cost::incSafe( int inc ) { if ( *this == infinity ) return *this; safeCost += inc; return *this; } inline Cost & Cost::incReference( int inc ) { if ( *this == infinity ) return *this; referenceCost += inc; return *this; } inline Cost Cost::operator+( const Cost &other ) const { if ( *this == infinity || other == infinity ) return infinity; return Cost( unsafeCost + other.unsafeCost, polyCost + other.polyCost, varCost + other.varCost, specCost + other.specCost, safeCost + other.safeCost, referenceCost + other.referenceCost ); } inline Cost Cost::operator-( const Cost &other ) const { if ( *this == infinity || other == infinity ) return infinity; return Cost( unsafeCost - other.unsafeCost, polyCost - other.polyCost, varCost + other.varCost, specCost + other.specCost, safeCost - other.safeCost, referenceCost - other.referenceCost ); } inline Cost &Cost::operator+=( const Cost &other ) { if ( *this == infinity ) return *this; if ( other == infinity ) { *this = infinity; return *this; } unsafeCost += other.unsafeCost; polyCost += other.polyCost; varCost += other.varCost; specCost += other.specCost; safeCost += other.safeCost; referenceCost += other.referenceCost; return *this; } inline bool Cost::operator<( const Cost &other ) const { if ( *this == infinity ) return false; if ( other == infinity ) return true; if ( unsafeCost > other.unsafeCost ) { return false; } else if ( unsafeCost < other.unsafeCost ) { return true; } else if ( polyCost > other.polyCost ) { return false; } else if ( polyCost < other.polyCost ) { return true; } else if ( varCost > other.varCost ) { return false; } else if ( varCost < other.varCost ) { return true; } else if ( specCost > other.specCost ) { return false; } else if ( specCost < other.specCost ) { return true; } else if ( safeCost > other.safeCost ) { return false; } else if ( safeCost < other.safeCost ) { return true; } else if ( referenceCost > other.referenceCost ) { return false; } else if ( referenceCost < other.referenceCost ) { return true; } else { return false; } // if } inline bool Cost::operator==( const Cost &other ) const { return unsafeCost == other.unsafeCost && polyCost == other.polyCost && varCost == other.varCost && specCost == other.specCost && safeCost == other.safeCost && referenceCost == other.referenceCost; } inline bool Cost::operator!=( const Cost &other ) const { return !( *this == other ); } inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) { return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " << cost.varCost << ", " << cost.specCost << ", " << cost.safeCost << ", " << cost.referenceCost << " )"; } } // namespace ResolvExpr // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //