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