/** * The physical length library. Made for nanometer scale. * @file length.h */ /* sorry it is not styles correctly, i'll work on it further */ #ifndef LENGTH_H_INCLUDED #define LENGTH_H_INCLUDED 1 typedef int DEF_LENGTH_VALUE; template class LENGTH; template class LENGTH_UNITS; template struct LENGTH_TRAITS { typedef LENGTH flat; }; template struct LENGTH_TRAITS { typedef T flat; }; template class LENGTH { friend class LENGTH_UNITS; friend class LENGTH_TRAITS; template friend class LENGTH; protected: T m_U; LENGTH(T units) : m_U(units) { } static T RawValue(const LENGTH &x) { return x.m_U; } static T RawValue(const T& x) { return x; } public: typedef LENGTH flat; typedef T value_type; enum { dimension = P }; LENGTH(const LENGTH &orig) : m_U(orig.m_U) { } LENGTH( void ) : m_U() { } static LENGTH zero (void) { return T(0); } LENGTH & operator = (const LENGTH & y) { this->m_U = y.m_U; return *this; } template operator LENGTH (void) { return this->m_U; } /*************************/ /* comparisons and tests */ /*************************/ bool operator ==(const LENGTH y) const { return m_U == y.m_U; } bool operator !=(const LENGTH y) const { return m_U != y.m_U; } bool operator <(const LENGTH y) const { return m_U < y.m_U; } bool operator >=(const LENGTH y) const { return m_U >= y.m_U; } bool operator >(const LENGTH y) const { return m_U > y.m_U; } bool operator <=(const LENGTH y) const { return m_U <= y.m_U; } bool operator !( void ) const { return !m_U; } /*************************/ /* basic arithmetic */ /*************************/ LENGTH operator - (void) const { return LENGTH(-this->m_U); } LENGTH operator - (const LENGTH y) const { return m_U - y.m_U; } LENGTH operator + (const LENGTH y) const { return m_U + y.m_U; } template typename LENGTH_TRAITS::flat operator * (const LENGTH &y) const { return m_U * y.m_U; } LENGTH operator * (const T &y) const { return m_U * y; } LENGTH friend operator * (const T &y, const LENGTH &x) { return x.m_U * y; } template typename LENGTH_TRAITS::flat operator / (const LENGTH &y) const { return m_U / y.m_U; } LENGTH operator / (const T &y) const { return m_U / y; } LENGTH friend operator / (const T &y, const LENGTH &x) { return y / x.m_U; } friend LENGTH sqrt(LENGTH y) { return sqrt(y.m_U); } friend LENGTH cbrt(LENGTH y) { return cbrt(y.m_U); } /*************************/ /* assignment arithmetic */ /*************************/ LENGTH& operator -= (const LENGTH y) { return m_U -= y.m_U; } LENGTH& operator += (const LENGTH y) { return m_U += y.m_U; } LENGTH& operator *= (const T y) { return m_U *= y; } LENGTH& operator /= (const T y) { return m_U /= y; } /*************************/ /* more arithmetic */ /*************************/ }; template class LENGTH_UNITS { protected: enum { METRE = 1000000000, /* The ONLY constant connecting length to the real world */ INCH = METRE / 10000 * 254 }; public: static LENGTH metre( void ) { return T(METRE); } static LENGTH decimetre( void ) { return T(METRE / 10); } static LENGTH centimetre( void ) { return T(METRE / 100); } static LENGTH millimetre( void ) { return T(METRE / 1000); } static LENGTH micrometre( void ) { return T(METRE / 1000000); } static LENGTH foot( void ) { /* do not think this will ever need */ return T(INCH * 12); } static LENGTH inch( void ) { return T(INCH); } static LENGTH mil( void ) { return T(INCH / 1000); } }; /* shortcut */ template class LENGTH_UNITS >: public LENGTH_UNITS { }; /* TODO: argument promotion (but is this need? explicit casts would be enough) */ #endif