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