00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef BOOST_UNITS_STATIC_RATIONAL_HPP
00011 #define BOOST_UNITS_STATIC_RATIONAL_HPP
00012
00013
00014 #include <boost/math/common_factor.hpp>
00015
00016
00017
00020
00021 namespace mcs {
00022
00023 namespace units {
00024
00025
00027 template<typename R> struct static_negate;
00028
00030 template<typename R1,typename R2> struct static_add;
00031
00033 template<typename R1,typename R2> struct static_subtract;
00034
00036 template<typename R1,typename R2> struct static_multiply;
00037
00039 template<typename R1,typename R2> struct static_divide;
00040
00042 template<typename R1,typename R2> struct static_power;
00043
00044
00045 typedef long integer_type;
00046
00048 template<integer_type Value>
00049 struct static_abs
00050 {
00051 BOOST_STATIC_CONSTANT(integer_type,value) = Value < 0 ? -Value : Value;
00052 };
00053
00055
00073 template<integer_type N,integer_type D = 1>
00074 class static_rational
00075 {
00076 private:
00077 static const integer_type nabs = static_abs<N>::value,
00078 dabs = static_abs<D>::value;
00079
00081
00082 static const integer_type den =
00083 static_cast<integer_type>(boost::math::static_gcd<nabs,dabs>::value);
00084
00085 public:
00086 static const integer_type Numerator = N/den,
00087 Denominator = D/den;
00088
00089 typedef static_rational<N,D> this_type;
00090
00092 typedef static_rational<Numerator,Denominator> type;
00093
00094 static integer_type numerator() { return Numerator; }
00095 static integer_type denominator() { return Denominator; }
00096
00097 static_rational() { }
00098
00099 };
00100
00101
00102 template<integer_type N> class static_rational<N,0>;
00103
00104
00105 #ifdef MCS_HAS_TYPEOF
00106 template<class T,integer_type N,integer_type D>
00107 typename divide_typeof_helper<T,T>::type
00108 value(const static_rational<N,D>& r)
00109 {
00110 return T(N)/T(D);
00111 }
00112 #else
00113 template<class T,integer_type N,integer_type D>
00114 T value(const static_rational<N,D>& r)
00115 {
00116
00117 return T(N)/T(D);
00118 }
00119 #endif
00120
00122 template<integer_type N,integer_type D>
00123 struct static_negate< static_rational<N,D> >
00124 {
00125 typedef typename static_rational<-N,D>::type type;
00126 };
00127
00129 template<integer_type N1,integer_type D1,
00130 integer_type N2,integer_type D2>
00131 struct static_add< static_rational<N1,D1>,static_rational<N2,D2> >
00132 {
00133 typedef typename static_rational<N1*D2+N2*D1,D1*D2>::type type;
00134 };
00135
00137 template<integer_type N1,integer_type D1,
00138 integer_type N2,integer_type D2>
00139 struct static_subtract< static_rational<N1,D1>,static_rational<N2,D2> >
00140 {
00141 typedef typename static_rational<N1*D2-N2*D1,D1*D2>::type type;
00142 };
00143
00145 template<integer_type N1,integer_type D1,
00146 integer_type N2,integer_type D2>
00147 struct static_multiply< static_rational<N1,D1>,static_rational<N2,D2> >
00148 {
00149 typedef typename static_rational<N1*N2,D1*D2>::type type;
00150 };
00151
00153 template<integer_type N1,integer_type D1,
00154 integer_type N2,integer_type D2>
00155 struct static_divide< static_rational<N1,D1>,static_rational<N2,D2> >
00156 {
00157 typedef typename static_rational<N1*D2,D1*N2>::type type;
00158 };
00159
00160
00161 }
00162
00163 }
00164
00165 #endif // BOOST_UNITS_STATIC_RATIONAL_HPP