X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=ETL%2FETL%2F_fixed.h;fp=ETL%2FETL%2F_fixed.h;h=541f40c79ec9fe21e4d17b0a2bdaf4009518095f;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=0000000000000000000000000000000000000000;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/ETL/ETL/_fixed.h b/ETL/ETL/_fixed.h new file mode 100644 index 0000000..541f40c --- /dev/null +++ b/ETL/ETL/_fixed.h @@ -0,0 +1,643 @@ +/*! ======================================================================== +** Extended Template and Library +** Fixed-Point Math Class Implementation +** $Id$ +** +** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** Copyright (c) 2007 Chris Moore +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** === N O T E S =========================================================== +** +** This is an internal header file, included by other ETL headers. +** You should not attempt to use it directly. +** +** ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __ETL__FIXED_H +#define __ETL__FIXED_H + +/* === H E A D E R S ======================================================= */ + +#include + +/* === M A C R O S ========================================================= */ + +// the "+0.5" code was commented out - maybe to make thing run faster? +// it can be re-enabled by uncommenting this next line: +// #define ROUND_TO_NEAREST_INTEGER + +#ifndef ETL_FIXED_TYPE +# define ETL_FIXED_TYPE int +#endif + +#ifndef ETL_FIXED_BITS +#define ETL_FIXED_BITS 12 +#endif + +#ifndef ETL_FIXED_EPSILON +#define ETL_FIXED_EPSILON _EPSILON() +#endif + +#ifdef __GNUC___ +#define ETL_ATTRIB_CONST __attribute__ ((const)) +#define ETL_ATTRIB_PURE __attribute__ ((pure)) +#define ETL_ATTRIB_INLINE __attribute__ ((always_inline)) +#else +#define ETL_ATTRIB_CONST +#define ETL_ATTRIB_PURE +#define ETL_ATTRIB_INLINE +#endif + +/* === C L A S S E S & S T R U C T S ======================================= */ + +_ETL_BEGIN_NAMESPACE + +// Forward declarations +template class fixed_base; +//template<> class fixed_base; + +_ETL_END_NAMESPACE + +_STD_BEGIN_NAMESPACE +template _ETL::fixed_base abs(const _ETL::fixed_base&); +template _ETL::fixed_base cos(const _ETL::fixed_base&); +template _ETL::fixed_base cosh(const _ETL::fixed_base&); +template _ETL::fixed_base exp(const _ETL::fixed_base&); +template _ETL::fixed_base log(const _ETL::fixed_base&); +template _ETL::fixed_base log10(const _ETL::fixed_base&); +template _ETL::fixed_base pow(const _ETL::fixed_base&, int); +template _ETL::fixed_base pow(const _ETL::fixed_base&, const T&); +template _ETL::fixed_base pow(const _ETL::fixed_base&, + const _ETL::fixed_base&); +template _ETL::fixed_base pow(const _ETL::fixed_base&, const _ETL::fixed_base&); +template _ETL::fixed_base sin(const _ETL::fixed_base&); +template _ETL::fixed_base sinh(const _ETL::fixed_base&); +template _ETL::fixed_base sqrt(const _ETL::fixed_base&); +template _ETL::fixed_base tan(const _ETL::fixed_base&); +template _ETL::fixed_base tanh(const _ETL::fixed_base&); +_STD_END_NAMESPACE +_ETL_BEGIN_NAMESPACE + +/*! ======================================================================== +** \class fixed_base +** \brief Fixed-point template base class +** +** A more detailed description needs to be written. +*/ +template +class fixed_base +{ +public: + typedef T value_type; +private: + T _data; + + typedef fixed_base _fixed; + typedef fixed_base self_type; + + inline static bool _TYPE_SMALLER_THAN_INT() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE; + inline static bool _USING_ALL_BITS() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE; + inline static value_type _ONE() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE; + inline static value_type _F_MASK() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE; + inline static float _EPSILON() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE; + + class raw { }; +public: + fixed_base()ETL_ATTRIB_INLINE; + fixed_base(const float &f)ETL_ATTRIB_INLINE; + fixed_base(const double &f)ETL_ATTRIB_INLINE; + fixed_base(const long double &f)ETL_ATTRIB_INLINE; + fixed_base(const int &i)ETL_ATTRIB_INLINE; + fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE; //!< Fraction constructor + fixed_base(const _fixed &x)ETL_ATTRIB_INLINE; + fixed_base(value_type x,raw)ETL_ATTRIB_INLINE; + + T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE; + const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE; + + const _fixed& operator+=(const _fixed &rhs) ETL_ATTRIB_INLINE; + const _fixed& operator-=(const _fixed &rhs) ETL_ATTRIB_INLINE; + template const _fixed& operator*=(const U &rhs) ETL_ATTRIB_INLINE; + template const _fixed& operator/=(const U &rhs) ETL_ATTRIB_INLINE; + const _fixed& operator*=(const _fixed &rhs) ETL_ATTRIB_INLINE; + const _fixed& operator/=(const _fixed &rhs) ETL_ATTRIB_INLINE; + const _fixed& operator*=(const int &rhs) ETL_ATTRIB_INLINE; + const _fixed& operator/=(const int &rhs) ETL_ATTRIB_INLINE; + + + template _fixed operator+(const U &rhs)const ETL_ATTRIB_INLINE; + template _fixed operator-(const U &rhs)const ETL_ATTRIB_INLINE; + template _fixed operator*(const U &rhs)const ETL_ATTRIB_INLINE; + template _fixed operator/(const U &rhs)const ETL_ATTRIB_INLINE; + _fixed operator+(const _fixed &rhs)const ETL_ATTRIB_INLINE; + _fixed operator-(const _fixed &rhs)const ETL_ATTRIB_INLINE; + _fixed operator*(const _fixed &rhs)const ETL_ATTRIB_INLINE; + _fixed operator/(const _fixed &rhs)const ETL_ATTRIB_INLINE; + _fixed operator*(const int &rhs)const ETL_ATTRIB_INLINE; + _fixed operator/(const int &rhs)const ETL_ATTRIB_INLINE; + _fixed operator*(const float &rhs)const ETL_ATTRIB_INLINE; + _fixed operator*(const double &rhs)const ETL_ATTRIB_INLINE; + + // Negation Operator + _fixed operator-()const ETL_ATTRIB_INLINE; + + // Casting Operators + inline operator float()const ETL_ATTRIB_INLINE; + inline operator double()const ETL_ATTRIB_INLINE; + inline operator long double()const ETL_ATTRIB_INLINE; + inline operator int()const ETL_ATTRIB_INLINE; + inline operator bool()const ETL_ATTRIB_INLINE; + + _fixed floor()const; + _fixed ceil()const; + _fixed round()const; + + bool operator==(const _fixed &rhs)const { return data()==rhs.data(); } + bool operator!=(const _fixed &rhs)const { return data()!=rhs.data(); } + bool operator<(const _fixed &rhs)const { return data()(const _fixed &rhs)const { return data()>rhs.data(); } + bool operator<=(const _fixed &rhs)const { return data()<=rhs.data(); } + bool operator>=(const _fixed &rhs)const { return data()>=rhs.data(); } +}; + + +template +fixed_base::fixed_base() +{} + +template +fixed_base::fixed_base(const _fixed &x):_data(x._data) +{} + +template +fixed_base::fixed_base(const float &f):_data(static_cast(f*_ONE() +#ifdef ROUND_TO_NEAREST_INTEGER + +0.5f +#endif + )) {} + +template +fixed_base::fixed_base(const double &f):_data(static_cast(f*_ONE() +#ifdef ROUND_TO_NEAREST_INTEGER + +0.5 +#endif + )) {} + +template +fixed_base::fixed_base(const long double &f):_data(static_cast(f*_ONE() +#ifdef ROUND_TO_NEAREST_INTEGER + +0.5 +#endif + )) {} + +template +fixed_base::fixed_base(const int &i):_data(i< +fixed_base::fixed_base(value_type x,raw):_data(x) { } + +template +fixed_base::fixed_base(const int &n,const int &d):_data((n< inline bool +fixed_base::_TYPE_SMALLER_THAN_INT() +{ + return sizeof(T) inline bool +fixed_base::_USING_ALL_BITS() +{ + return sizeof(T)*8==FIXED_BITS; +} + +template inline T +fixed_base::_ONE() +{ + return static_cast((_USING_ALL_BITS()?~T(0):1< inline T +fixed_base::_F_MASK() +{ + return static_cast(_USING_ALL_BITS()?~T(0):_ONE()-1); +} + +template inline float +fixed_base::_EPSILON() +{ + return 1.0f/((float)_ONE()*2); +} + + +template T & +fixed_base::data() +{ + return _data; +} + +template const T & +fixed_base::data()const +{ + return _data; +} + +//! fixed+=fixed +template const fixed_base & +fixed_base::operator+=(const _fixed &rhs) +{ + _data+=rhs._data; + return *this; +} + +//! fixed-=fixed +template const fixed_base & +fixed_base::operator-=(const _fixed &rhs) +{ + _data-=rhs._data; + return *this; +} + +//! fixed*=fixed +template const fixed_base & +fixed_base::operator*=(const _fixed &rhs) +{ + if(_TYPE_SMALLER_THAN_INT()) + _data=static_cast((int)_data*(int)rhs._data>>FIXED_BITS); + else + { + _data*=rhs._data; + _data>>=FIXED_BITS; + } + + return *this; +} + +//! fixed/=fixed +template const fixed_base & +fixed_base::operator/=(const _fixed &rhs) +{ + if(_TYPE_SMALLER_THAN_INT()) + _data=static_cast((int)_data/(int)rhs._data< template const fixed_base & +fixed_base::operator*=(const U &rhs) +{ + return operator*=(fixed_base(rhs)); +} + +template template const fixed_base & +fixed_base::operator/=(const U &rhs) +{ + return operator/=(fixed_base(rhs)); +} + +//! fixed*=int +template const fixed_base & +fixed_base::operator*=(const int &rhs) +{ + _data*=rhs; return *this; +} + +//! fixed/=int +template const fixed_base & +fixed_base::operator/=(const int &rhs) +{ + _data/=rhs; return *this; +} + + + + + + + +//! fixed + fixed +template fixed_base +fixed_base::operator+(const _fixed &rhs)const +{ + _fixed ret; + ret._data=_data+rhs._data; + return ret; +} + +//! fixed - fixed +template fixed_base +fixed_base::operator-(const _fixed &rhs)const +{ + _fixed ret; + ret._data=_data-rhs._data; + return ret; +} + +//! fixed * fixed +template fixed_base +fixed_base::operator*(const _fixed &rhs)const +{ + _fixed ret; + ret._data=((_data*rhs._data)>>FIXED_BITS); + return ret; + //return reinterpret_cast<_fixed>((_data*rhs._data)>>FIXED_BITS); +} + +//! fixed / fixed +template fixed_base +fixed_base::operator/(const _fixed &rhs)const +{ + _fixed ret; + ret._data=((_data/rhs._data)<((_data/rhs._data)< template fixed_base +fixed_base::operator+(const U &rhs) const +{ + return operator+(fixed_base(rhs)); +} + +//! fixed - ... +template template fixed_base +fixed_base::operator-(const U &rhs) const +{ + return operator-(fixed_base(rhs)); +} + +//! fixed * ... +template template fixed_base +fixed_base::operator*(const U &rhs) const +{ + return operator*(fixed_base(rhs)); +} + +//! fixed / ... +template template fixed_base +fixed_base::operator/(const U &rhs) const +{ + return operator/(fixed_base(rhs)); +} + +//! fixed * int +template fixed_base +fixed_base::operator*(const int &rhs)const +{ + _fixed ret; + ret._data=_data*rhs; + return ret; + //return reinterpret_cast<_fixed>(_data*rhs); +} + +//! fixed * float +template fixed_base +fixed_base::operator*(const float &rhs)const +{ + return (*this)*_fixed(rhs); +} + +//! fixed * double +template fixed_base +fixed_base::operator*(const double &rhs)const +{ + return (*this)*_fixed(rhs); +} + + +//! fixed / int +template fixed_base +fixed_base::operator/(const int &rhs)const +{ + _fixed ret; + ret._data=_data/rhs; + return ret; + //return reinterpret_cast<_fixed>(_data/rhs); +} + +//! float * fixed +template fixed_base +operator*(const float& lhs, const fixed_base &rhs) +{ + return rhs*lhs; +} + +//! double * fixed +template fixed_base +operator*(const double& lhs, const fixed_base &rhs) +{ + return rhs*lhs; +} + + + + + + +// Negation Operator +template fixed_base +fixed_base::operator-()const +{ + _fixed ret; ret._data=-_data; return ret; +} + +// Casting Operators +template +fixed_base::operator float()const +{ + return static_cast(_data)/static_cast(_ONE()); +} + +template +fixed_base::operator double()const +{ + return static_cast(_data)/static_cast(_ONE()); +} + +template +fixed_base::operator long double()const +{ + return static_cast(_data)/static_cast(_ONE()); +} + +template +fixed_base::operator int()const +{ + return static_cast(_data>>FIXED_BITS); +} + +template +fixed_base::operator bool()const +{ + return static_cast(_data); +} + + +template fixed_base +fixed_base::floor()const +{ + _fixed ret(*this); + ret._data&=~_F_MASK(); + return ret; +} + +template fixed_base +fixed_base::ceil()const +{ + _fixed ret(*this); + if(ret._data&_F_MASK()) + ret._data=(ret._data&~_F_MASK()) + _ONE(); + else + ret._data&=~_F_MASK(); + return ret; +} + +template fixed_base +fixed_base::round()const +{ + _fixed ret(*this); + ret._data+=_ONE()>>1; + ret._data&=~_F_MASK(); + return ret; +} + + + + + + + + + + + + + + + + + + + + + + + + + + +typedef fixed_base fixed; + +_ETL_END_NAMESPACE + +_STD_BEGIN_NAMESPACE + +template +inline _ETL::fixed_base +ceil(const _ETL::fixed_base &rhs) +{ return rhs.ceil(); } + +template +_ETL::fixed_base +floor(const _ETL::fixed_base &rhs) +{ return rhs.floor(); } + +template +_ETL::fixed_base +round(const _ETL::fixed_base &rhs) +{ return rhs.round(); } + +template +_ETL::fixed_base +abs(const _ETL::fixed_base &rhs) +{ return rhs<_ETL::fixed_base(0)?-rhs:rhs; } + +_STD_END_NAMESPACE + +/* +template bool +operator==(const _ETL::fixed_base& lhs, const _ETL::fixed_base& rhs) +{ return lhs.data()==rhs.data(); } + +template bool +operator!=(const _ETL::fixed_base& lhs, const _ETL::fixed_base& rhs) +{ return lhs.data()!=rhs.data(); } + +template bool +operator>(const _ETL::fixed_base& lhs, const _ETL::fixed_base& rhs) +{ return lhs.data()>rhs.data(); } + +template bool +operator<(const _ETL::fixed_base& lhs, const _ETL::fixed_base& rhs) +{ return lhs.data() bool +operator>=(const _ETL::fixed_base& lhs, const _ETL::fixed_base& rhs) +{ return lhs.data()>=rhs.data(); } + +template bool +operator<=(const _ETL::fixed_base& lhs, const _ETL::fixed_base& rhs) +{ return lhs.data()<=rhs.data(); } +*/ + + +#if defined(__GNUC__) && __GNUC__ == 3 +template U +operator*(const U &a,const _ETL::fixed_base &b) + { return a*static_cast(b); } + +template U +operator/(const U &a,const _ETL::fixed_base &b) + { return a/static_cast(b); } + +template U +operator+(const U &a,const _ETL::fixed_base &b) + { return a+static_cast(b); } + +template U +operator-(const U &a,const _ETL::fixed_base &b) + { return a-static_cast(b); } + + +/* +inline const float & +operator*=(float &a,const _ETL::fixed &b) + { a*=(float)b; return a; } + +inline const float & +operator/=(float &a,const _ETL::fixed &b) + { a/=(float)b; return a; } + +inline const float & +operator-=(float &a,const _ETL::fixed &b) + { a-=(float)b; return a; } + +inline const float & +operator+=(float &a,const _ETL::fixed &b) + { a+=(float)b; return a; } +*/ +#endif + +/* === E N D =============================================================== */ + +#endif