Listing 4 — Temperature.h (alt)

#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.15F; }
    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 punct : public std::locale::facet {
    public:
        typedef std::locale::facet inherited;
        typedef float (Temperature::*ValueFunc)()const;
    private:
        ValueFunc        _valueFunc;
        char            _scale;
    public:
        static std::locale::id id;
        punct(ValueFunc func, char scale) 
        : inherited(1), _valueFunc(func), _scale(scale) {}

        // access
        float    value(Temperature t) const    { return (t.*_valueFunc)(); }
        char     scale() const        { return _scale; }
    };

    // static facets
    static punct    punct_asK;
    static punct    punct_asC;
    static punct    punct_asF;

protected:
    Temperature(float val) : _val(val) {}

public:
    // iostream operations
    static const int    strm_index;    // iword/pword 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&);
};

// 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.15F); }

inline Temperature
Temperature::inF(float val)
{ return Temperature( ((val - 32) * 5 / 9) + 273.15F); }

} //> namespace

#endif