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_REAL_INT_U_HH
00029 # define NTG_REAL_INT_U_HH
00030
00031 # include <ntg/basics.hh>
00032 # include <ntg/real/optraits_real.hh>
00033 # include <ntg/real/real_value.hh>
00034 # include <ntg/bin.hh>
00035
00036 # include <mlc/cmp.hh>
00037
00038 # include <string>
00039 # include <sstream>
00040
00041
00042
00043
00044
00045 # define INT_U_CTOR_FROM_UNSIGNED_BUILTIN_INT(Builtin) \
00046 int_u (const Builtin rhs) \
00047 { \
00048 if ((unsigned) internal::typetraits<ntg_type(Builtin)>::size <= nbits) \
00049 this->val_ = rhs; \
00050 else \
00051 this->val_ = optraits_type::check(rhs); \
00052 } \
00053 self& operator=(const Builtin rhs) \
00054 { \
00055 if ((unsigned) internal::typetraits<ntg_type(Builtin)>::size <= nbits) \
00056 this->val_ = rhs; \
00057 else \
00058 this->val_ = optraits_type::check(rhs); \
00059 return *this; \
00060 }
00061
00062 # define INT_U_CTOR_FROM_BUILTIN_INT(Builtin) \
00063 int_u (const Builtin rhs) \
00064 { \
00065 this->val_ = optraits_type::check(rhs); \
00066 } \
00067 self& operator=(const Builtin rhs) \
00068 { \
00069 this->val_ = optraits_type::check(rhs); \
00070 return *this; \
00071 }
00072
00073
00074 namespace ntg {
00075
00076 namespace internal {
00077
00078
00079
00080
00081
00082 template <unsigned nbits, class behavior>
00083 struct typetraits<int_u<nbits, behavior> >
00084 : public typetraits<uint_value<int_u<nbits, behavior> > >
00085 {
00086 typedef int_u<nbits, behavior> self;
00087 typedef unsigned_integer abstract_type;
00088 typedef self ntg_type;
00089
00090 ntg_build_value_type(uint_value<E>);
00091
00092 typedef optraits<self> optraits_type;
00093 typedef behavior abstract_behavior_type;
00094 typedef typename behavior::template get<self> behavior_type;
00095
00096 typedef self base_type;
00097 typedef typename C_for_int_u<nbits>::type storage_type;
00098 typedef int_s<mlc::saturateN<nbits+1, 32>::ret,
00099 behavior> signed_type;
00100 typedef self unsigned_type;
00101
00102 typedef int_u<32, behavior> cumul_type;
00103 typedef int_u<32, behavior> largest_type;
00104 typedef int_s<32, behavior> signed_largest_type;
00105 typedef int_s<32, behavior> signed_cumul_type;
00106 typedef int_u<32, behavior> unsigned_largest_type;
00107 typedef int_u<32, behavior> unsigned_cumul_type;
00108 typedef unsigned int integer_type;
00109 typedef int_u<nbits, unsafe> unsafe_type;
00110
00111
00112 enum { size = nbits };
00113 };
00114
00115 }
00116
00117
00118
00119
00120
00121 template <unsigned nbits, class behavior>
00122 class int_u : public uint_value<int_u<nbits, behavior> >
00123 {
00124 typedef int_u<nbits, behavior> self;
00125 typedef ntgi_storage_type(self) storage_type;
00126
00127
00128 typedef ntgi_optraits_type(self) optraits_type;
00129
00130 public:
00131 int_u () { this->val_ = 0; }
00132
00133
00134
00135
00136
00137
00138 INT_U_CTOR_FROM_UNSIGNED_BUILTIN_INT(unsigned long);
00139 INT_U_CTOR_FROM_BUILTIN_INT(signed long);
00140
00141 INT_U_CTOR_FROM_UNSIGNED_BUILTIN_INT(unsigned int);
00142 INT_U_CTOR_FROM_BUILTIN_INT(signed int);
00143
00144 INT_U_CTOR_FROM_UNSIGNED_BUILTIN_INT(unsigned short);
00145 INT_U_CTOR_FROM_BUILTIN_INT(signed short);
00146
00147 INT_U_CTOR_FROM_UNSIGNED_BUILTIN_INT(unsigned char);
00148 INT_U_CTOR_FROM_BUILTIN_INT(signed char);
00149 INT_U_CTOR_FROM_BUILTIN_INT(char);
00150
00151 int_u (const float_s rhs)
00152 {
00153 this->val_ = optraits_type::check(roundf(rhs));
00154 }
00155 self&
00156 operator=(const float rhs)
00157 {
00158 this->val_ = optraits_type::check(roundf(rhs));
00159 return *this;
00160 }
00161
00162 int_u (const float_d rhs)
00163 {
00164 this->val_ = optraits_type::check(round(rhs));
00165 }
00166 self&
00167 operator=(const double rhs)
00168 {
00169 this->val_ = optraits_type::check(round(rhs));
00170 return *this;
00171 }
00172
00173 template <unsigned mbits, class B2>
00174 int_u (const int_u<mbits, B2>& rhs)
00175 {
00176 if (mbits <= nbits)
00177 this->val_ = rhs.val();
00178 else
00179 this->val_ = optraits_type::check(rhs.val());
00180 }
00181 template <unsigned mbits, class B2>
00182 self&
00183 operator=(const int_u<mbits, B2>& rhs)
00184 {
00185 if (mbits <= nbits)
00186 this->val_ = rhs.val();
00187 else
00188 this->val_ = optraits_type::check(rhs.val());
00189 return *this;
00190 }
00191
00192 template <class T>
00193 int_u (const real_value<T>& rhs)
00194 {
00195 this->val_ = optraits_type::check(rhs.val());
00196 }
00197 template <class T>
00198 self&
00199 operator=(const real_value<T>& rhs)
00200 {
00201 this->val_ = optraits_type::check(rhs.val());
00202 return *this;
00203 }
00204
00205
00206 int_u (bin b)
00207 {
00208 this->val_ = b.val();
00209 }
00210 self&
00211 operator=(bin b)
00212 {
00213 this->val_ = b.val();
00214 return *this;
00215 }
00216
00217 operator storage_type () const { return this->val_; }
00218
00219 private:
00220
00221 int_u(bool);
00222 };
00223
00224 template<unsigned nbits, class behavior>
00225 inline std::ostream&
00226 operator<<(std::ostream& stream, const int_u<nbits, behavior>& rhs)
00227 {
00228 stream << unsigned(rhs.val());
00229 return stream;
00230 }
00231
00232 namespace internal
00233 {
00234
00235
00236
00237
00238
00239 template <unsigned nbits, class behavior>
00240 struct optraits<int_u<nbits, behavior> > :
00241 public optraits<uint_value<int_u<nbits, behavior> > >
00242 {
00243 private:
00244 typedef int_u<nbits, behavior> self;
00245 typedef typename typetraits<self>::storage_type storage_type_;
00246 typedef typename behavior::template get<self> behavior_type_;
00247
00248 public:
00249 template <class P>
00250 static storage_type_ check(const P& rhs)
00251 { return behavior_type_::check(rhs); }
00252
00253 static storage_type_ max()
00254 { return C_for_int_u<nbits>::max(); }
00255
00256 static std::string
00257 name()
00258 {
00259 std::ostringstream out;
00260 out << "int_u<" << int(nbits) << ", " << behavior::name() << ">"
00261 << std::ends;
00262 return out.str();
00263 }
00264 };
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 template<unsigned nbits, class B1, unsigned mbits, class B2>
00277 struct operator_traits<operator_plus, int_u<nbits, B1>, int_u<mbits, B2> >
00278 {
00279 enum { commutative = true,
00280 need_check = ((unsigned) mlc::max<nbits, mbits>::ret >= 32) };
00281 typedef int_u<(unsigned) mlc::maxN<nbits + 1, mbits + 1, 32>::ret,
00282 typename deduce_op_behavior<B1, B2>::ret> ret;
00283 typedef int_u<nbits,
00284 typename ret_behavior_if<need_check, ret>::ret> impl;
00285 };
00286
00287
00288
00289
00290
00291
00292
00293 template<unsigned nbits, class B1, unsigned mbits, class B2>
00294 struct operator_traits<operator_minus, int_u<nbits, B1>, int_u<mbits, B2> >
00295 {
00296 enum { commutative = true,
00297 need_check = ((unsigned) mlc::max<nbits, mbits>::ret >= 32) };
00298 typedef int_s<(unsigned) mlc::maxN<nbits+1, mbits+1, 32>::ret,
00299 typename deduce_op_behavior<B1, B2>::ret> ret;
00300 typedef int_u<nbits,
00301 typename ret_behavior_if<need_check, ret>::ret> impl;
00302 };
00303
00304
00305
00306
00307 template<class B1, unsigned mbits, class B2>
00308 struct operator_traits<operator_minus, int_u<32, B1>, int_u<mbits, B2> >
00309 {
00310 enum { commutative = true };
00311 typedef int_u<32, typename deduce_op_behavior<B1, B2>::ret> ret;
00312 typedef int_u<32, force> impl;
00313 };
00314
00315
00316
00317
00318
00319
00320
00321 template<unsigned nbits, class B1, unsigned mbits, class B2>
00322 struct operator_traits<operator_times, int_u<nbits, B1>, int_u<mbits, B2> >
00323 {
00324 enum { commutative = true, need_check = (nbits + mbits > 32) };
00325 typedef int_u<(unsigned) mlc::saturateN<nbits + mbits, 32>::ret,
00326 typename deduce_op_behavior<B1, B2>::ret> ret;
00327 typedef int_u<nbits,
00328 typename ret_behavior_if<need_check, ret>::ret> impl;
00329 };
00330
00331
00332
00333
00334
00335
00336
00337 template<unsigned nbits, class B1, unsigned mbits, class B2>
00338 struct operator_traits<operator_div, int_u<nbits, B1>, int_u<mbits, B2> >
00339 {
00340 enum { commutative = true };
00341 typedef int_u<nbits, typename deduce_op_behavior<B1, B2>::ret> ret;
00342 typedef int_u<nbits, force> impl;
00343 };
00344
00345
00346
00347
00348
00349
00350
00351 template<unsigned nbits, class B1, unsigned mbits, class B2>
00352 struct operator_traits<operator_mod, int_u<nbits, B1>, int_u<mbits, B2> >
00353 {
00354 enum { commutative = false };
00355 typedef int_u<mbits, typename deduce_op_behavior<B1, B2>::ret> ret;
00356 typedef int_u<nbits, force> impl;
00357 };
00358
00359
00360
00361
00362
00363
00364
00365 template<unsigned nbits, class B1, unsigned mbits, class B2>
00366 struct operator_traits<operator_min, int_u<nbits, B1>, int_u<mbits, B2> >
00367 {
00368 enum { commutative = true };
00369 typedef int_u<(unsigned) mlc::min<nbits, mbits>::ret,
00370 typename deduce_op_behavior<B1, B2>::ret> ret;
00371 typedef int_u<nbits, force> impl;
00372 };
00373
00374
00375
00376
00377
00378
00379
00380
00381 template<unsigned nbits, class B1, unsigned mbits, class B2>
00382 struct operator_traits<operator_max, int_u<nbits, B1>, int_u<mbits, B2> >
00383 {
00384 enum { commutative = true };
00385 typedef int_u<(unsigned) mlc::max<nbits, mbits>::ret,
00386 typename deduce_op_behavior<B1, B2>::ret> ret;
00387 typedef int_u<nbits, force> impl;
00388 };
00389
00390
00391
00392
00393
00394
00395
00396
00397 template<unsigned nbits, class B1, unsigned mbits, class B2>
00398 struct operator_traits<operator_cmp, int_u<nbits, B1>, int_u<mbits, B2> >
00399 {
00400 enum { commutative = true };
00401
00402 typedef int_u<(unsigned) mlc::maxN<nbits, mbits, 32>::ret, unsafe> ret;
00403 typedef int_u<nbits, force> impl;
00404 };
00405
00406 }
00407
00408 }
00409
00410 #endif // !NTG_REAL_INT_U_HH