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