Listing 2 - Temperature.h

   
#ifndef UTIL_TEMPERATURE_H
#define UTIL_TEMPERATURE_H
    
#include <platform.h>
    
#include <iosfwd>
#include <locale>
    
namespace Util {
    
class Temperature {
    // data
    float        _val;
public:
    // LWC
    Temperature() {}
    
    // access
    float        inK() const        { return _val; }
    float        inC() const        { return inK() - 273.15; }
    float        inF() const        { return (inC() * 9 / 5) + 32; }
    
    // creation
    static Temperature    inK(float val);
    static Temperature    inC(float val);
    static Temperature    inF(float val);
    
    // Facet
    typedef std::ostream& (*Formater)(std::ostream&, Temperature, long);
    class temp_put : public std::locale::facet { 
        typedef std::locale::facet inherited;
        Formater    _fmtr;
    public:
        static std::locale::id id;
        temp_put(Formater fmtr) 
            : inherited(1), _fmtr(fmtr)
            {}
        std::ostream& put(std::ostream& os, Temperature t, long flags) const
            { return _fmtr(os, t, flags); }
    private:
        temp_put(const temp_put&);
        temp_put& operator=(const temp_put&);
    };
    
    static temp_put temp_put_asK;
    static temp_put temp_put_asC;
    static temp_put temp_put_asF;
    
protected:
    Temperature(float val) : _val(val) {}
    
    
    // iostream operations
public:
    // iword/pword index
    static const int        strm_index;
    
    // manipulators
    static std::ostream&    asK(std::ostream&);
    static std::ostream&    asC(std::ostream&);
    static std::ostream&    asF(std::ostream&);
    static std::ostream&    showscale(std::ostream&);
    static std::ostream&    noscale(std::ostream&);
    
private:
    // formaters
    static std::ostream&    _putK(std::ostream&, Temperature obj, long flags);
    static std::ostream&    _putC(std::ostream&, Temperature obj, long flags);
    static std::ostream&    _putF(std::ostream&, Temperature obj, long flags);
};
    
// comparison operators
bool operator==(Temperature lhs, Temperature rhs);
    
inline bool 
operator!=(Temperature lhs, Temperature rhs)
{ return !(lhs == rhs); }
    
inline bool 
operator< (Temperature lhs, Temperature rhs)
{ return lhs.inK() < rhs.inK(); }
    
inline bool 
operator<=(Temperature lhs, Temperature rhs)
{ return !(rhs < lhs); }
    
inline bool 
operator> (Temperature lhs, Temperature rhs)
{ return lhs < rhs; }
    
inline bool 
operator>=(Temperature lhs, Temperature rhs)
{ return !(rhs < lhs); }

// I/O operators
std::ostream& operator<<(std::ostream&, Temperature obj);
std::istream& operator>>(std::istream&, Temperature& obj);
    
// inline functions
inline Temperature
Temperature::inK(float val)
{ return Temperature(val); }
    
inline Temperature
Temperature::inC(float val)
{ return Temperature(val + 273.15); }
    
inline Temperature
Temperature::inF(float val)
{ return Temperature( ((val - 32) * 5 / 9) + 273.15); }
    
} //> namespace
    
#endif