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_CORE_INT_S_HH
00029 # define NTG_CORE_INT_S_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/bool.hh>
00037 # include <mlc/cmp.hh>
00038 # include <mlc/is_a.hh>
00039
00040 # include <string>
00041 # include <sstream>
00042
00043
00044
00045
00046
00047
00048
00049 # define INT_S_CTOR_FROM_UNSIGNED_BUILTIN(Builtin) \
00050 int_s (const Builtin rhs) \
00051 { \
00052 if ((unsigned) internal::typetraits<ntg_type(Builtin)>::size < nbits) \
00053 this->val_ = rhs; \
00054 else \
00055 this->val_ = optraits_type::check(rhs); \
00056 } \
00057 self& operator=(const Builtin rhs) \
00058 { \
00059 if ((unsigned) internal::typetraits<ntg_type(Builtin)>::size < nbits) \
00060 this->val_ = rhs; \
00061 else \
00062 this->val_ = optraits_type::check(rhs); \
00063 return *this; \
00064 }
00065
00066 # define INT_S_CTOR_FROM_SIGNED_BUILTIN(Builtin) \
00067 int_s (const Builtin rhs) \
00068 { \
00069 if ((unsigned)internal::typetraits<ntg_type(Builtin)>::size <= nbits) \
00070 this->val_ = rhs; \
00071 else \
00072 this->val_ = optraits_type::check(rhs); \
00073 } \
00074 self& operator=(const Builtin rhs) \
00075 { \
00076 if ((unsigned)internal::typetraits<ntg_type(Builtin)>::size <= nbits) \
00077 this->val_ = rhs; \
00078 else \
00079 this->val_ = optraits_type::check(rhs); \
00080 return *this; \
00081 }
00082
00083
00084 namespace ntg {
00085
00086 namespace internal {
00087
00088
00089
00090
00091
00092 template <unsigned nbits, class behavior>
00093 struct typetraits<int_s<nbits, behavior> >
00094 : public typetraits<sint_value<int_s<nbits, behavior> > >
00095 {
00096 typedef int_s<nbits, behavior> self;
00097 typedef signed_integer abstract_type;
00098 typedef self ntg_type;
00099
00100 ntg_build_value_type(sint_value<E>);
00101
00102 typedef optraits<self> optraits_type;
00103 typedef behavior abstract_behavior_type;
00104 typedef typename behavior::template get<self> behavior_type;
00105
00106 typedef self base_type;
00107 typedef typename C_for_int_s<nbits>::type storage_type;
00108 typedef self signed_type;
00109 typedef int_u<nbits-1, behavior> unsigned_type;
00110
00111 typedef int_s<32, behavior> cumul_type;
00112 typedef int_s<32, behavior> largest_type;
00113 typedef int_s<32, behavior> signed_largest_type;
00114 typedef int_s<32, behavior> signed_cumul_type;
00115 typedef int_u<32, behavior> unsigned_largest_type;
00116 typedef int_u<32, behavior> unsigned_cumul_type;
00117 typedef signed int integer_type;
00118
00119
00120 enum { size = nbits };
00121 };
00122
00123 }
00124
00125
00126
00127
00128
00129 template <unsigned nbits, class behavior>
00130 class int_s : public sint_value<int_s<nbits, behavior> >
00131 {
00132 typedef int_s<nbits, behavior> self;
00133 typedef ntgi_storage_type(self) storage_type;
00134 typedef ntgi_optraits_type(self) optraits_type;
00135
00136 public:
00137
00138 int_s () { this->val_ = 0; }
00139
00140
00141
00142
00143 INT_S_CTOR_FROM_UNSIGNED_BUILTIN(unsigned long);
00144 INT_S_CTOR_FROM_SIGNED_BUILTIN(signed long);
00145
00146 INT_S_CTOR_FROM_UNSIGNED_BUILTIN(unsigned int);
00147 INT_S_CTOR_FROM_SIGNED_BUILTIN(signed int);
00148
00149 INT_S_CTOR_FROM_UNSIGNED_BUILTIN(unsigned short);
00150 INT_S_CTOR_FROM_SIGNED_BUILTIN(signed short);
00151
00152 INT_S_CTOR_FROM_UNSIGNED_BUILTIN(unsigned char);
00153 INT_S_CTOR_FROM_SIGNED_BUILTIN(signed char);
00154 INT_S_CTOR_FROM_SIGNED_BUILTIN(char);
00155
00156 template <unsigned mbits, class B2>
00157 int_s (const int_s<mbits, B2>& rhs)
00158 {
00159 if (mbits <= nbits)
00160 this->val_ = rhs.val();
00161 else
00162 this->val_ = optraits_type::check(rhs.val());
00163 }
00164 template <unsigned mbits, class B2>
00165 self&
00166 operator=(const int_s<mbits, B2>& rhs)
00167 {
00168 if (mbits <= nbits)
00169 this->val_ = rhs.val();
00170 else
00171 this->val_ = optraits_type::check(rhs.val());
00172 return *this;
00173 }
00174
00175 template <class T>
00176 int_s (const real_value<T>& rhs)
00177 {
00178 this->val_ = optraits_type::check(rhs.val());
00179 }
00180 template <class T>
00181 self&
00182 operator=(const real_value<T>& rhs)
00183 {
00184 this->val_ = optraits_type::check(rhs.val());
00185 return *this;
00186 }
00187
00188
00189
00190 int_s (const float_s rhs)
00191 {
00192 this->val_ = optraits_type::check(roundf(rhs));
00193 }
00194 self& operator=(const float_s rhs)
00195 {
00196 this->val_ = optraits_type::check(roundf(rhs));
00197 return *this;
00198 }
00199
00200 int_s (const float_d rhs)
00201 {
00202 this->val_ = optraits_type::check(round(rhs));
00203 }
00204 self& operator=(const float_d rhs)
00205 {
00206 this->val_ = optraits_type::check(round(rhs));
00207 return *this;
00208 }
00209
00210
00211 int_s (bin b)
00212 {
00213 this->val_ = b.val();
00214 }
00215 self& operator=(bin b)
00216 {
00217 this->val_ = b.val();
00218 return *this;
00219 }
00220
00221 operator storage_type () const { return this->val_; }
00222
00223 private:
00224
00225 int_s(bool);
00226 };
00227
00228 template<unsigned nbits, class behavior>
00229 inline std::ostream&
00230 operator<<(std::ostream& stream, const int_s<nbits, behavior>& rhs)
00231 {
00232 stream << signed(rhs.val());
00233 return stream;
00234 }
00235
00236 namespace internal
00237 {
00238
00239
00240
00241
00242
00243 template <unsigned nbits, class behavior>
00244 struct optraits<int_s<nbits, behavior> > :
00245 public optraits<sint_value<int_s<nbits, behavior> > >
00246 {
00247 public:
00248 typedef int_s<nbits, behavior> self;
00249 typedef optraits<sint_value<int_s<nbits, behavior> > > super;
00250
00251 private:
00252 typedef typename typetraits<self>::base_type base_type_;
00253 typedef typename typetraits<self>::storage_type storage_type_;
00254 typedef typename behavior::template get<self> behavior_type_;
00255
00256 public:
00257 template <class P>
00258 static storage_type_
00259 check(const P& rhs)
00260 { return behavior_type_::check(rhs); }
00261
00262 static storage_type_ max()
00263 { return C_for_int_s<nbits>::max(); }
00264
00265 static storage_type_ min()
00266 { return C_for_int_s<nbits>::min(); }
00267
00268
00269
00270
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 template <unsigned mbits, class B1, class B2>
00284 static bool
00285 cmp_eq(const int_s<mbits, B1>& lhs, const int_u<32, B2>& rhs)
00286 {
00287 if (lhs.val() < 0)
00288 return false;
00289
00290 return static_cast<int_u<32, B2> >(lhs).val() == rhs.val();
00291 }
00292 template <unsigned mbits, class B1, class B2>
00293 static bool cmp_eq(const int_u<32, B1>& lhs, const int_s<mbits, B2>& rhs)
00294 { return cmp_eq(rhs, lhs); }
00295
00296
00297
00298 template <class T1, class T2>
00299 static bool
00300 cmp_eq(const T1& lhs, const T2& rhs)
00301 { return super::cmp_eq(lhs, rhs); }
00302
00303
00304
00305
00306
00307
00308
00309 template <unsigned mbits, class B1, class B2>
00310 static bool
00311 cmp_lt(const int_s<mbits, B1>& lhs, const int_u<32, B2>& rhs)
00312 {
00313 if (lhs.val() < 0)
00314 return true;
00315
00316 return static_cast<int_u<32, B2> >(lhs).val() < rhs.val();
00317 }
00318 template <unsigned mbits, class B1, class B2>
00319 static bool cmp_lt(const int_u<32, B1>& lhs, const int_s<mbits, B2>& rhs)
00320 {
00321 if (rhs.val() < 0)
00322 return false;
00323
00324 return lhs.val() < static_cast<int_u<32, B1> >(rhs.val());
00325 }
00326
00327
00328
00329 template <class T1, class T2>
00330 static bool
00331 cmp_lt(const T1& lhs, const T2& rhs)
00332 { return super::cmp_lt(lhs, rhs); }
00333
00334
00335 static std::string name() {
00336 std::ostringstream out;
00337 out << "int_s<" << int(nbits) << ", " << behavior::name() << ">"
00338 << std::ends;
00339 return out.str();
00340 }
00341 };
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 template<unsigned nbits, class B1, unsigned mbits, class B2>
00355 struct operator_traits<operator_plus, int_s<nbits, B1>, int_s<mbits, B2> >
00356 {
00357 enum { commutative = true,
00358 need_check = ((unsigned) mlc::max<nbits, mbits>::ret >= 32) };
00359 typedef int_s<(unsigned)mlc::maxN<nbits + 1,mbits + 1, 32>::ret,
00360 typename deduce_op_behavior<B1, B2>::ret> ret;
00361 typedef int_s<nbits,
00362 typename ret_behavior_if<need_check, ret>::ret> impl;
00363 };
00364
00365
00366
00367
00368 template <unsigned nbits, class B1, unsigned mbits, class B2>
00369 struct operator_traits<operator_plus, int_s<nbits, B1>, int_u<mbits, B2> >
00370 {
00371 enum { commutative = true,
00372 need_check = ((mbits >= 31) || (nbits >= 32)) };
00373 typedef int_s<(unsigned)mlc::maxN<nbits + 1,mbits + 2, 32>::ret,
00374 typename deduce_op_behavior<B1, B2>::ret> ret;
00375 typedef int_s<nbits,
00376 typename ret_behavior_if<need_check, ret>::ret> impl;
00377 };
00378
00379
00380
00381
00382
00383
00384
00385
00386 template<unsigned nbits, class B1, unsigned mbits, class B2>
00387 struct operator_traits<operator_minus, int_s<nbits, B1>, int_s<mbits, B2> >
00388 {
00389 enum { commutative = true,
00390 need_check = ((mbits >= 31) || (nbits >= 31)) };
00391 typedef int_s<(unsigned)mlc::maxN<nbits + 1, mbits + 1, 32>::ret,
00392 typename deduce_op_behavior<B1, B2>::ret> ret;
00393 typedef int_s<nbits,
00394 typename ret_behavior_if<need_check, ret>::ret> impl;
00395 };
00396
00397
00398
00399 template <unsigned nbits, class B1, unsigned mbits, class B2>
00400 struct operator_traits<operator_minus, int_s<nbits, B1>, int_u<mbits, B2> >
00401 {
00402 enum { commutative = true,
00403 need_check = ((mbits >= 31) || (nbits >= 32)) };
00404 typedef int_s<(unsigned)mlc::maxN<nbits + 1, mbits + 2, 32>::ret,
00405 typename deduce_op_behavior<B1, B2>::ret> ret;
00406 typedef int_s<nbits,
00407 typename ret_behavior_if<need_check, ret>::ret> impl;
00408 };
00409
00410
00411
00412
00413
00414
00415
00416
00417 template<unsigned nbits, class B1, unsigned mbits, class B2>
00418 struct operator_traits<operator_times, int_s<nbits, B1>, int_s<mbits, B2> >
00419 {
00420 enum { commutative = true,
00421 need_check = (mbits + nbits > 32) };
00422 typedef int_s<(unsigned)mlc::saturateN<nbits + mbits, 32>::ret,
00423 typename deduce_op_behavior<B1, B2>::ret> ret;
00424 typedef int_s<nbits,
00425 typename ret_behavior_if<need_check, ret>::ret> impl;
00426 };
00427
00428
00429
00430
00431 template <unsigned nbits, class B1, unsigned mbits, class B2>
00432 struct operator_traits<operator_times, int_s<nbits, B1>, int_u<mbits, B2> >
00433 {
00434 enum { commutative = true,
00435 need_check = (nbits + mbits + 1 > 32)};
00436 typedef int_s<(unsigned)mlc::saturateN<nbits + mbits+1, 32>::ret,
00437 typename deduce_op_behavior<B1, B2>::ret> ret;
00438 typedef int_s<nbits,
00439 typename ret_behavior_if<need_check, ret>::ret> impl;
00440 };
00441
00442
00443
00444
00445
00446
00447
00448 template<unsigned nbits, class B1, unsigned mbits, class B2>
00449 struct operator_traits<operator_div, int_s<nbits, B1>, int_s<mbits, B2> >
00450 {
00451 enum { commutative = true };
00452 typedef int_s<nbits, typename deduce_op_behavior<B1, B2>::ret> ret;
00453 typedef int_s<nbits, force> impl;
00454 };
00455
00456
00457
00458 template <unsigned nbits, class B1, unsigned mbits, class B2>
00459 struct operator_traits<operator_div, int_s<nbits, B1>, int_u<mbits, B2> >
00460 {
00461 enum { commutative = false,
00462 need_check = (mbits >= 32) };
00463 typedef int_s<nbits, typename deduce_op_behavior<B1, B2>::ret> ret;
00464 typedef int_s<nbits,
00465 typename ret_behavior_if<need_check, ret>::ret> impl;
00466 };
00467
00468 template <unsigned nbits, class B1, unsigned mbits, class B2>
00469 struct operator_traits<operator_div, int_u<mbits, B2>, int_s<nbits, B1> >
00470 {
00471 enum { commutative = false,
00472 need_check = (mbits >= 32) };
00473 typedef int_s<mlc::saturateN<mbits + 1, 32>::ret,
00474 typename deduce_op_behavior<B1, B2>::ret> ret;
00475 typedef int_s<nbits,
00476 typename ret_behavior_if<need_check, ret>::ret> impl;
00477 };
00478
00479
00480
00481
00482
00483
00484
00485 template<unsigned nbits, class B1, unsigned mbits, class B2>
00486 struct operator_traits<operator_mod, int_s<nbits, B1>, int_s<mbits, B2> >
00487 {
00488 enum { commutative = false };
00489 typedef int_s<mbits, typename deduce_op_behavior<B1, B2>::ret> ret;
00490 typedef int_s<nbits, force> impl;
00491 };
00492
00493
00494
00495 template <unsigned nbits, class B1, unsigned mbits, class B2>
00496 struct operator_traits<operator_mod, int_s<nbits, B1>, int_u<mbits, B2> >
00497 {
00498 enum { commutative = false,
00499 need_check = (mbits >= 32) };
00500 typedef int_s<(unsigned)mlc::saturateN<mbits + 1, 32>::ret,
00501 typename deduce_op_behavior<B1, B2>::ret> ret;
00502 typedef int_s<nbits,
00503 typename ret_behavior_if<need_check, ret>::ret> impl;
00504 };
00505
00506
00507
00508
00509
00510 #if 0
00511 template <unsigned nbits, class B1, unsigned mbits, class B2>
00512 struct operator_traits<operator_mod, int_u<nbits, B1>, int_s<mbits, B2> >
00513 {
00514 enum { commutative = false };
00515 typedef int_u<mbits, typename deduce_op_behavior<B1, B2>::ret> ret;
00516 typedef int_s<nbits, B1> impl;
00517 };
00518 #endif
00519
00520
00521
00522
00523
00524
00525
00526 template<unsigned nbits, class B1, unsigned mbits, class B2>
00527 struct operator_traits<operator_min, int_s<nbits, B1>, int_s<mbits, B2> >
00528 {
00529 enum { commutative = true };
00530 typedef int_s<(unsigned) mlc::min<nbits, mbits>::ret,
00531 typename deduce_op_behavior<B1, B2>::ret> ret;
00532 typedef int_s<nbits, force> impl;
00533 };
00534
00535
00536
00537
00538
00539
00540
00541 template<unsigned nbits, class B1, unsigned mbits, class B2>
00542 struct operator_traits<operator_max, int_s<nbits, B1>, int_s<mbits, B2> >
00543 {
00544 enum { commutative = true };
00545 typedef int_s<(unsigned) mlc::max<nbits, mbits>::ret,
00546 typename deduce_op_behavior<B1, B2>::ret> ret;
00547 typedef int_s<nbits, force> impl;
00548 };
00549
00550
00551
00552
00553
00554
00555
00556 template<unsigned nbits, class B1, unsigned mbits, class B2>
00557 struct operator_traits<operator_cmp, int_s<nbits, B1>, int_s<mbits, B2> >
00558 {
00559 enum { commutative = true };
00560 typedef int_s<(unsigned)mlc::maxN<nbits,mbits,32>::ret, unsafe> ret;
00561 typedef int_s<nbits, force> impl;
00562 };
00563
00564
00565
00566
00567 template <unsigned nbits, class B1, unsigned mbits, class B2>
00568 struct operator_traits<operator_cmp, int_s<nbits, B1>, int_u<mbits, B2> >
00569 {
00570 enum { commutative = true };
00571 typedef int_s<(unsigned)mlc::maxN<nbits,mbits+1, 32>::ret, unsafe> ret;
00572 typedef int_s<nbits, force> impl;
00573 };
00574
00575 }
00576
00577 }
00578
00579 #endif // !NTG_CORE_INT_S_HH