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 #ifndef NTG_UTILS_CAST_HH
00029 # define NTG_UTILS_CAST_HH
00030
00031 # include <ntg/config/system.hh>
00032 # include <ntg/core/macros.hh>
00033 # include <ntg/core/predecls.hh>
00034 # include <ntg/core/type_traits.hh>
00035 # include <ntg/real/real_value.hh>
00036
00037
00038
00039
00040
00041
00042
00043
00044 # define TO_NTG_CAST(Dest) \
00045 template<class T> \
00046 inline ntg_##Dest##_type(T) to_##Dest##_ntg(T val) \
00047 { \
00048 return static_cast<ntg_##Dest##_type(T)>(val); \
00049 }
00050
00051 namespace ntg {
00052
00053
00054
00055
00056
00057 template<class T>
00058 inline ntg_type(T) to_ntg(T val)
00059 {
00060 return static_cast<ntg_type(T)>(val);
00061 }
00062
00063 TO_NTG_CAST(signed)
00064
00065 namespace cast {
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 template<class Tdest, class Tsrc> inline
00077 const Tdest
00078 force(const Tsrc& val)
00079 {
00080 return ntg_unsafe_type(Tdest)(val);
00081 }
00082
00083
00084
00085
00086
00087
00088 template<class Tdest, class Tsrc> inline
00089 const Tdest
00090 bound(const Tsrc& val)
00091 {
00092 if (ntg_max_val(Tsrc) > ntg_max_val(Tdest))
00093 if (val > Tsrc(Tdest(ntg_max_val(Tdest))))
00094 return ntg_max_val(Tdest);
00095 if (ntg_min_val(Tsrc) < ntg_min_val(Tdest))
00096 if (val < Tsrc(Tdest(ntg_min_val(Tdest))))
00097 return ntg_min_val(Tdest);
00098 return val;
00099 }
00100
00101
00102
00103
00104
00105 namespace internal {
00106 template<class Tdest, class Tsrc>
00107 struct _round {
00108
00109
00110 };
00111
00112 template<class Tdest, class Tsrc>
00113 struct _round<Tdest, float_value<Tsrc> >
00114 {
00115 static const Tdest
00116 doit(const float_value<Tsrc>& val)
00117 {
00118
00119
00120 #if 1
00121
00122
00123
00124 return (ntg_storage_type(Tdest)) round(val.exact());
00125 #endif
00126
00127 }
00128 };
00129
00130 template<class Tdest>
00131 struct _round<Tdest, float_s >
00132 {
00133 static const Tdest
00134 doit(const float_s& val)
00135 {
00136
00137 #if 1
00138
00139
00140
00141 return (ntg_storage_type(Tdest)) roundf(val);
00142 #endif
00143
00144 }
00145 };
00146
00147 template<class Tdest>
00148 struct _round<Tdest, double>
00149 {
00150 static const Tdest
00151 doit(const float_d& val)
00152 {
00153
00154 #if 0
00155
00156
00157
00158 return (ntg_storage_type(Tdest)) round(val);
00159 #endif
00160 return round(val);
00161 }
00162 };
00163
00164 template<class Tdest, class Tsrc>
00165 struct _round<float_value<Tdest>, float_value<Tsrc> >
00166 {
00167 static const Tdest
00168 doit(const float_value<Tsrc>& val)
00169 {
00170 return val.exact();
00171 }
00172 };
00173
00174 template<class Tsrc>
00175 struct _round<float_s, float_value<Tsrc> >
00176 {
00177 static float_s
00178 doit(const float_value<Tsrc>& val)
00179 {
00180 return val.exact();
00181 }
00182 };
00183
00184 template<class Tsrc>
00185 struct _round<float_d, float_value<Tsrc> >
00186 {
00187 static float_d
00188 doit(const float_value<Tsrc>& val)
00189 {
00190 return val.exact();
00191 }
00192 };
00193
00194 template<>
00195 struct _round<float_s, float_d>
00196 {
00197 static float
00198 doit(const double& val)
00199 {
00200 return val;
00201 }
00202 };
00203
00204 template<>
00205 struct _round<float_d, float_s>
00206 {
00207 static float_d
00208 doit(const float& val)
00209 {
00210 return val;
00211 }
00212 };
00213 }
00214
00215 template<class Tdest, class Tsrc> inline
00216 const Tdest round(const Tsrc& val)
00217 {
00218 return internal::_round<Tdest, Tsrc>::doit(val);
00219 }
00220
00221
00222 template<class Tdest, class Tsrc> inline
00223 const Tdest rbound(const Tsrc& val)
00224 {
00225 if (val > Tsrc(Tdest(ntg_max_val(Tdest))))
00226 return ntg_max_val(Tdest);
00227 if (val < Tsrc(Tdest(ntg_min_val(Tdest))))
00228 return ntg_min_val(Tdest);
00229 return cast::round<Tdest>(val);
00230 }
00231
00232 }
00233
00234 }
00235
00236 #endif // NTG_UTILS_CAST_HH