Listing 1: Temperature.h

#ifndef UTIL_TEMPERATURE_H
#define UTIL_TEMPERATURE_H

#include <iosfwd>

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);

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&    show_scale(std::ostream&);
    static std::ostream&    no_scale(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
inline bool 
operator==(Temperature lhs, Temperature rhs)
{ return lhs.inK() == rhs.inK(); }

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