1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: wx/longlong.h 3 // Purpose: declaration of wxLongLong class - best implementation of a 64 4 // bit integer for the current platform. 5 // Author: Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin 6 // Modified by: 7 // Created: 10.02.99 8 // RCS-ID: $Id: longlong.h 61872 2009-09-09 22:37:05Z VZ $ 9 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 10 // Licence: wxWindows licence 11 ///////////////////////////////////////////////////////////////////////////// 12 13 #ifndef _WX_LONGLONG_H 14 #define _WX_LONGLONG_H 15 16 #include "wx/defs.h" 17 18 #if wxUSE_LONGLONG 19 20 #include "wx/string.h" 21 22 #include <limits.h> // for LONG_MAX 23 24 // define this to compile wxLongLongWx in "test" mode: the results of all 25 // calculations will be compared with the real results taken from 26 // wxLongLongNative -- this is extremely useful to find the bugs in 27 // wxLongLongWx class! 28 29 // #define wxLONGLONG_TEST_MODE 30 31 #ifdef wxLONGLONG_TEST_MODE 32 #define wxUSE_LONGLONG_WX 1 33 #define wxUSE_LONGLONG_NATIVE 1 34 #endif // wxLONGLONG_TEST_MODE 35 36 // ---------------------------------------------------------------------------- 37 // decide upon which class we will use 38 // ---------------------------------------------------------------------------- 39 40 #ifndef wxLongLong_t 41 // both warning and pragma warning are not portable, but at least an 42 // unknown pragma should never be an error -- except that, actually, some 43 // broken compilers don't like it, so we have to disable it in this case 44 // <sigh> 45 #ifdef __GNUC__ 46 #warning "Your compiler does not appear to support 64 bit "\ 47 "integers, using emulation class instead.\n" \ 48 "Please report your compiler version to " \ 49 "wx-dev@lists.wxwidgets.org!" 50 #elif !(defined(__WATCOMC__) || defined(__VISAGECPP__)) 51 #pragma warning "Your compiler does not appear to support 64 bit "\ 52 "integers, using emulation class instead.\n" \ 53 "Please report your compiler version to " \ 54 "wx-dev@lists.wxwidgets.org!" 55 #endif 56 57 #define wxUSE_LONGLONG_WX 1 58 #endif // compiler 59 60 // the user may predefine wxUSE_LONGLONG_NATIVE and/or wxUSE_LONGLONG_NATIVE 61 // to disable automatic testing (useful for the test program which defines 62 // both classes) but by default we only use one class 63 #if (defined(wxUSE_LONGLONG_WX) && wxUSE_LONGLONG_WX) || !defined(wxLongLong_t) 64 // don't use both classes unless wxUSE_LONGLONG_NATIVE was explicitly set: 65 // this is useful in test programs and only there 66 #ifndef wxUSE_LONGLONG_NATIVE 67 #define wxUSE_LONGLONG_NATIVE 0 68 #endif 69 70 class WXDLLIMPEXP_BASE wxLongLongWx; 71 class WXDLLIMPEXP_BASE wxULongLongWx; 72 #if defined(__VISUALC__) && !defined(__WIN32__) 73 #define wxLongLong wxLongLongWx 74 #define wxULongLong wxULongLongWx 75 #else 76 typedef wxLongLongWx wxLongLong; 77 typedef wxULongLongWx wxULongLong; 78 #endif 79 80 #else 81 // if nothing is defined, use native implementation by default, of course 82 #ifndef wxUSE_LONGLONG_NATIVE 83 #define wxUSE_LONGLONG_NATIVE 1 84 #endif 85 #endif 86 87 #ifndef wxUSE_LONGLONG_WX 88 #define wxUSE_LONGLONG_WX 0 89 class WXDLLIMPEXP_FWD_BASE wxLongLongNative; 90 class WXDLLIMPEXP_FWD_BASE wxULongLongNative; 91 typedef wxLongLongNative wxLongLong; 92 typedef wxULongLongNative wxULongLong; 93 #endif 94 95 // NB: if both wxUSE_LONGLONG_WX and NATIVE are defined, the user code should 96 // typedef wxLongLong as it wants, we don't do it 97 98 // ---------------------------------------------------------------------------- 99 // choose the appropriate class 100 // ---------------------------------------------------------------------------- 101 102 // we use iostream for wxLongLong output 103 #include "wx/iosfwrap.h" 104 105 #if wxUSE_LONGLONG_NATIVE 106 107 class WXDLLIMPEXP_BASE wxLongLongNative 108 { 109 public: 110 // ctors 111 // default ctor initializes to 0 wxLongLongNative()112 wxLongLongNative() : m_ll(0) { } 113 // from long long wxLongLongNative(wxLongLong_t ll)114 wxLongLongNative(wxLongLong_t ll) : m_ll(ll) { } 115 // from 2 longs wxLongLongNative(wxInt32 hi,wxUint32 lo)116 wxLongLongNative(wxInt32 hi, wxUint32 lo) 117 { 118 // cast to wxLongLong_t first to avoid precision loss! 119 m_ll = ((wxLongLong_t) hi) << 32; 120 m_ll |= (wxLongLong_t) lo; 121 } 122 #if wxUSE_LONGLONG_WX 123 wxLongLongNative(wxLongLongWx ll); 124 #endif 125 126 // default copy ctor is ok 127 128 // no dtor 129 130 // assignment operators 131 // from native 64 bit integer 132 #ifndef wxLongLongIsLong 133 wxLongLongNative& operator=(wxLongLong_t ll) 134 { m_ll = ll; return *this; } 135 wxLongLongNative& operator=(wxULongLong_t ll) 136 { m_ll = ll; return *this; } 137 #endif // !wxLongLongNative 138 wxLongLongNative& operator=(const wxULongLongNative &ll); 139 wxLongLongNative& operator=(int l) 140 { m_ll = l; return *this; } 141 wxLongLongNative& operator=(long l) 142 { m_ll = l; return *this; } 143 wxLongLongNative& operator=(unsigned int l) 144 { m_ll = l; return *this; } 145 wxLongLongNative& operator=(unsigned long l) 146 { m_ll = l; return *this; } 147 #if wxUSE_LONGLONG_WX 148 wxLongLongNative& operator=(wxLongLongWx ll); 149 wxLongLongNative& operator=(const class wxULongLongWx &ll); 150 #endif 151 152 153 // from double: this one has an explicit name because otherwise we 154 // would have ambiguity with "ll = int" and also because we don't want 155 // to have implicit conversions between doubles and wxLongLongs Assign(double d)156 wxLongLongNative& Assign(double d) 157 { m_ll = (wxLongLong_t)d; return *this; } 158 159 // assignment operators from wxLongLongNative is ok 160 161 // accessors 162 // get high part GetHi()163 wxInt32 GetHi() const 164 { return wx_truncate_cast(wxInt32, m_ll >> 32); } 165 // get low part GetLo()166 wxUint32 GetLo() const 167 { return wx_truncate_cast(wxUint32, m_ll); } 168 169 // get absolute value Abs()170 wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); } Abs()171 wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; } 172 173 // convert to native long long GetValue()174 wxLongLong_t GetValue() const { return m_ll; } 175 176 // convert to long with range checking in debug mode (only!) ToLong()177 long ToLong() const 178 { 179 wxASSERT_MSG( (m_ll >= LONG_MIN) && (m_ll <= LONG_MAX), 180 wxT("wxLongLong to long conversion loss of precision") ); 181 182 return wx_truncate_cast(long, m_ll); 183 } 184 185 // convert to double ToDouble()186 double ToDouble() const { return wx_truncate_cast(double, m_ll); } 187 188 // don't provide implicit conversion to wxLongLong_t or we will have an 189 // ambiguity for all arithmetic operations 190 //operator wxLongLong_t() const { return m_ll; } 191 192 // operations 193 // addition 194 wxLongLongNative operator+(const wxLongLongNative& ll) const 195 { return wxLongLongNative(m_ll + ll.m_ll); } 196 wxLongLongNative& operator+=(const wxLongLongNative& ll) 197 { m_ll += ll.m_ll; return *this; } 198 199 wxLongLongNative operator+(const wxLongLong_t ll) const 200 { return wxLongLongNative(m_ll + ll); } 201 wxLongLongNative& operator+=(const wxLongLong_t ll) 202 { m_ll += ll; return *this; } 203 204 // pre increment 205 wxLongLongNative& operator++() 206 { m_ll++; return *this; } 207 208 // post increment 209 wxLongLongNative operator++(int) 210 { wxLongLongNative value(*this); m_ll++; return value; } 211 212 // negation operator 213 wxLongLongNative operator-() const 214 { return wxLongLongNative(-m_ll); } Negate()215 wxLongLongNative& Negate() { m_ll = -m_ll; return *this; } 216 217 // subtraction 218 wxLongLongNative operator-(const wxLongLongNative& ll) const 219 { return wxLongLongNative(m_ll - ll.m_ll); } 220 wxLongLongNative& operator-=(const wxLongLongNative& ll) 221 { m_ll -= ll.m_ll; return *this; } 222 223 wxLongLongNative operator-(const wxLongLong_t ll) const 224 { return wxLongLongNative(m_ll - ll); } 225 wxLongLongNative& operator-=(const wxLongLong_t ll) 226 { m_ll -= ll; return *this; } 227 228 // pre decrement 229 wxLongLongNative& operator--() 230 { m_ll--; return *this; } 231 232 // post decrement 233 wxLongLongNative operator--(int) 234 { wxLongLongNative value(*this); m_ll--; return value; } 235 236 // shifts 237 // left shift 238 wxLongLongNative operator<<(int shift) const 239 { return wxLongLongNative(m_ll << shift); } 240 wxLongLongNative& operator<<=(int shift) 241 { m_ll <<= shift; return *this; } 242 243 // right shift 244 wxLongLongNative operator>>(int shift) const 245 { return wxLongLongNative(m_ll >> shift); } 246 wxLongLongNative& operator>>=(int shift) 247 { m_ll >>= shift; return *this; } 248 249 // bitwise operators 250 wxLongLongNative operator&(const wxLongLongNative& ll) const 251 { return wxLongLongNative(m_ll & ll.m_ll); } 252 wxLongLongNative& operator&=(const wxLongLongNative& ll) 253 { m_ll &= ll.m_ll; return *this; } 254 255 wxLongLongNative operator|(const wxLongLongNative& ll) const 256 { return wxLongLongNative(m_ll | ll.m_ll); } 257 wxLongLongNative& operator|=(const wxLongLongNative& ll) 258 { m_ll |= ll.m_ll; return *this; } 259 260 wxLongLongNative operator^(const wxLongLongNative& ll) const 261 { return wxLongLongNative(m_ll ^ ll.m_ll); } 262 wxLongLongNative& operator^=(const wxLongLongNative& ll) 263 { m_ll ^= ll.m_ll; return *this; } 264 265 // multiplication/division 266 wxLongLongNative operator*(const wxLongLongNative& ll) const 267 { return wxLongLongNative(m_ll * ll.m_ll); } 268 wxLongLongNative operator*(long l) const 269 { return wxLongLongNative(m_ll * l); } 270 wxLongLongNative& operator*=(const wxLongLongNative& ll) 271 { m_ll *= ll.m_ll; return *this; } 272 wxLongLongNative& operator*=(long l) 273 { m_ll *= l; return *this; } 274 275 wxLongLongNative operator/(const wxLongLongNative& ll) const 276 { return wxLongLongNative(m_ll / ll.m_ll); } 277 wxLongLongNative operator/(long l) const 278 { return wxLongLongNative(m_ll / l); } 279 wxLongLongNative& operator/=(const wxLongLongNative& ll) 280 { m_ll /= ll.m_ll; return *this; } 281 wxLongLongNative& operator/=(long l) 282 { m_ll /= l; return *this; } 283 284 wxLongLongNative operator%(const wxLongLongNative& ll) const 285 { return wxLongLongNative(m_ll % ll.m_ll); } 286 wxLongLongNative operator%(long l) const 287 { return wxLongLongNative(m_ll % l); } 288 289 // comparison 290 bool operator==(const wxLongLongNative& ll) const 291 { return m_ll == ll.m_ll; } 292 bool operator==(long l) const 293 { return m_ll == l; } 294 bool operator!=(const wxLongLongNative& ll) const 295 { return m_ll != ll.m_ll; } 296 bool operator!=(long l) const 297 { return m_ll != l; } 298 bool operator<(const wxLongLongNative& ll) const 299 { return m_ll < ll.m_ll; } 300 bool operator<(long l) const 301 { return m_ll < l; } 302 bool operator>(const wxLongLongNative& ll) const 303 { return m_ll > ll.m_ll; } 304 bool operator>(long l) const 305 { return m_ll > l; } 306 bool operator<=(const wxLongLongNative& ll) const 307 { return m_ll <= ll.m_ll; } 308 bool operator<=(long l) const 309 { return m_ll <= l; } 310 bool operator>=(const wxLongLongNative& ll) const 311 { return m_ll >= ll.m_ll; } 312 bool operator>=(long l) const 313 { return m_ll >= l; } 314 315 // miscellaneous 316 317 // return the string representation of this number 318 wxString ToString() const; 319 320 // conversion to byte array: returns a pointer to static buffer! 321 void *asArray() const; 322 323 #if wxUSE_STD_IOSTREAM 324 // input/output 325 friend WXDLLIMPEXP_BASE 326 wxSTD ostream& operator<<(wxSTD ostream&, const wxLongLongNative&); 327 #endif 328 329 friend WXDLLIMPEXP_BASE 330 wxString& operator<<(wxString&, const wxLongLongNative&); 331 332 #if wxUSE_STREAMS 333 friend WXDLLIMPEXP_BASE 334 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLongNative&); 335 friend WXDLLIMPEXP_BASE 336 class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLongNative&); 337 #endif 338 339 private: 340 wxLongLong_t m_ll; 341 }; 342 343 344 class WXDLLIMPEXP_BASE wxULongLongNative 345 { 346 public: 347 // ctors 348 // default ctor initializes to 0 wxULongLongNative()349 wxULongLongNative() : m_ll(0) { } 350 // from long long wxULongLongNative(wxULongLong_t ll)351 wxULongLongNative(wxULongLong_t ll) : m_ll(ll) { } 352 // from 2 longs wxULongLongNative(wxUint32 hi,wxUint32 lo)353 wxULongLongNative(wxUint32 hi, wxUint32 lo) : m_ll(0) 354 { 355 // cast to wxLongLong_t first to avoid precision loss! 356 m_ll = ((wxULongLong_t) hi) << 32; 357 m_ll |= (wxULongLong_t) lo; 358 } 359 360 #if wxUSE_LONGLONG_WX 361 wxULongLongNative(const class wxULongLongWx &ll); 362 #endif 363 364 // default copy ctor is ok 365 366 // no dtor 367 368 // assignment operators 369 // from native 64 bit integer 370 #ifndef wxLongLongIsLong 371 wxULongLongNative& operator=(wxULongLong_t ll) 372 { m_ll = ll; return *this; } 373 wxULongLongNative& operator=(wxLongLong_t ll) 374 { m_ll = ll; return *this; } 375 #endif // !wxLongLongNative 376 wxULongLongNative& operator=(int l) 377 { m_ll = l; return *this; } 378 wxULongLongNative& operator=(long l) 379 { m_ll = l; return *this; } 380 wxULongLongNative& operator=(unsigned int l) 381 { m_ll = l; return *this; } 382 wxULongLongNative& operator=(unsigned long l) 383 { m_ll = l; return *this; } 384 wxULongLongNative& operator=(const wxLongLongNative &ll) 385 { m_ll = ll.GetValue(); return *this; } 386 #if wxUSE_LONGLONG_WX 387 wxULongLongNative& operator=(wxLongLongWx ll); 388 wxULongLongNative& operator=(const class wxULongLongWx &ll); 389 #endif 390 391 // assignment operators from wxULongLongNative is ok 392 393 // accessors 394 // get high part GetHi()395 wxUint32 GetHi() const 396 { return wx_truncate_cast(wxUint32, m_ll >> 32); } 397 // get low part GetLo()398 wxUint32 GetLo() const 399 { return wx_truncate_cast(wxUint32, m_ll); } 400 401 // convert to native ulong long GetValue()402 wxULongLong_t GetValue() const { return m_ll; } 403 404 // convert to ulong with range checking in debug mode (only!) ToULong()405 unsigned long ToULong() const 406 { 407 wxASSERT_MSG( m_ll <= LONG_MAX, 408 wxT("wxULongLong to long conversion loss of precision") ); 409 410 return wx_truncate_cast(unsigned long, m_ll); 411 } 412 413 // convert to double 414 #ifdef _MSC_VER ToDouble()415 double ToDouble() const { return wx_truncate_cast(double, (__int64) m_ll); } 416 #else ToDouble()417 double ToDouble() const { return wx_truncate_cast(double, m_ll); } 418 #endif 419 420 // operations 421 // addition 422 wxULongLongNative operator+(const wxULongLongNative& ll) const 423 { return wxULongLongNative(m_ll + ll.m_ll); } 424 wxULongLongNative& operator+=(const wxULongLongNative& ll) 425 { m_ll += ll.m_ll; return *this; } 426 427 wxULongLongNative operator+(const wxULongLong_t ll) const 428 { return wxULongLongNative(m_ll + ll); } 429 wxULongLongNative& operator+=(const wxULongLong_t ll) 430 { m_ll += ll; return *this; } 431 432 // pre increment 433 wxULongLongNative& operator++() 434 { m_ll++; return *this; } 435 436 // post increment 437 wxULongLongNative operator++(int) 438 { wxULongLongNative value(*this); m_ll++; return value; } 439 440 // subtraction 441 wxULongLongNative operator-(const wxULongLongNative& ll) const 442 { return wxULongLongNative(m_ll - ll.m_ll); } 443 wxULongLongNative& operator-=(const wxULongLongNative& ll) 444 { m_ll -= ll.m_ll; return *this; } 445 446 wxULongLongNative operator-(const wxULongLong_t ll) const 447 { return wxULongLongNative(m_ll - ll); } 448 wxULongLongNative& operator-=(const wxULongLong_t ll) 449 { m_ll -= ll; return *this; } 450 451 // pre decrement 452 wxULongLongNative& operator--() 453 { m_ll--; return *this; } 454 455 // post decrement 456 wxULongLongNative operator--(int) 457 { wxULongLongNative value(*this); m_ll--; return value; } 458 459 // shifts 460 // left shift 461 wxULongLongNative operator<<(int shift) const 462 { return wxULongLongNative(m_ll << shift); } 463 wxULongLongNative& operator<<=(int shift) 464 { m_ll <<= shift; return *this; } 465 466 // right shift 467 wxULongLongNative operator>>(int shift) const 468 { return wxULongLongNative(m_ll >> shift); } 469 wxULongLongNative& operator>>=(int shift) 470 { m_ll >>= shift; return *this; } 471 472 // bitwise operators 473 wxULongLongNative operator&(const wxULongLongNative& ll) const 474 { return wxULongLongNative(m_ll & ll.m_ll); } 475 wxULongLongNative& operator&=(const wxULongLongNative& ll) 476 { m_ll &= ll.m_ll; return *this; } 477 478 wxULongLongNative operator|(const wxULongLongNative& ll) const 479 { return wxULongLongNative(m_ll | ll.m_ll); } 480 wxULongLongNative& operator|=(const wxULongLongNative& ll) 481 { m_ll |= ll.m_ll; return *this; } 482 483 wxULongLongNative operator^(const wxULongLongNative& ll) const 484 { return wxULongLongNative(m_ll ^ ll.m_ll); } 485 wxULongLongNative& operator^=(const wxULongLongNative& ll) 486 { m_ll ^= ll.m_ll; return *this; } 487 488 // multiplication/division 489 wxULongLongNative operator*(const wxULongLongNative& ll) const 490 { return wxULongLongNative(m_ll * ll.m_ll); } 491 wxULongLongNative operator*(unsigned long l) const 492 { return wxULongLongNative(m_ll * l); } 493 wxULongLongNative& operator*=(const wxULongLongNative& ll) 494 { m_ll *= ll.m_ll; return *this; } 495 wxULongLongNative& operator*=(unsigned long l) 496 { m_ll *= l; return *this; } 497 498 wxULongLongNative operator/(const wxULongLongNative& ll) const 499 { return wxULongLongNative(m_ll / ll.m_ll); } 500 wxULongLongNative operator/(unsigned long l) const 501 { return wxULongLongNative(m_ll / l); } 502 wxULongLongNative& operator/=(const wxULongLongNative& ll) 503 { m_ll /= ll.m_ll; return *this; } 504 wxULongLongNative& operator/=(unsigned long l) 505 { m_ll /= l; return *this; } 506 507 wxULongLongNative operator%(const wxULongLongNative& ll) const 508 { return wxULongLongNative(m_ll % ll.m_ll); } 509 wxULongLongNative operator%(unsigned long l) const 510 { return wxULongLongNative(m_ll % l); } 511 512 // comparison 513 bool operator==(const wxULongLongNative& ll) const 514 { return m_ll == ll.m_ll; } 515 bool operator==(unsigned long l) const 516 { return m_ll == l; } 517 bool operator!=(const wxULongLongNative& ll) const 518 { return m_ll != ll.m_ll; } 519 bool operator!=(unsigned long l) const 520 { return m_ll != l; } 521 bool operator<(const wxULongLongNative& ll) const 522 { return m_ll < ll.m_ll; } 523 bool operator<(unsigned long l) const 524 { return m_ll < l; } 525 bool operator>(const wxULongLongNative& ll) const 526 { return m_ll > ll.m_ll; } 527 bool operator>(unsigned long l) const 528 { return m_ll > l; } 529 bool operator<=(const wxULongLongNative& ll) const 530 { return m_ll <= ll.m_ll; } 531 bool operator<=(unsigned long l) const 532 { return m_ll <= l; } 533 bool operator>=(const wxULongLongNative& ll) const 534 { return m_ll >= ll.m_ll; } 535 bool operator>=(unsigned long l) const 536 { return m_ll >= l; } 537 538 // miscellaneous 539 540 // return the string representation of this number 541 wxString ToString() const; 542 543 // conversion to byte array: returns a pointer to static buffer! 544 void *asArray() const; 545 546 #if wxUSE_STD_IOSTREAM 547 // input/output 548 friend WXDLLIMPEXP_BASE 549 wxSTD ostream& operator<<(wxSTD ostream&, const wxULongLongNative&); 550 #endif 551 552 friend WXDLLIMPEXP_BASE 553 wxString& operator<<(wxString&, const wxULongLongNative&); 554 555 #if wxUSE_STREAMS 556 friend WXDLLIMPEXP_BASE 557 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLongNative&); 558 friend WXDLLIMPEXP_BASE 559 class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLongNative&); 560 #endif 561 562 private: 563 wxULongLong_t m_ll; 564 }; 565 566 inline 567 wxLongLongNative& wxLongLongNative::operator=(const wxULongLongNative &ll) 568 { 569 m_ll = ll.GetValue(); 570 return *this; 571 } 572 573 #endif // wxUSE_LONGLONG_NATIVE 574 575 #if wxUSE_LONGLONG_WX 576 577 class WXDLLIMPEXP_BASE wxLongLongWx 578 { 579 public: 580 // ctors 581 // default ctor initializes to 0 wxLongLongWx()582 wxLongLongWx() 583 { 584 m_lo = m_hi = 0; 585 586 #ifdef wxLONGLONG_TEST_MODE 587 m_ll = 0; 588 589 Check(); 590 #endif // wxLONGLONG_TEST_MODE 591 } 592 // from long wxLongLongWx(long l)593 wxLongLongWx(long l) { *this = l; } 594 // from 2 longs wxLongLongWx(long hi,unsigned long lo)595 wxLongLongWx(long hi, unsigned long lo) 596 { 597 m_hi = hi; 598 m_lo = lo; 599 600 #ifdef wxLONGLONG_TEST_MODE 601 m_ll = hi; 602 m_ll <<= 32; 603 m_ll |= lo; 604 605 Check(); 606 #endif // wxLONGLONG_TEST_MODE 607 } 608 609 // default copy ctor is ok in both cases 610 611 // no dtor 612 613 // assignment operators 614 // from long 615 wxLongLongWx& operator=(long l) 616 { 617 m_lo = l; 618 m_hi = (l < 0 ? -1l : 0l); 619 620 #ifdef wxLONGLONG_TEST_MODE 621 m_ll = l; 622 623 Check(); 624 #endif // wxLONGLONG_TEST_MODE 625 626 return *this; 627 } 628 // from int 629 wxLongLongWx& operator=(int l) 630 { 631 return operator=((long)l); 632 } 633 634 wxLongLongWx& operator=(unsigned long l) 635 { 636 m_lo = l; 637 m_hi = 0; 638 639 #ifdef wxLONGLONG_TEST_MODE 640 m_ll = l; 641 642 Check(); 643 #endif // wxLONGLONG_TEST_MODE 644 645 return *this; 646 } 647 648 wxLongLongWx& operator=(unsigned int l) 649 { 650 return operator=((unsigned long)l); 651 } 652 653 wxLongLongWx& operator=(const class wxULongLongWx &ll); 654 655 // from double 656 wxLongLongWx& Assign(double d); 657 // can't have assignment operator from 2 longs 658 659 // accessors 660 // get high part GetHi()661 long GetHi() const { return m_hi; } 662 // get low part GetLo()663 unsigned long GetLo() const { return m_lo; } 664 665 // get absolute value Abs()666 wxLongLongWx Abs() const { return wxLongLongWx(*this).Abs(); } Abs()667 wxLongLongWx& Abs() 668 { 669 if ( m_hi < 0 ) 670 m_hi = -m_hi; 671 672 #ifdef wxLONGLONG_TEST_MODE 673 if ( m_ll < 0 ) 674 m_ll = -m_ll; 675 676 Check(); 677 #endif // wxLONGLONG_TEST_MODE 678 679 return *this; 680 } 681 682 // convert to long with range checking in debug mode (only!) ToLong()683 long ToLong() const 684 { 685 wxASSERT_MSG( (m_hi == 0l) || (m_hi == -1l), 686 wxT("wxLongLong to long conversion loss of precision") ); 687 688 return (long)m_lo; 689 } 690 691 // convert to double 692 double ToDouble() const; 693 694 // operations 695 // addition 696 wxLongLongWx operator+(const wxLongLongWx& ll) const; 697 wxLongLongWx& operator+=(const wxLongLongWx& ll); 698 wxLongLongWx operator+(long l) const; 699 wxLongLongWx& operator+=(long l); 700 701 // pre increment operator 702 wxLongLongWx& operator++(); 703 704 // post increment operator 705 wxLongLongWx& operator++(int) { return ++(*this); } 706 707 // negation operator 708 wxLongLongWx operator-() const; 709 wxLongLongWx& Negate(); 710 711 // subraction 712 wxLongLongWx operator-(const wxLongLongWx& ll) const; 713 wxLongLongWx& operator-=(const wxLongLongWx& ll); 714 715 // pre decrement operator 716 wxLongLongWx& operator--(); 717 718 // post decrement operator 719 wxLongLongWx& operator--(int) { return --(*this); } 720 721 // shifts 722 // left shift 723 wxLongLongWx operator<<(int shift) const; 724 wxLongLongWx& operator<<=(int shift); 725 726 // right shift 727 wxLongLongWx operator>>(int shift) const; 728 wxLongLongWx& operator>>=(int shift); 729 730 // bitwise operators 731 wxLongLongWx operator&(const wxLongLongWx& ll) const; 732 wxLongLongWx& operator&=(const wxLongLongWx& ll); 733 wxLongLongWx operator|(const wxLongLongWx& ll) const; 734 wxLongLongWx& operator|=(const wxLongLongWx& ll); 735 wxLongLongWx operator^(const wxLongLongWx& ll) const; 736 wxLongLongWx& operator^=(const wxLongLongWx& ll); 737 wxLongLongWx operator~() const; 738 739 // comparison 740 bool operator==(const wxLongLongWx& ll) const 741 { return m_lo == ll.m_lo && m_hi == ll.m_hi; } 742 #if wxUSE_LONGLONG_NATIVE 743 bool operator==(const wxLongLongNative& ll) const 744 { return m_lo == ll.GetLo() && m_hi == ll.GetHi(); } 745 #endif 746 bool operator!=(const wxLongLongWx& ll) const 747 { return !(*this == ll); } 748 bool operator<(const wxLongLongWx& ll) const; 749 bool operator>(const wxLongLongWx& ll) const; 750 bool operator<=(const wxLongLongWx& ll) const 751 { return *this < ll || *this == ll; } 752 bool operator>=(const wxLongLongWx& ll) const 753 { return *this > ll || *this == ll; } 754 755 bool operator<(long l) const { return *this < wxLongLongWx(l); } 756 bool operator>(long l) const { return *this > wxLongLongWx(l); } 757 bool operator==(long l) const 758 { 759 return l >= 0 ? (m_hi == 0 && m_lo == (unsigned long)l) 760 : (m_hi == -1 && m_lo == (unsigned long)l); 761 } 762 763 bool operator<=(long l) const { return *this < l || *this == l; } 764 bool operator>=(long l) const { return *this > l || *this == l; } 765 766 // multiplication 767 wxLongLongWx operator*(const wxLongLongWx& ll) const; 768 wxLongLongWx& operator*=(const wxLongLongWx& ll); 769 770 // division 771 wxLongLongWx operator/(const wxLongLongWx& ll) const; 772 wxLongLongWx& operator/=(const wxLongLongWx& ll); 773 774 wxLongLongWx operator%(const wxLongLongWx& ll) const; 775 776 void Divide(const wxLongLongWx& divisor, 777 wxLongLongWx& quotient, 778 wxLongLongWx& remainder) const; 779 780 // input/output 781 782 // return the string representation of this number 783 wxString ToString() const; 784 785 void *asArray() const; 786 787 #if wxUSE_STD_IOSTREAM 788 friend WXDLLIMPEXP_BASE 789 wxSTD ostream& operator<<(wxSTD ostream&, const wxLongLongWx&); 790 #endif // wxUSE_STD_IOSTREAM 791 792 friend WXDLLIMPEXP_BASE 793 wxString& operator<<(wxString&, const wxLongLongWx&); 794 795 #if wxUSE_STREAMS 796 friend WXDLLIMPEXP_BASE 797 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLongWx&); 798 friend WXDLLIMPEXP_BASE 799 class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLongWx&); 800 #endif 801 802 private: 803 // long is at least 32 bits, so represent our 64bit number as 2 longs 804 805 long m_hi; // signed bit is in the high part 806 unsigned long m_lo; 807 808 #ifdef wxLONGLONG_TEST_MODE Check()809 void Check() 810 { 811 wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo ); 812 } 813 814 wxLongLong_t m_ll; 815 #endif // wxLONGLONG_TEST_MODE 816 }; 817 818 819 class WXDLLIMPEXP_BASE wxULongLongWx 820 { 821 public: 822 // ctors 823 // default ctor initializes to 0 wxULongLongWx()824 wxULongLongWx() 825 { 826 m_lo = m_hi = 0; 827 828 #ifdef wxLONGLONG_TEST_MODE 829 m_ll = 0; 830 831 Check(); 832 #endif // wxLONGLONG_TEST_MODE 833 } 834 // from ulong wxULongLongWx(unsigned long l)835 wxULongLongWx(unsigned long l) { *this = l; } 836 // from 2 ulongs wxULongLongWx(unsigned long hi,unsigned long lo)837 wxULongLongWx(unsigned long hi, unsigned long lo) 838 { 839 m_hi = hi; 840 m_lo = lo; 841 842 #ifdef wxLONGLONG_TEST_MODE 843 m_ll = hi; 844 m_ll <<= 32; 845 m_ll |= lo; 846 847 Check(); 848 #endif // wxLONGLONG_TEST_MODE 849 } 850 851 // from signed to unsigned wxULongLongWx(wxLongLongWx ll)852 wxULongLongWx(wxLongLongWx ll) 853 { 854 wxASSERT(ll.GetHi() >= 0); 855 m_hi = (unsigned long)ll.GetHi(); 856 m_lo = ll.GetLo(); 857 } 858 859 // default copy ctor is ok in both cases 860 861 // no dtor 862 863 // assignment operators 864 // from long 865 wxULongLongWx& operator=(unsigned long l) 866 { 867 m_lo = l; 868 m_hi = 0; 869 870 #ifdef wxLONGLONG_TEST_MODE 871 m_ll = l; 872 873 Check(); 874 #endif // wxLONGLONG_TEST_MODE 875 876 return *this; 877 } 878 wxULongLongWx& operator=(long l) 879 { 880 m_lo = l; 881 m_hi = (unsigned long) ((l<0) ? -1l : 0); 882 883 #ifdef wxLONGLONG_TEST_MODE 884 m_ll = (wxULongLong_t) (wxLongLong_t) l; 885 886 Check(); 887 #endif // wxLONGLONG_TEST_MODE 888 889 return *this; 890 } 891 wxULongLongWx& operator=(const class wxLongLongWx &ll) { 892 // Should we use an assert like it was before in the constructor? 893 // wxASSERT(ll.GetHi() >= 0); 894 m_hi = (unsigned long)ll.GetHi(); 895 m_lo = ll.GetLo(); 896 return *this; 897 } 898 899 // can't have assignment operator from 2 longs 900 901 // accessors 902 // get high part GetHi()903 unsigned long GetHi() const { return m_hi; } 904 // get low part GetLo()905 unsigned long GetLo() const { return m_lo; } 906 907 // convert to long with range checking in debug mode (only!) ToULong()908 unsigned long ToULong() const 909 { 910 wxASSERT_MSG( m_hi == 0ul, 911 wxT("wxULongLong to long conversion loss of precision") ); 912 913 return (unsigned long)m_lo; 914 } 915 916 // convert to double 917 double ToDouble() const; 918 919 // operations 920 // addition 921 wxULongLongWx operator+(const wxULongLongWx& ll) const; 922 wxULongLongWx& operator+=(const wxULongLongWx& ll); 923 wxULongLongWx operator+(unsigned long l) const; 924 wxULongLongWx& operator+=(unsigned long l); 925 926 // pre increment operator 927 wxULongLongWx& operator++(); 928 929 // post increment operator 930 wxULongLongWx& operator++(int) { return ++(*this); } 931 932 // subtraction 933 wxLongLongWx operator-(const wxULongLongWx& ll) const; 934 wxULongLongWx& operator-=(const wxULongLongWx& ll); 935 936 // pre decrement operator 937 wxULongLongWx& operator--(); 938 939 // post decrement operator 940 wxULongLongWx& operator--(int) { return --(*this); } 941 942 // shifts 943 // left shift 944 wxULongLongWx operator<<(int shift) const; 945 wxULongLongWx& operator<<=(int shift); 946 947 // right shift 948 wxULongLongWx operator>>(int shift) const; 949 wxULongLongWx& operator>>=(int shift); 950 951 // bitwise operators 952 wxULongLongWx operator&(const wxULongLongWx& ll) const; 953 wxULongLongWx& operator&=(const wxULongLongWx& ll); 954 wxULongLongWx operator|(const wxULongLongWx& ll) const; 955 wxULongLongWx& operator|=(const wxULongLongWx& ll); 956 wxULongLongWx operator^(const wxULongLongWx& ll) const; 957 wxULongLongWx& operator^=(const wxULongLongWx& ll); 958 wxULongLongWx operator~() const; 959 960 // comparison 961 bool operator==(const wxULongLongWx& ll) const 962 { return m_lo == ll.m_lo && m_hi == ll.m_hi; } 963 bool operator!=(const wxULongLongWx& ll) const 964 { return !(*this == ll); } 965 bool operator<(const wxULongLongWx& ll) const; 966 bool operator>(const wxULongLongWx& ll) const; 967 bool operator<=(const wxULongLongWx& ll) const 968 { return *this < ll || *this == ll; } 969 bool operator>=(const wxULongLongWx& ll) const 970 { return *this > ll || *this == ll; } 971 972 bool operator<(unsigned long l) const { return *this < wxULongLongWx(l); } 973 bool operator>(unsigned long l) const { return *this > wxULongLongWx(l); } 974 bool operator==(unsigned long l) const 975 { 976 return (m_hi == 0 && m_lo == (unsigned long)l); 977 } 978 979 bool operator<=(unsigned long l) const { return *this < l || *this == l; } 980 bool operator>=(unsigned long l) const { return *this > l || *this == l; } 981 982 // multiplication 983 wxULongLongWx operator*(const wxULongLongWx& ll) const; 984 wxULongLongWx& operator*=(const wxULongLongWx& ll); 985 986 // division 987 wxULongLongWx operator/(const wxULongLongWx& ll) const; 988 wxULongLongWx& operator/=(const wxULongLongWx& ll); 989 990 wxULongLongWx operator%(const wxULongLongWx& ll) const; 991 992 void Divide(const wxULongLongWx& divisor, 993 wxULongLongWx& quotient, 994 wxULongLongWx& remainder) const; 995 996 // input/output 997 998 // return the string representation of this number 999 wxString ToString() const; 1000 1001 void *asArray() const; 1002 1003 #if wxUSE_STD_IOSTREAM 1004 friend WXDLLIMPEXP_BASE 1005 wxSTD ostream& operator<<(wxSTD ostream&, const wxULongLongWx&); 1006 #endif // wxUSE_STD_IOSTREAM 1007 1008 friend WXDLLIMPEXP_BASE 1009 wxString& operator<<(wxString&, const wxULongLongWx&); 1010 1011 #if wxUSE_STREAMS 1012 friend WXDLLIMPEXP_BASE 1013 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLongWx&); 1014 friend WXDLLIMPEXP_BASE 1015 class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLongWx&); 1016 #endif 1017 1018 private: 1019 // long is at least 32 bits, so represent our 64bit number as 2 longs 1020 1021 unsigned long m_hi; 1022 unsigned long m_lo; 1023 1024 #ifdef wxLONGLONG_TEST_MODE Check()1025 void Check() 1026 { 1027 wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo ); 1028 } 1029 1030 wxULongLong_t m_ll; 1031 #endif // wxLONGLONG_TEST_MODE 1032 }; 1033 1034 #endif // wxUSE_LONGLONG_WX 1035 1036 // ---------------------------------------------------------------------------- 1037 // binary operators 1038 // ---------------------------------------------------------------------------- 1039 1040 inline bool operator<(long l, const wxLongLong& ll) { return ll > l; } 1041 inline bool operator>(long l, const wxLongLong& ll) { return ll < l; } 1042 inline bool operator<=(long l, const wxLongLong& ll) { return ll >= l; } 1043 inline bool operator>=(long l, const wxLongLong& ll) { return ll <= l; } 1044 inline bool operator==(long l, const wxLongLong& ll) { return ll == l; } 1045 inline bool operator!=(long l, const wxLongLong& ll) { return ll != l; } 1046 1047 inline wxLongLong operator+(long l, const wxLongLong& ll) { return ll + l; } 1048 inline wxLongLong operator-(long l, const wxLongLong& ll) 1049 { 1050 return wxLongLong(l) - ll; 1051 } 1052 1053 inline bool operator<(unsigned long l, const wxULongLong& ull) { return ull > l; } 1054 inline bool operator>(unsigned long l, const wxULongLong& ull) { return ull < l; } 1055 inline bool operator<=(unsigned long l, const wxULongLong& ull) { return ull >= l; } 1056 inline bool operator>=(unsigned long l, const wxULongLong& ull) { return ull <= l; } 1057 inline bool operator==(unsigned long l, const wxULongLong& ull) { return ull == l; } 1058 inline bool operator!=(unsigned long l, const wxULongLong& ull) { return ull != l; } 1059 1060 inline wxULongLong operator+(unsigned long l, const wxULongLong& ull) { return ull + l; } 1061 1062 inline wxLongLong operator-(unsigned long l, const wxULongLong& ull) 1063 { 1064 wxULongLong ret = wxULongLong(l) - ull; 1065 return wxLongLong((long)ret.GetHi(),ret.GetLo()); 1066 } 1067 1068 #if wxUSE_LONGLONG_NATIVE && wxUSE_STREAMS 1069 1070 WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxULongLong_t value); 1071 WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxLongLong_t value); 1072 1073 WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxULongLong_t &value); 1074 WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxLongLong_t &value); 1075 1076 #endif 1077 1078 #endif // wxUSE_LONGLONG 1079 1080 #endif // _WX_LONGLONG_H 1081