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