00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef MORE_MATHBITS_H
00033 #define MORE_MATHBITS_H
00034
00035 #include <more/meta.h>
00036
00037 namespace more {
00038 namespace math {
00039
00040
00041
00042 template<typename T>
00043 struct undefined_type {};
00044
00045 template<typename T> struct scalar_type_
00046 { typedef typename T::scalar_type eval; };
00047 template<typename T> struct scalar_type_<const T>
00048 { typedef const typename scalar_type_<T>::eval eval; };
00049 template<> struct scalar_type_<float> { typedef float eval; };
00050 template<> struct scalar_type_<double> { typedef double eval; };
00051 template<> struct scalar_type_<long double> { typedef long double eval; };
00052 template<> struct scalar_type_<int> { typedef int eval; };
00053
00054 template<typename T> struct norm_type_
00055 { typedef typename scalar_type_<T>::eval eval; };
00056 template<typename T> struct norm_type_<const T>
00057 { typedef const typename norm_type_<T>::eval eval; };
00058
00059 template<typename T>
00060 struct element_type_ { typedef typename T::element_type eval; };
00061
00062 template<typename T>
00063 struct position_type_ { typedef typename T::position_type eval; };
00064
00065 template<typename T>
00066 struct outer_product_type_ {
00067 typedef typename T::outer_product_type eval;
00068 };
00069 template<typename T> struct outer_product_type_<const T>
00070 { typedef const typename outer_product_type_<T>::eval eval; };
00071 template<> struct outer_product_type_<float> { typedef float eval; };
00072 template<> struct outer_product_type_<double> { typedef double eval; };
00073 template<> struct outer_product_type_<long double>
00074 { typedef long double eval; };
00075 template<> struct outer_product_type_<int> { typedef int eval; };
00076
00077 template<typename T, typename U> struct balanced_type_
00078 { typedef typename bigger_type_<T, U>::eval eval; };
00079
00080 template<typename T, typename U> struct times_type_
00081 { typedef typename balanced_type_<T, U>::eval eval; };
00082
00083 template<typename T, typename U> struct divides_type_
00084 { typedef typename balanced_type_<T, U>::eval eval; };
00085
00086 template<typename T, typename U> struct plus_type_
00087 { typedef typename balanced_type_<T, U>::eval eval; };
00088
00089 template<typename T, typename U> struct minus_type_
00090 { typedef typename balanced_type_<T, U>::eval eval; };
00091
00092
00093 template<typename T> struct size_
00094 { static int const eval = T::CTC_size; };
00095
00096
00097
00098
00099 struct zero_tag {
00100 operator char() const { return 0; }
00101 operator short() const { return 0; }
00102 operator int() const { return 0; }
00103 operator long() const { return 0L; }
00104 operator unsigned long() const { return 0L; }
00105 operator float() const { return 0.0F; }
00106 operator double() const { return 0.0; }
00107 operator long double() const { return 0.0L; }
00108
00109
00110
00111
00112
00113
00114
00115 };
00116 extern zero_tag zero;
00117
00118 struct one_tag {
00119 operator char() const { return 1; }
00120 operator short() const { return 1; }
00121 operator int() const { return 1; }
00122 operator long() const { return 1L; }
00123 operator unsigned long() const { return 1L; }
00124 operator float() const { return 1.0F; }
00125 operator double() const { return 1.0; }
00126 operator long double() const { return 1.0L; }
00127
00128
00129
00130
00131
00132
00133
00134 };
00135 extern one_tag one;
00136
00137 struct minus_one_tag {
00138 operator char() const { return 1; }
00139 operator short() const { return 1; }
00140 operator int() const { return 1; }
00141 operator long() const { return 1L; }
00142 operator unsigned long() const { return 1L; }
00143 operator float() const { return 1.0F; }
00144 operator double() const { return 1.0; }
00145 operator long double() const { return 1.0L; }
00146
00147
00148
00149
00150
00151
00152 };
00153
00154 inline one_tag operator+(one_tag) { return one_tag(); }
00155 inline minus_one_tag operator+(minus_one_tag) { return minus_one_tag(); }
00156 inline minus_one_tag operator-(one_tag) { return minus_one_tag(); }
00157 inline one_tag operator-(minus_one_tag) { return one_tag(); }
00158
00159 template<typename T>
00160 inline zero_tag operator*(zero_tag, T) { return zero; }
00161 template<typename T>
00162 inline zero_tag operator*(T, zero_tag) { return zero; }
00163 template<typename T>
00164 inline zero_tag operator/(zero_tag, T) { return zero; }
00165 template<typename T>
00166 inline T operator+(zero_tag, const T& x) { return x; }
00167 template<typename T>
00168 inline T operator+(const T& x, zero_tag) { return x; }
00169 template<typename T>
00170 inline T operator-(zero_tag, const T& x) { return -x; }
00171 template<typename T>
00172 inline T operator-(const T& x, zero_tag) { return x; }
00173 template<typename T>
00174 inline T operator*(one_tag, const T& x) { return x; }
00175 template<typename T>
00176 inline T operator*(const T& x, one_tag) { return x; }
00177 template<typename T>
00178 inline T operator/(const T&x, one_tag) { return x; }
00179 template<typename T>
00180 inline T operator*(minus_one_tag, const T& x) { return -x; }
00181 template<typename T>
00182 inline T operator*(const T& x, minus_one_tag) { return -x; }
00183 template<typename T>
00184 inline T operator/(const T&x, minus_one_tag) { return -x; }
00185
00186 }
00187 using namespace math;
00188 }
00189 #endif