00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if !defined (octave_inttypes_h)
00025 #define octave_inttypes_h 1
00026
00027 #include <climits>
00028 #include <cstdlib>
00029
00030 #include <limits>
00031 #include <iosfwd>
00032
00033 #include "lo-traits.h"
00034 #include "lo-math.h"
00035 #include "lo-mappers.h"
00036
00037 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
00038 inline long double xround (long double x) { return roundl (x); }
00039 inline long double xisnan (long double x) { return xisnan (static_cast<double> (x)); }
00040 #endif
00041
00042
00043 #ifdef min
00044 #undef min
00045 #undef max
00046 #endif
00047
00048
00049
00050
00051 template <class T>
00052 inline T octave_int_abs (T x) { return x >= 0 ? x : -x; }
00053
00054
00055 template<int qsize, bool qsigned>
00056 struct query_integer_type
00057 {
00058 public:
00059 static const bool registered = false;
00060 typedef void type;
00061
00062 };
00063
00064 #define REGISTER_INT_TYPE(TYPE) \
00065 template <> \
00066 class query_integer_type<sizeof (TYPE), std::numeric_limits<TYPE>::is_signed> \
00067 { \
00068 public: \
00069 static const bool registered = true; \
00070 typedef TYPE type; \
00071 }
00072
00073
00074 REGISTER_INT_TYPE (int8_t);
00075 REGISTER_INT_TYPE (uint8_t);
00076 REGISTER_INT_TYPE (int16_t);
00077 REGISTER_INT_TYPE (uint16_t);
00078 REGISTER_INT_TYPE (int32_t);
00079 REGISTER_INT_TYPE (uint32_t);
00080 REGISTER_INT_TYPE (int64_t);
00081 REGISTER_INT_TYPE (uint64_t);
00082
00083
00084
00085
00086 #define REGISTER_OCTAVE_CMP_OP(NM,OP) \
00087 class NM \
00088 { \
00089 public: \
00090 static const bool ltval = (0 OP 1), gtval = (1 OP 0); \
00091 template <class T> \
00092 static bool op (T x, T y) { return x OP y; } \
00093 }
00094
00095
00096
00097 #define REGISTER_OCTAVE_CONST_OP(NM,value) \
00098 class NM \
00099 { \
00100 public: \
00101 static const bool ltval = value, gtval = value; \
00102 template <class T> \
00103 static bool op (T, T) { return value; } \
00104 }
00105
00106
00107 class octave_int_cmp_op
00108 {
00109
00110
00111
00112
00113
00114 template <class T1, class T2>
00115 class prom
00116 {
00117
00118 static const bool pint = (sizeof (T1) < sizeof (int)
00119 && sizeof (T2) < sizeof (int));
00120 static const bool t1sig = std::numeric_limits<T1>::is_signed;
00121 static const bool t2sig = std::numeric_limits<T2>::is_signed;
00122 static const bool psig =
00123 (pint || (sizeof (T2) > sizeof (T1) && t2sig) || t1sig);
00124 static const int psize =
00125 (pint ? sizeof (int) : (sizeof (T2) > sizeof (T1)
00126 ? sizeof (T2) : sizeof (T1)));
00127 public:
00128 typedef typename query_integer_type<psize, psig>::type type;
00129 };
00130
00131
00132
00133 template<class xop, int size>
00134 class uiop
00135 {
00136 typedef typename query_integer_type<size, false>::type utype;
00137 typedef typename query_integer_type<size, true>::type stype;
00138 public:
00139 static bool op (utype x, utype y)
00140 { return xop::op (x, y); }
00141 static bool op (stype x, stype y)
00142 { return xop::op (x, y); }
00143 static bool op (stype x, utype y)
00144 { return (x < 0) ? xop::ltval : xop::op (static_cast<utype> (x), y); }
00145 static bool op (utype x, stype y)
00146 { return (y < 0) ? xop::gtval : xop::op (x, static_cast<utype> (y)); }
00147 };
00148
00149 public:
00150 REGISTER_OCTAVE_CMP_OP (lt, <);
00151 REGISTER_OCTAVE_CMP_OP (le, <=);
00152 REGISTER_OCTAVE_CMP_OP (gt, >);
00153 REGISTER_OCTAVE_CMP_OP (ge, >=);
00154 REGISTER_OCTAVE_CMP_OP (eq, ==);
00155 REGISTER_OCTAVE_CMP_OP (ne, !=);
00156 REGISTER_OCTAVE_CONST_OP (ct, true);
00157 REGISTER_OCTAVE_CONST_OP (cf, false);
00158
00159
00160 template<class xop, class T1, class T2>
00161 static bool
00162 op (T1 x, T2 y)
00163 {
00164 typedef typename prom<T1, T2>::type PT1;
00165 typedef typename prom<T2, T1>::type PT2;
00166 return uiop<xop, sizeof (PT1)>::op (static_cast<PT1> (x),
00167 static_cast<PT2> (y));
00168 }
00169
00170 public:
00171
00172
00173 template <class xop, class T>
00174 static bool
00175 mop (T x, double y)
00176 { return xop::op (static_cast<double> (x), y); }
00177
00178 template <class xop, class T>
00179 static bool
00180 mop (double x, T y)
00181 { return xop::op (x, static_cast<double> (y)); }
00182
00183
00184
00185 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
00186 #define DEFINE_LONG_DOUBLE_CMP_OP(T1, T2) \
00187 template <class xop> \
00188 static bool \
00189 mop (T1 x, T2 y) \
00190 { \
00191 return xop::op (static_cast<long double> (x), \
00192 static_cast<long double> (y)); \
00193 }
00194 #else
00195
00196
00197
00198
00199
00200 #define DEFINE_LONG_DOUBLE_CMP_OP(T1, T2) \
00201 template <class xop> static OCTAVE_API bool \
00202 emulate_mop (T1, T2); \
00203 template <class xop> \
00204 static bool \
00205 mop (T1 x, T2 y) \
00206 { \
00207 return emulate_mop<xop> (x, y); \
00208 }
00209 #endif
00210
00211 DEFINE_LONG_DOUBLE_CMP_OP(double, uint64_t)
00212 DEFINE_LONG_DOUBLE_CMP_OP(double, int64_t)
00213 DEFINE_LONG_DOUBLE_CMP_OP(int64_t, double)
00214 DEFINE_LONG_DOUBLE_CMP_OP(uint64_t, double)
00215
00216 #undef DEFINE_LONG_DOUBLE_CMP_OP
00217 };
00218
00219
00220 template <class T>
00221 class octave_int_base
00222 {
00223 protected:
00224
00225 static T min_val () { return std::numeric_limits<T>:: min (); }
00226 static T max_val () { return std::numeric_limits<T>:: max (); }
00227
00228 public:
00229
00230
00231 template <class S>
00232 static T
00233 truncate_int (const S& value)
00234 {
00235
00236 static const bool t_is_signed = std::numeric_limits<T>::is_signed;
00237 static const bool s_is_signed = std::numeric_limits<S>::is_signed;
00238 static const int t_size = sizeof (T), s_size = sizeof (S);
00239 static const bool omit_chk_min =
00240 (! s_is_signed || (t_is_signed && t_size >= s_size));
00241 static const bool omit_chk_max =
00242 (t_size > s_size || (t_size == s_size
00243 && (! t_is_signed || s_is_signed)));
00244
00245 typedef octave_int_cmp_op::cf cf;
00246 typedef octave_int_cmp_op::lt lt;
00247 typedef octave_int_cmp_op::gt gt;
00248 typedef typename if_then_else<omit_chk_min, cf, lt>::result chk_min;
00249 typedef typename if_then_else<omit_chk_max, cf, gt>::result chk_max;
00250
00251
00252
00253 if (chk_min::op (value, static_cast<S> (min_val ())))
00254 {
00255 ftrunc = true;
00256 return min_val ();
00257 }
00258 else if (chk_max::op (value, static_cast<S> (max_val ())))
00259 {
00260 ftrunc = true;
00261 return max_val ();
00262 }
00263 else
00264 return static_cast<T> (value);
00265 }
00266
00267 private:
00268
00269
00270 template <class S>
00271 static S
00272 compute_threshold (S val, T orig_val)
00273 {
00274 val = xround (val);
00275
00276 if (orig_val % 2 && val / 2 == xround (val / 2))
00277
00278 val *= (static_cast<S>(1) - (std::numeric_limits<S>::epsilon () / 2));
00279 return val;
00280 }
00281
00282 public:
00283
00284 template <class S>
00285 static T
00286 convert_real (const S& value)
00287 {
00288
00289 static const S thmin = compute_threshold (static_cast<S> (min_val ()), min_val ());
00290 static const S thmax = compute_threshold (static_cast<S> (max_val ()), max_val ());
00291 if (xisnan (value))
00292 {
00293 fnan = true;
00294 return static_cast<T> (0);
00295 }
00296 else if (value < thmin)
00297 {
00298 ftrunc = true;
00299 return min_val ();
00300 }
00301 else if (value > thmax)
00302 {
00303 ftrunc = true;
00304 return max_val ();
00305 }
00306 else
00307 {
00308 S rvalue = xround (value);
00309 if (rvalue != value) fnon_int = true;
00310 return static_cast<T> (rvalue);
00311 }
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 static bool get_trunc_flag () { return ftrunc; }
00325 static bool get_nan_flag () { return fnan; }
00326 static bool get_non_int_flag () { return fnon_int; }
00327 static void clear_conv_flags ()
00328 {
00329 ftrunc = false;
00330 fnan = false;
00331 fnon_int = false;
00332 }
00333
00334 static bool get_math_trunc_flag () { return ftrunc || fnan; }
00335 static void clear_conv_flag () { clear_conv_flags (); }
00336
00337 protected:
00338
00339
00340 static bool ftrunc;
00341 static bool fnon_int;
00342 static bool fnan;
00343 };
00344
00345 template<class T> bool octave_int_base<T>::ftrunc = false;
00346 template<class T> bool octave_int_base<T>::fnon_int = false;
00347 template<class T> bool octave_int_base<T>::fnan = false;
00348
00349
00350
00351
00352
00353
00354 template <class T, bool is_signed>
00355 class octave_int_arith_base
00356 { };
00357
00358
00359
00360 template <class T>
00361 class octave_int_arith_base<T, false> : octave_int_base<T>
00362 {
00363 public:
00364
00365 static T
00366 abs (T x) { return x; }
00367
00368 static T
00369 signum (T x) { return x ? static_cast<T> (1) : static_cast<T> (0); }
00370
00371
00372 static T
00373 rshift (T x, int n) { return x >> n; }
00374
00375 static T
00376 lshift (T x, int n) { return x << n; }
00377
00378 static T
00379 minus (T x)
00380 {
00381 if (x != 0) octave_int_base<T>::ftrunc = true;
00382 return static_cast<T> (0);
00383 }
00384
00385
00386
00387 static T
00388 add (T x, T y)
00389 {
00390 T u = x + y;
00391 if (u < x)
00392 {
00393 u = octave_int_base<T>::max_val ();
00394 octave_int_base<T>::ftrunc = true;
00395 }
00396 return u;
00397 }
00398
00399 static T
00400 sub (T x, T y)
00401 {
00402 T u = x - y;
00403 if (u > x)
00404 {
00405 u = 0;
00406 octave_int_base<T>::ftrunc = true;
00407 }
00408 return u;
00409 }
00410
00411
00412
00413 static T
00414 mul (T x, T y)
00415 {
00416
00417 typedef typename query_integer_type<2*sizeof (T), false>::type mptype;
00418 return truncate_int (static_cast<mptype> (x)
00419 * static_cast<mptype> (y));
00420 }
00421
00422
00423
00424 static T
00425 div (T x, T y)
00426 {
00427 if (y != 0)
00428 {
00429 T z = x / y, w = x % y;
00430 if (w >= y-w) z += 1;
00431 return z;
00432 }
00433 else
00434 {
00435 octave_int_base<T>::ftrunc = true;
00436 return x ? octave_int_base<T>::max_val () : 0;
00437 }
00438 }
00439 };
00440
00441 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
00442
00443 template <>
00444 inline uint64_t
00445 octave_int_arith_base<uint64_t, false>:: mul (uint64_t x, uint64_t y)
00446 {
00447 long double p = static_cast<long double> (x) * static_cast<long double> (y);
00448 if (p > static_cast<long double> (octave_int_base<uint64_t>::max_val ()))
00449 {
00450 octave_int_base<uint64_t>::ftrunc = true;
00451 return octave_int_base<uint64_t>::max_val ();
00452 }
00453 else
00454 return static_cast<uint64_t> (p);
00455 }
00456 #else
00457
00458 template <>
00459 OCTAVE_API uint64_t
00460 octave_int_arith_base<uint64_t, false>::mul (uint64_t, uint64_t);
00461 #endif
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 template <class T>
00484 class octave_int_arith_base<T, true> : octave_int_base<T>
00485 {
00486
00487 typedef typename query_integer_type<sizeof (T), false>::type UT;
00488 public:
00489
00490
00491 static T
00492 signbit (T x)
00493 {
00494 #ifdef HAVE_FAST_INT_OPS
00495 return static_cast<UT> (x) >> std::numeric_limits<T>::digits;
00496 #else
00497 return (x < 0) ? 1 : 0;
00498 #endif
00499 }
00500
00501 static T
00502 abs (T x)
00503 {
00504 #ifdef HAVE_FAST_INT_OPS
00505
00506
00507
00508 T m = x >> std::numeric_limits<T>::digits;
00509 T y = (x ^ m) - m;
00510 if (y < 0)
00511 {
00512 y = octave_int_base<T>::max_val ();
00513 octave_int_base<T>::ftrunc = true;
00514 }
00515 return y;
00516 #else
00517
00518
00519
00520
00521 T y;
00522 if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
00523 && x == octave_int_base<T>::min_val ())
00524 {
00525 y = octave_int_base<T>::max_val ();
00526 octave_int_base<T>::ftrunc = true;
00527 }
00528 else
00529 y = (x < 0) ? -x : x;
00530 return y;
00531 #endif
00532 }
00533
00534 static T
00535 signum (T x)
00536 {
00537
00538 return ((x > 0) ? 1 : 0) - signbit (x);
00539 }
00540
00541
00542
00543
00544
00545 static T
00546 rshift (T x, int n) { return x >> n; }
00547
00548 static T
00549 lshift (T x, int n) { return x << n; }
00550
00551
00552 static T
00553 minus (T x)
00554 {
00555 #ifdef HAVE_FAST_INT_OPS
00556 T y = -x;
00557 if (y == octave_int_base<T>::min_val ())
00558 {
00559 --y;
00560 octave_int_base<T>::ftrunc = false;
00561 }
00562 return y;
00563 #else
00564 T y;
00565 if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
00566 && x == octave_int_base<T>::min_val ())
00567 {
00568 y = octave_int_base<T>::max_val ();
00569 octave_int_base<T>::ftrunc = true;
00570 }
00571 else
00572 y = -x;
00573 return y;
00574 #endif
00575 }
00576
00577 static T
00578 add (T x, T y)
00579 {
00580 #ifdef HAVE_FAST_INT_OPS
00581
00582
00583
00584 T u = static_cast<UT> (x) + static_cast<UT> (y);
00585 T ux = u ^ x, uy = u ^ y;
00586 if ((ux & uy) < 0)
00587 {
00588 u = octave_int_base<T>::max_val () + signbit (~u);
00589 octave_int_base<T>::ftrunc = true;
00590 }
00591 return u;
00592 #else
00593
00594 T u;
00595 if (y < 0)
00596 {
00597 if (x < octave_int_base<T>::min_val () - y)
00598 {
00599 u = octave_int_base<T>::min_val ();
00600 octave_int_base<T>::ftrunc = true;
00601 }
00602 else
00603 u = x + y;
00604 }
00605 else
00606 {
00607 if (x > octave_int_base<T>::max_val () - y)
00608 {
00609 u = octave_int_base<T>::max_val ();
00610 octave_int_base<T>::ftrunc = true;
00611 }
00612 else
00613 u = x + y;
00614 }
00615
00616 return u;
00617 #endif
00618 }
00619
00620
00621 static T
00622 sub (T x, T y)
00623 {
00624 #ifdef HAVE_FAST_INT_OPS
00625
00626
00627
00628 T u = static_cast<UT> (x) - static_cast<UT> (y);
00629 T ux = u ^ x, uy = u ^ ~y;
00630 if ((ux & uy) < 0)
00631 {
00632 u = octave_int_base<T>::max_val () + signbit (~u);
00633 octave_int_base<T>::ftrunc = true;
00634 }
00635 return u;
00636 #else
00637
00638 T u;
00639 if (y < 0)
00640 {
00641 if (x > octave_int_base<T>::max_val () + y)
00642 {
00643 u = octave_int_base<T>::max_val ();
00644 octave_int_base<T>::ftrunc = true;
00645 }
00646 else
00647 u = x - y;
00648 }
00649 else
00650 {
00651 if (x < octave_int_base<T>::min_val () + y)
00652 {
00653 u = octave_int_base<T>::min_val ();
00654 octave_int_base<T>::ftrunc = true;
00655 }
00656 else
00657 u = x - y;
00658 }
00659
00660 return u;
00661 #endif
00662 }
00663
00664
00665
00666 static T
00667 mul (T x, T y)
00668 {
00669
00670 typedef typename query_integer_type<2*sizeof (T), true>::type mptype;
00671 return truncate_int (static_cast<mptype> (x)
00672 * static_cast<mptype> (y));
00673 }
00674
00675
00676 static T
00677 div (T x, T y)
00678 {
00679 T z;
00680 if (y == 0)
00681 {
00682 octave_int_base<T>::ftrunc = true;
00683 if (x < 0)
00684 z = octave_int_base<T>::min_val ();
00685 else if (x != 0)
00686 z = octave_int_base<T>::max_val ();
00687 else
00688 z = 0;
00689 }
00690 else if (y < 0)
00691 {
00692
00693 if (y == -1 && x == octave_int_base<T>::min_val ())
00694 {
00695 octave_int_base<T>::ftrunc = true;
00696 z = octave_int_base<T>::max_val ();
00697 }
00698 else
00699 {
00700 z = x / y;
00701 T w = -octave_int_abs (x % y);
00702 if (w <= y - w)
00703 z -= 1 - (signbit (x) << 1);
00704 }
00705 }
00706 else
00707 {
00708 z = x / y;
00709
00710
00711
00712 T w = octave_int_abs (x % y);
00713
00714 if (w >= y - w)
00715 z += 1 - (signbit (x) << 1);
00716 }
00717 return z;
00718 }
00719
00720 };
00721
00722 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
00723
00724 template <>
00725 inline int64_t
00726 octave_int_arith_base<int64_t, true>:: mul (int64_t x, int64_t y)
00727 {
00728 long double p = static_cast<long double> (x) * static_cast<long double> (y);
00729
00730
00731
00732 if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ()))
00733 {
00734 octave_int_base<int64_t>::ftrunc = true;
00735 return octave_int_base<int64_t>::max_val ();
00736 }
00737 else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ()))
00738 {
00739 octave_int_base<int64_t>::ftrunc = true;
00740 return octave_int_base<int64_t>::min_val ();
00741 }
00742 else
00743 return static_cast<int64_t> (p);
00744 }
00745 #else
00746
00747 template <>
00748 OCTAVE_API int64_t
00749 octave_int_arith_base<int64_t, true>::mul (int64_t, int64_t);
00750 #endif
00751
00752
00753 template<class T>
00754 class octave_int_arith
00755 : public octave_int_arith_base<T, std::numeric_limits<T>::is_signed>
00756 {};
00757
00758 template <class T>
00759 class
00760 octave_int : public octave_int_base<T>
00761 {
00762 public:
00763 typedef T val_type;
00764
00765 octave_int (void) : ival () { }
00766
00767 octave_int (T i) : ival (i) { }
00768
00769 octave_int (double d) : ival (octave_int_base<T>::convert_real (d)) { }
00770
00771 octave_int (float d) : ival (octave_int_base<T>::convert_real (d)) { }
00772
00773 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
00774 octave_int (long double d) : ival (octave_int_base<T>::convert_real (d)) { }
00775 #endif
00776
00777 octave_int (bool b) : ival (b) { }
00778
00779 template <class U>
00780 octave_int (const U& i) : ival(octave_int_base<T>::truncate_int (i)) { }
00781
00782 template <class U>
00783 octave_int (const octave_int<U>& i)
00784 : ival (octave_int_base<T>::truncate_int (i.value ())) { }
00785
00786 octave_int (const octave_int<T>& i) : ival (i.ival) { }
00787
00788 octave_int& operator = (const octave_int<T>& i)
00789 {
00790 ival = i.ival;
00791 return *this;
00792 }
00793
00794 T value (void) const { return ival; }
00795
00796 const unsigned char * iptr (void) const
00797 { return reinterpret_cast<const unsigned char *> (& ival); }
00798
00799 bool operator ! (void) const { return ! ival; }
00800
00801 bool bool_value (void) const { return static_cast<bool> (value ()); }
00802
00803 char char_value (void) const { return static_cast<char> (value ()); }
00804
00805 double double_value (void) const { return static_cast<double> (value ()); }
00806
00807 float float_value (void) const { return static_cast<float> (value ()); }
00808
00809 operator T (void) const { return value (); }
00810
00811
00812
00813 operator double (void) const { return double_value (); }
00814
00815 operator float (void) const { return float_value (); }
00816
00817 octave_int<T>
00818 operator + () const
00819 { return *this; }
00820
00821
00822 #define OCTAVE_INT_UN_OP(OPNAME,NAME) \
00823 inline octave_int<T> \
00824 OPNAME () const \
00825 { return octave_int_arith<T>::NAME (ival); }
00826
00827 OCTAVE_INT_UN_OP(operator -, minus)
00828 OCTAVE_INT_UN_OP(abs, abs)
00829 OCTAVE_INT_UN_OP(signum, signum)
00830
00831 #undef OCTAVE_INT_UN_OP
00832
00833
00834 #define OCTAVE_INT_BIN_OP(OP, NAME, ARGT) \
00835 inline octave_int<T> \
00836 operator OP (const ARGT& y) const \
00837 { return octave_int_arith<T>::NAME (ival, y); } \
00838 inline octave_int<T>& \
00839 operator OP##= (const ARGT& y) \
00840 { \
00841 ival = octave_int_arith<T>::NAME (ival, y); \
00842 return *this; \
00843 }
00844
00845 OCTAVE_INT_BIN_OP(+, add, octave_int<T>)
00846 OCTAVE_INT_BIN_OP(-, sub, octave_int<T>)
00847 OCTAVE_INT_BIN_OP(*, mul, octave_int<T>)
00848 OCTAVE_INT_BIN_OP(/, div, octave_int<T>)
00849 OCTAVE_INT_BIN_OP(<<, lshift, int)
00850 OCTAVE_INT_BIN_OP(>>, rshift, int)
00851
00852 #undef OCTAVE_INT_BIN_OP
00853
00854 static octave_int<T> min (void) { return std::numeric_limits<T>::min (); }
00855 static octave_int<T> max (void) { return std::numeric_limits<T>::max (); }
00856
00857 static int nbits (void) { return std::numeric_limits<T>::digits; }
00858
00859 static int byte_size (void) { return sizeof(T); }
00860
00861 static const char *type_name ();
00862
00863
00864 static const octave_int zero, one;
00865
00866
00867
00868 void *mex_get_data (void) const { return const_cast<T *> (&ival); }
00869
00870 private:
00871
00872 T ival;
00873 };
00874
00875
00876
00877 template <class T>
00878 inline bool
00879 xisnan (const octave_int<T>&)
00880 { return false; }
00881
00882
00883
00884 template <class T>
00885 extern OCTAVE_API octave_int<T>
00886 pow (const octave_int<T>&, const octave_int<T>&);
00887
00888 template <class T>
00889 extern OCTAVE_API octave_int<T>
00890 pow (const double& a, const octave_int<T>& b);
00891
00892 template <class T>
00893 extern OCTAVE_API octave_int<T>
00894 pow (const octave_int<T>& a, const double& b);
00895
00896 template <class T>
00897 extern OCTAVE_API octave_int<T>
00898 powf (const float& a, const octave_int<T>& b);
00899
00900 template <class T>
00901 extern OCTAVE_API octave_int<T>
00902 powf (const octave_int<T>& a, const float& b);
00903
00904
00905
00906 #define OCTAVE_INT_CMP_OP(OP, NAME) \
00907 template<class T1, class T2> \
00908 inline bool \
00909 operator OP (const octave_int<T1>& x, const octave_int<T2>& y) \
00910 { return octave_int_cmp_op::op<octave_int_cmp_op::NAME, T1, T2> \
00911 (x.value (), y.value ()); }
00912
00913 OCTAVE_INT_CMP_OP (<, lt)
00914 OCTAVE_INT_CMP_OP (<=, le)
00915 OCTAVE_INT_CMP_OP (>, gt)
00916 OCTAVE_INT_CMP_OP (>=, ge)
00917 OCTAVE_INT_CMP_OP (==, eq)
00918 OCTAVE_INT_CMP_OP (!=, ne)
00919
00920 #undef OCTAVE_INT_CMP_OP
00921
00922 template <class T>
00923 inline std::ostream&
00924 operator << (std::ostream& os, const octave_int<T>& ival)
00925 {
00926 os << ival.value ();
00927 return os;
00928 }
00929
00930 template <class T>
00931 inline std::istream&
00932 operator >> (std::istream& is, octave_int<T>& ival)
00933 {
00934 T tmp = 0;
00935 is >> tmp;
00936 ival = tmp;
00937 return is;
00938 }
00939
00940
00941
00942 #define OCTAVE_INT_BITCMP_OP(OP) \
00943 template <class T> \
00944 octave_int<T> \
00945 operator OP (const octave_int<T>& x, const octave_int<T>& y) \
00946 { return x.value () OP y.value (); }
00947
00948 OCTAVE_INT_BITCMP_OP (&)
00949 OCTAVE_INT_BITCMP_OP (|)
00950 OCTAVE_INT_BITCMP_OP (^)
00951
00952 #undef OCTAVE_INT_BITCMP_OP
00953
00954
00955 template <class T>
00956 octave_int<T>
00957 bitshift (const octave_int<T>& a, int n,
00958 const octave_int<T>& mask = std::numeric_limits<T>::max ())
00959 {
00960 if (n > 0)
00961 return (a << n) & mask;
00962 else if (n < 0)
00963 return (a >> -n) & mask;
00964 else
00965 return a & mask;
00966 }
00967
00968 typedef octave_int<int8_t> octave_int8;
00969 typedef octave_int<int16_t> octave_int16;
00970 typedef octave_int<int32_t> octave_int32;
00971 typedef octave_int<int64_t> octave_int64;
00972
00973 typedef octave_int<uint8_t> octave_uint8;
00974 typedef octave_int<uint16_t> octave_uint16;
00975 typedef octave_int<uint32_t> octave_uint32;
00976 typedef octave_int<uint64_t> octave_uint64;
00977
00978 #define OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
00979 template <class T> \
00980 inline octave_int<T> \
00981 operator OP (const octave_int<T>& x, const double& y) \
00982 { return octave_int<T> (static_cast<double> (x) OP y); } \
00983 template <class T> \
00984 inline octave_int<T> \
00985 operator OP (const double& x, const octave_int<T>& y) \
00986 { return octave_int<T> (x OP static_cast<double> (y)); } \
00987
00988 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
00989
00990 #define OCTAVE_INT_DOUBLE_BIN_OP(OP) \
00991 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
00992 template <> \
00993 inline octave_int64 \
00994 operator OP (const double& x, const octave_int64& y) \
00995 { return octave_int64 (x OP static_cast<long double> (y.value ())); } \
00996 template <> \
00997 inline octave_uint64 \
00998 operator OP (const double& x, const octave_uint64& y) \
00999 { return octave_uint64 (x OP static_cast<long double> (y.value ())); } \
01000 template <> \
01001 inline octave_int64 \
01002 operator OP (const octave_int64& x, const double& y) \
01003 { return octave_int64 (static_cast<long double> (x.value ()) OP y); } \
01004 template <> \
01005 inline octave_uint64 \
01006 operator OP (const octave_uint64& x, const double& y) \
01007 { return octave_uint64 (static_cast<long double> (x.value ()) OP y); }
01008
01009 #else
01010
01011 #define OCTAVE_INT_DOUBLE_BIN_OP(OP) \
01012 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
01013 template <> \
01014 OCTAVE_API octave_int64 \
01015 operator OP (const double&, const octave_int64&); \
01016 template <> \
01017 OCTAVE_API octave_uint64 \
01018 operator OP (const double&, const octave_uint64&); \
01019 template <> \
01020 OCTAVE_API octave_int64 \
01021 operator OP (const octave_int64&, const double&); \
01022 template <> \
01023 OCTAVE_API octave_uint64 \
01024 operator OP (const octave_uint64&, const double&);
01025
01026 #endif
01027
01028 OCTAVE_INT_DOUBLE_BIN_OP (+)
01029 OCTAVE_INT_DOUBLE_BIN_OP (-)
01030 OCTAVE_INT_DOUBLE_BIN_OP (*)
01031 OCTAVE_INT_DOUBLE_BIN_OP (/)
01032
01033 #undef OCTAVE_INT_DOUBLE_BIN_OP0
01034 #undef OCTAVE_INT_DOUBLE_BIN_OP
01035
01036 #define OCTAVE_INT_DOUBLE_CMP_OP(OP,NAME) \
01037 template <class T> \
01038 inline bool \
01039 operator OP (const octave_int<T>& x, const double& y) \
01040 { return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x.value (), y); } \
01041 template <class T> \
01042 inline bool \
01043 operator OP (const double& x, const octave_int<T>& y) \
01044 { return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x, y.value ()); }
01045
01046 OCTAVE_INT_DOUBLE_CMP_OP (<, lt)
01047 OCTAVE_INT_DOUBLE_CMP_OP (<=, le)
01048 OCTAVE_INT_DOUBLE_CMP_OP (>=, ge)
01049 OCTAVE_INT_DOUBLE_CMP_OP (>, gt)
01050 OCTAVE_INT_DOUBLE_CMP_OP (==, eq)
01051 OCTAVE_INT_DOUBLE_CMP_OP (!=, ne)
01052
01053 #undef OCTAVE_INT_DOUBLE_CMP_OP
01054
01055
01056
01057 #define OCTAVE_INT_FLOAT_BIN_OP(OP) \
01058 template <class T> \
01059 inline octave_int<T> \
01060 operator OP (const octave_int<T>& x, float y) \
01061 { return x OP static_cast<double> (y); } \
01062 template <class T> \
01063 inline octave_int<T> \
01064 operator OP (float x, const octave_int<T>& y) \
01065 { return static_cast<double> (x) OP y; }
01066
01067 OCTAVE_INT_FLOAT_BIN_OP (+)
01068 OCTAVE_INT_FLOAT_BIN_OP (-)
01069 OCTAVE_INT_FLOAT_BIN_OP (*)
01070 OCTAVE_INT_FLOAT_BIN_OP (/)
01071
01072 #undef OCTAVE_INT_FLOAT_BIN_OP
01073
01074 #define OCTAVE_INT_FLOAT_CMP_OP(OP) \
01075 template <class T> \
01076 inline bool \
01077 operator OP (const octave_int<T>& x, const float& y) \
01078 { return x OP static_cast<double> (y); } \
01079 template <class T> \
01080 bool \
01081 operator OP (const float& x, const octave_int<T>& y) \
01082 { return static_cast<double> (x) OP y; }
01083
01084 OCTAVE_INT_FLOAT_CMP_OP (<)
01085 OCTAVE_INT_FLOAT_CMP_OP (<=)
01086 OCTAVE_INT_FLOAT_CMP_OP (>=)
01087 OCTAVE_INT_FLOAT_CMP_OP (>)
01088 OCTAVE_INT_FLOAT_CMP_OP (==)
01089 OCTAVE_INT_FLOAT_CMP_OP (!=)
01090
01091 #undef OCTAVE_INT_FLOAT_CMP_OP
01092
01093 #endif
01094
01095
01096
01097
01098
01099