]> git.saurik.com Git - wxWidgets.git/blob - include/wx/longlong.h
added support for 64 bit ints in wx stream classes (patch 1203970)
[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 #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_BASE wxLongLongNative;
90 class WXDLLIMPEXP_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
112 wxLongLongNative() : m_ll(0) { }
113 // from long long
114 wxLongLongNative(wxLongLong_t ll) : m_ll(ll) { }
115 // from 2 longs
116 wxLongLongNative(long hi, unsigned long lo) : m_ll(0)
117 {
118 // assign 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 wxLongLongNative& operator=(wxLongLong_t ll)
133 { m_ll = ll; return *this; }
134 wxLongLongNative& operator=(wxULongLong_t ll)
135 { m_ll = ll; return *this; }
136 wxLongLongNative& operator=(const wxULongLongNative &ll);
137 wxLongLongNative& operator=(long l)
138 { m_ll = l; return *this; }
139 wxLongLongNative& operator=(unsigned long l)
140 { m_ll = l; return *this; }
141 #if wxUSE_LONGLONG_WX
142 wxLongLongNative& operator=(wxLongLongWx ll);
143 wxLongLongNative& operator=(const class wxULongLongWx &ll);
144 #endif
145
146
147 // from double: this one has an explicit name because otherwise we
148 // would have ambiguity with "ll = int" and also because we don't want
149 // to have implicit conversions between doubles and wxLongLongs
150 wxLongLongNative& Assign(double d)
151 { m_ll = (wxLongLong_t)d; return *this; }
152
153 // assignment operators from wxLongLongNative is ok
154
155 // accessors
156 // get high part
157 long GetHi() const
158 { return wx_truncate_cast(long, m_ll >> 32); }
159 // get low part
160 unsigned long GetLo() const
161 { return wx_truncate_cast(unsigned long, m_ll); }
162
163 // get absolute value
164 wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); }
165 wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
166
167 // convert to native long long
168 wxLongLong_t GetValue() const { return m_ll; }
169
170 // convert to long with range checking in debug mode (only!)
171 long ToLong() const
172 {
173 wxASSERT_MSG( (m_ll >= LONG_MIN) && (m_ll <= LONG_MAX),
174 _T("wxLongLong to long conversion loss of precision") );
175
176 return wx_truncate_cast(long, m_ll);
177 }
178
179 // convert to double
180 double ToDouble() const { return wx_truncate_cast(double, m_ll); }
181
182 // don't provide implicit conversion to wxLongLong_t or we will have an
183 // ambiguity for all arithmetic operations
184 //operator wxLongLong_t() const { return m_ll; }
185
186 // operations
187 // addition
188 wxLongLongNative operator+(const wxLongLongNative& ll) const
189 { return wxLongLongNative(m_ll + ll.m_ll); }
190 wxLongLongNative& operator+=(const wxLongLongNative& ll)
191 { m_ll += ll.m_ll; return *this; }
192
193 wxLongLongNative operator+(const wxLongLong_t ll) const
194 { return wxLongLongNative(m_ll + ll); }
195 wxLongLongNative& operator+=(const wxLongLong_t ll)
196 { m_ll += ll; return *this; }
197
198 // pre increment
199 wxLongLongNative& operator++()
200 { m_ll++; return *this; }
201
202 // post increment
203 wxLongLongNative operator++(int)
204 { wxLongLongNative value(*this); m_ll++; return value; }
205
206 // negation operator
207 wxLongLongNative operator-() const
208 { return wxLongLongNative(-m_ll); }
209 wxLongLongNative& Negate() { m_ll = -m_ll; return *this; }
210
211 // subtraction
212 wxLongLongNative operator-(const wxLongLongNative& ll) const
213 { return wxLongLongNative(m_ll - ll.m_ll); }
214 wxLongLongNative& operator-=(const wxLongLongNative& ll)
215 { m_ll -= ll.m_ll; return *this; }
216
217 wxLongLongNative operator-(const wxLongLong_t ll) const
218 { return wxLongLongNative(m_ll - ll); }
219 wxLongLongNative& operator-=(const wxLongLong_t ll)
220 { m_ll -= ll; return *this; }
221
222 // pre decrement
223 wxLongLongNative& operator--()
224 { m_ll--; return *this; }
225
226 // post decrement
227 wxLongLongNative operator--(int)
228 { wxLongLongNative value(*this); m_ll--; return value; }
229
230 // shifts
231 // left shift
232 wxLongLongNative operator<<(int shift) const
233 { return wxLongLongNative(m_ll << shift); }
234 wxLongLongNative& operator<<=(int shift)
235 { m_ll <<= shift; return *this; }
236
237 // right 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 // bitwise operators
244 wxLongLongNative operator&(const wxLongLongNative& ll) const
245 { return wxLongLongNative(m_ll & ll.m_ll); }
246 wxLongLongNative& operator&=(const wxLongLongNative& ll)
247 { m_ll &= ll.m_ll; return *this; }
248
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 // multiplication/division
260 wxLongLongNative operator*(const wxLongLongNative& ll) const
261 { return wxLongLongNative(m_ll * ll.m_ll); }
262 wxLongLongNative operator*(long l) const
263 { return wxLongLongNative(m_ll * l); }
264 wxLongLongNative& operator*=(const wxLongLongNative& ll)
265 { m_ll *= ll.m_ll; return *this; }
266 wxLongLongNative& operator*=(long l)
267 { m_ll *= l; return *this; }
268
269 wxLongLongNative operator/(const wxLongLongNative& ll) const
270 { return wxLongLongNative(m_ll / ll.m_ll); }
271 wxLongLongNative operator/(long l) const
272 { return wxLongLongNative(m_ll / l); }
273 wxLongLongNative& operator/=(const wxLongLongNative& ll)
274 { m_ll /= ll.m_ll; return *this; }
275 wxLongLongNative& operator/=(long l)
276 { m_ll /= l; return *this; }
277
278 wxLongLongNative operator%(const wxLongLongNative& ll) const
279 { return wxLongLongNative(m_ll % ll.m_ll); }
280 wxLongLongNative operator%(long l) const
281 { return wxLongLongNative(m_ll % l); }
282
283 // comparison
284 bool operator==(const wxLongLongNative& ll) const
285 { return m_ll == ll.m_ll; }
286 bool operator==(long l) const
287 { return m_ll == l; }
288 bool operator!=(const wxLongLongNative& ll) const
289 { return m_ll != ll.m_ll; }
290 bool operator!=(long l) const
291 { return m_ll != l; }
292 bool operator<(const wxLongLongNative& ll) const
293 { return m_ll < ll.m_ll; }
294 bool operator<(long l) const
295 { return m_ll < l; }
296 bool operator>(const wxLongLongNative& ll) const
297 { return m_ll > ll.m_ll; }
298 bool operator>(long l) const
299 { return m_ll > l; }
300 bool operator<=(const wxLongLongNative& ll) const
301 { return m_ll <= ll.m_ll; }
302 bool operator<=(long l) const
303 { return m_ll <= l; }
304 bool operator>=(const wxLongLongNative& ll) const
305 { return m_ll >= ll.m_ll; }
306 bool operator>=(long l) const
307 { return m_ll >= l; }
308
309 // miscellaneous
310
311 // return the string representation of this number
312 wxString ToString() const;
313
314 // conversion to byte array: returns a pointer to static buffer!
315 void *asArray() const;
316
317 #if wxUSE_STD_IOSTREAM
318 // input/output
319 friend WXDLLIMPEXP_BASE
320 wxSTD ostream& operator<<(wxSTD ostream&, const wxLongLongNative&);
321 #endif
322
323 friend WXDLLIMPEXP_BASE
324 wxString& operator<<(wxString&, const wxLongLongNative&);
325
326 #if wxUSE_STREAMS
327 friend WXDLLIMPEXP_BASE
328 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLongNative&);
329 friend WXDLLIMPEXP_BASE
330 class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLongNative&);
331 #endif
332
333 private:
334 wxLongLong_t m_ll;
335 };
336
337
338 class WXDLLIMPEXP_BASE wxULongLongNative
339 {
340 public:
341 // ctors
342 // default ctor initializes to 0
343 wxULongLongNative() : m_ll(0) { }
344 // from long long
345 wxULongLongNative(wxULongLong_t ll) : m_ll(ll) { }
346 // from 2 longs
347 wxULongLongNative(unsigned long hi, unsigned long lo) : m_ll(0)
348 {
349 // assign first to avoid precision loss!
350 m_ll = ((wxULongLong_t) hi) << 32;
351 m_ll |= (wxULongLong_t) lo;
352 }
353
354 #if wxUSE_LONGLONG_WX
355 wxULongLongNative(const class wxULongLongWx &ll);
356 #endif
357
358 // default copy ctor is ok
359
360 // no dtor
361
362 // assignment operators
363 // from native 64 bit integer
364 wxULongLongNative& operator=(wxULongLong_t ll)
365 { m_ll = ll; return *this; }
366 wxULongLongNative& operator=(wxLongLong_t ll)
367 { m_ll = ll; return *this; }
368 wxULongLongNative& operator=(long l)
369 { m_ll = l; return *this; }
370 wxULongLongNative& operator=(unsigned long l)
371 { m_ll = l; return *this; }
372 wxULongLongNative& operator=(const wxLongLongNative &ll)
373 { m_ll = ll.GetValue(); return *this; }
374 #if wxUSE_LONGLONG_WX
375 wxULongLongNative& operator=(wxLongLongWx ll);
376 wxULongLongNative& operator=(const class wxULongLongWx &ll);
377 #endif
378
379 // assignment operators from wxULongLongNative is ok
380
381 // accessors
382 // get high part
383 unsigned long GetHi() const
384 { return wx_truncate_cast(unsigned long, m_ll >> 32); }
385 // get low part
386 unsigned long GetLo() const
387 { return wx_truncate_cast(unsigned long, m_ll); }
388
389 // convert to native ulong long
390 wxULongLong_t GetValue() const { return m_ll; }
391
392 // convert to ulong with range checking in debug mode (only!)
393 unsigned long ToULong() const
394 {
395 wxASSERT_MSG( m_ll <= LONG_MAX,
396 _T("wxULongLong to long conversion loss of precision") );
397
398 return wx_truncate_cast(unsigned long, m_ll);
399 }
400
401 // operations
402 // addition
403 wxULongLongNative operator+(const wxULongLongNative& ll) const
404 { return wxULongLongNative(m_ll + ll.m_ll); }
405 wxULongLongNative& operator+=(const wxULongLongNative& ll)
406 { m_ll += ll.m_ll; return *this; }
407
408 wxULongLongNative operator+(const wxULongLong_t ll) const
409 { return wxULongLongNative(m_ll + ll); }
410 wxULongLongNative& operator+=(const wxULongLong_t ll)
411 { m_ll += ll; return *this; }
412
413 // pre increment
414 wxULongLongNative& operator++()
415 { m_ll++; return *this; }
416
417 // post increment
418 wxULongLongNative operator++(int)
419 { wxULongLongNative value(*this); m_ll++; return value; }
420
421 // subtraction
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 decrement
433 wxULongLongNative& operator--()
434 { m_ll--; return *this; }
435
436 // post decrement
437 wxULongLongNative operator--(int)
438 { wxULongLongNative value(*this); m_ll--; return value; }
439
440 // shifts
441 // left shift
442 wxULongLongNative operator<<(int shift) const
443 { return wxULongLongNative(m_ll << shift); }
444 wxULongLongNative& operator<<=(int shift)
445 { m_ll <<= shift; return *this; }
446
447 // right shift
448 wxULongLongNative operator>>(int shift) const
449 { return wxULongLongNative(m_ll >> shift); }
450 wxULongLongNative& operator>>=(int shift)
451 { m_ll >>= shift; return *this; }
452
453 // bitwise operators
454 wxULongLongNative operator&(const wxULongLongNative& ll) const
455 { return wxULongLongNative(m_ll & ll.m_ll); }
456 wxULongLongNative& operator&=(const wxULongLongNative& ll)
457 { m_ll &= ll.m_ll; return *this; }
458
459 wxULongLongNative operator|(const wxULongLongNative& ll) const
460 { return wxULongLongNative(m_ll | ll.m_ll); }
461 wxULongLongNative& operator|=(const wxULongLongNative& ll)
462 { m_ll |= ll.m_ll; return *this; }
463
464 wxULongLongNative operator^(const wxULongLongNative& ll) const
465 { return wxULongLongNative(m_ll ^ ll.m_ll); }
466 wxULongLongNative& operator^=(const wxULongLongNative& ll)
467 { m_ll ^= ll.m_ll; return *this; }
468
469 // multiplication/division
470 wxULongLongNative operator*(const wxULongLongNative& ll) const
471 { return wxULongLongNative(m_ll * ll.m_ll); }
472 wxULongLongNative operator*(unsigned long l) const
473 { return wxULongLongNative(m_ll * l); }
474 wxULongLongNative& operator*=(const wxULongLongNative& ll)
475 { m_ll *= ll.m_ll; return *this; }
476 wxULongLongNative& operator*=(unsigned long l)
477 { m_ll *= l; return *this; }
478
479 wxULongLongNative operator/(const wxULongLongNative& ll) const
480 { return wxULongLongNative(m_ll / ll.m_ll); }
481 wxULongLongNative operator/(unsigned long l) const
482 { return wxULongLongNative(m_ll / l); }
483 wxULongLongNative& operator/=(const wxULongLongNative& ll)
484 { m_ll /= ll.m_ll; return *this; }
485 wxULongLongNative& operator/=(unsigned long l)
486 { m_ll /= l; return *this; }
487
488 wxULongLongNative operator%(const wxULongLongNative& ll) const
489 { return wxULongLongNative(m_ll % ll.m_ll); }
490 wxULongLongNative operator%(unsigned long l) const
491 { return wxULongLongNative(m_ll % l); }
492
493 // comparison
494 bool operator==(const wxULongLongNative& ll) const
495 { return m_ll == ll.m_ll; }
496 bool operator==(unsigned long l) const
497 { return m_ll == l; }
498 bool operator!=(const wxULongLongNative& ll) const
499 { return m_ll != ll.m_ll; }
500 bool operator!=(unsigned long l) const
501 { return m_ll != l; }
502 bool operator<(const wxULongLongNative& ll) const
503 { return m_ll < ll.m_ll; }
504 bool operator<(unsigned long l) const
505 { return m_ll < l; }
506 bool operator>(const wxULongLongNative& ll) const
507 { return m_ll > ll.m_ll; }
508 bool operator>(unsigned long l) const
509 { return m_ll > l; }
510 bool operator<=(const wxULongLongNative& ll) const
511 { return m_ll <= ll.m_ll; }
512 bool operator<=(unsigned long l) const
513 { return m_ll <= l; }
514 bool operator>=(const wxULongLongNative& ll) const
515 { return m_ll >= ll.m_ll; }
516 bool operator>=(unsigned long l) const
517 { return m_ll >= l; }
518
519 // miscellaneous
520
521 // return the string representation of this number
522 wxString ToString() const;
523
524 // conversion to byte array: returns a pointer to static buffer!
525 void *asArray() const;
526
527 #if wxUSE_STD_IOSTREAM
528 // input/output
529 friend WXDLLIMPEXP_BASE
530 wxSTD ostream& operator<<(wxSTD ostream&, const wxULongLongNative&);
531 #endif
532
533 friend WXDLLIMPEXP_BASE
534 wxString& operator<<(wxString&, const wxULongLongNative&);
535
536 #if wxUSE_STREAMS
537 friend WXDLLIMPEXP_BASE
538 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLongNative&);
539 friend WXDLLIMPEXP_BASE
540 class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLongNative&);
541 #endif
542
543 private:
544 wxULongLong_t m_ll;
545 };
546
547 inline
548 wxLongLongNative& wxLongLongNative::operator=(const wxULongLongNative &ll)
549 {
550 m_ll = ll.GetValue();
551 return *this;
552 }
553
554 #endif // wxUSE_LONGLONG_NATIVE
555
556 #if wxUSE_LONGLONG_WX
557
558 class WXDLLIMPEXP_BASE wxLongLongWx
559 {
560 public:
561 // ctors
562 // default ctor initializes to 0
563 wxLongLongWx()
564 {
565 m_lo = m_hi = 0;
566
567 #ifdef wxLONGLONG_TEST_MODE
568 m_ll = 0;
569
570 Check();
571 #endif // wxLONGLONG_TEST_MODE
572 }
573 // from long
574 wxLongLongWx(long l) { *this = l; }
575 // from 2 longs
576 wxLongLongWx(long hi, unsigned long lo)
577 {
578 m_hi = hi;
579 m_lo = lo;
580
581 #ifdef wxLONGLONG_TEST_MODE
582 m_ll = hi;
583 m_ll <<= 32;
584 m_ll |= lo;
585
586 Check();
587 #endif // wxLONGLONG_TEST_MODE
588 }
589
590 // default copy ctor is ok in both cases
591
592 // no dtor
593
594 // assignment operators
595 // from long
596 wxLongLongWx& operator=(long l)
597 {
598 m_lo = l;
599 m_hi = (l < 0 ? -1l : 0l);
600
601 #ifdef wxLONGLONG_TEST_MODE
602 m_ll = l;
603
604 Check();
605 #endif // wxLONGLONG_TEST_MODE
606
607 return *this;
608 }
609 wxLongLongWx& operator=(unsigned long l)
610 {
611 m_lo = l;
612 m_hi = 0;
613
614 #ifdef wxLONGLONG_TEST_MODE
615 m_ll = l;
616
617 Check();
618 #endif // wxLONGLONG_TEST_MODE
619
620 return *this;
621 }
622 wxLongLongWx& operator=(const class wxULongLongWx &ll);
623
624 // from double
625 wxLongLongWx& Assign(double d);
626 // can't have assignment operator from 2 longs
627
628 // accessors
629 // get high part
630 long GetHi() const { return m_hi; }
631 // get low part
632 unsigned long GetLo() const { return m_lo; }
633
634 // get absolute value
635 wxLongLongWx Abs() const { return wxLongLongWx(*this).Abs(); }
636 wxLongLongWx& Abs()
637 {
638 if ( m_hi < 0 )
639 m_hi = -m_hi;
640
641 #ifdef wxLONGLONG_TEST_MODE
642 if ( m_ll < 0 )
643 m_ll = -m_ll;
644
645 Check();
646 #endif // wxLONGLONG_TEST_MODE
647
648 return *this;
649 }
650
651 // convert to long with range checking in debug mode (only!)
652 long ToLong() const
653 {
654 wxASSERT_MSG( (m_hi == 0l) || (m_hi == -1l),
655 _T("wxLongLong to long conversion loss of precision") );
656
657 return (long)m_lo;
658 }
659
660 // convert to double
661 double ToDouble() const;
662
663 // operations
664 // addition
665 wxLongLongWx operator+(const wxLongLongWx& ll) const;
666 wxLongLongWx& operator+=(const wxLongLongWx& ll);
667 wxLongLongWx operator+(long l) const;
668 wxLongLongWx& operator+=(long l);
669
670 // pre increment operator
671 wxLongLongWx& operator++();
672
673 // post increment operator
674 wxLongLongWx& operator++(int) { return ++(*this); }
675
676 // negation operator
677 wxLongLongWx operator-() const;
678 wxLongLongWx& Negate();
679
680 // subraction
681 wxLongLongWx operator-(const wxLongLongWx& ll) const;
682 wxLongLongWx& operator-=(const wxLongLongWx& ll);
683
684 // pre decrement operator
685 wxLongLongWx& operator--();
686
687 // post decrement operator
688 wxLongLongWx& operator--(int) { return --(*this); }
689
690 // shifts
691 // left shift
692 wxLongLongWx operator<<(int shift) const;
693 wxLongLongWx& operator<<=(int shift);
694
695 // right shift
696 wxLongLongWx operator>>(int shift) const;
697 wxLongLongWx& operator>>=(int shift);
698
699 // bitwise operators
700 wxLongLongWx operator&(const wxLongLongWx& ll) const;
701 wxLongLongWx& operator&=(const wxLongLongWx& ll);
702 wxLongLongWx operator|(const wxLongLongWx& ll) const;
703 wxLongLongWx& operator|=(const wxLongLongWx& ll);
704 wxLongLongWx operator^(const wxLongLongWx& ll) const;
705 wxLongLongWx& operator^=(const wxLongLongWx& ll);
706 wxLongLongWx operator~() const;
707
708 // comparison
709 bool operator==(const wxLongLongWx& ll) const
710 { return m_lo == ll.m_lo && m_hi == ll.m_hi; }
711 #if wxUSE_LONGLONG_NATIVE
712 bool operator==(const wxLongLongNative& ll) const
713 { return m_lo == ll.GetLo() && m_hi == ll.GetHi(); }
714 #endif
715 bool operator!=(const wxLongLongWx& ll) const
716 { return !(*this == ll); }
717 bool operator<(const wxLongLongWx& ll) const;
718 bool operator>(const wxLongLongWx& ll) const;
719 bool operator<=(const wxLongLongWx& ll) const
720 { return *this < ll || *this == ll; }
721 bool operator>=(const wxLongLongWx& ll) const
722 { return *this > ll || *this == ll; }
723
724 bool operator<(long l) const { return *this < wxLongLongWx(l); }
725 bool operator>(long l) const { return *this > wxLongLongWx(l); }
726 bool operator==(long l) const
727 {
728 return l >= 0 ? (m_hi == 0 && m_lo == (unsigned long)l)
729 : (m_hi == -1 && m_lo == (unsigned long)l);
730 }
731
732 bool operator<=(long l) const { return *this < l || *this == l; }
733 bool operator>=(long l) const { return *this > l || *this == l; }
734
735 // multiplication
736 wxLongLongWx operator*(const wxLongLongWx& ll) const;
737 wxLongLongWx& operator*=(const wxLongLongWx& ll);
738
739 // division
740 wxLongLongWx operator/(const wxLongLongWx& ll) const;
741 wxLongLongWx& operator/=(const wxLongLongWx& ll);
742
743 wxLongLongWx operator%(const wxLongLongWx& ll) const;
744
745 void Divide(const wxLongLongWx& divisor,
746 wxLongLongWx& quotient,
747 wxLongLongWx& remainder) const;
748
749 // input/output
750
751 // return the string representation of this number
752 wxString ToString() const;
753
754 void *asArray() const;
755
756 #if wxUSE_STD_IOSTREAM
757 friend WXDLLIMPEXP_BASE
758 wxSTD ostream& operator<<(wxSTD ostream&, const wxLongLongWx&);
759 #endif // wxUSE_STD_IOSTREAM
760
761 friend WXDLLIMPEXP_BASE
762 wxString& operator<<(wxString&, const wxLongLongWx&);
763
764 #if wxUSE_STREAMS
765 friend WXDLLIMPEXP_BASE
766 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLongWx&);
767 friend WXDLLIMPEXP_BASE
768 class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLongWx&);
769 #endif
770
771 private:
772 // long is at least 32 bits, so represent our 64bit number as 2 longs
773
774 long m_hi; // signed bit is in the high part
775 unsigned long m_lo;
776
777 #ifdef wxLONGLONG_TEST_MODE
778 void Check()
779 {
780 wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo );
781 }
782
783 wxLongLong_t m_ll;
784 #endif // wxLONGLONG_TEST_MODE
785 };
786
787
788 class WXDLLIMPEXP_BASE wxULongLongWx
789 {
790 public:
791 // ctors
792 // default ctor initializes to 0
793 wxULongLongWx()
794 {
795 m_lo = m_hi = 0;
796
797 #ifdef wxLONGLONG_TEST_MODE
798 m_ll = 0;
799
800 Check();
801 #endif // wxLONGLONG_TEST_MODE
802 }
803 // from ulong
804 wxULongLongWx(unsigned long l) { *this = l; }
805 // from 2 ulongs
806 wxULongLongWx(unsigned long hi, unsigned long lo)
807 {
808 m_hi = hi;
809 m_lo = lo;
810
811 #ifdef wxLONGLONG_TEST_MODE
812 m_ll = hi;
813 m_ll <<= 32;
814 m_ll |= lo;
815
816 Check();
817 #endif // wxLONGLONG_TEST_MODE
818 }
819
820 // from signed to unsigned
821 wxULongLongWx(wxLongLongWx ll)
822 {
823 wxASSERT(ll.GetHi() >= 0);
824 m_hi = (unsigned long)ll.GetHi();
825 m_lo = ll.GetLo();
826 }
827
828 // default copy ctor is ok in both cases
829
830 // no dtor
831
832 // assignment operators
833 // from long
834 wxULongLongWx& operator=(unsigned long l)
835 {
836 m_lo = l;
837 m_hi = 0;
838
839 #ifdef wxLONGLONG_TEST_MODE
840 m_ll = l;
841
842 Check();
843 #endif // wxLONGLONG_TEST_MODE
844
845 return *this;
846 }
847 wxULongLongWx& operator=(long l)
848 {
849 m_lo = l;
850 m_hi = (unsigned long) ((l<0) ? -1l : 0);
851
852 #ifdef wxLONGLONG_TEST_MODE
853 m_ll = (wxULongLong_t) (wxLongLong_t) l;
854
855 Check();
856 #endif // wxLONGLONG_TEST_MODE
857
858 return *this;
859 }
860 wxULongLongWx& operator=(const class wxLongLongWx &ll) {
861 // Should we use an assert like it was before in the constructor?
862 // wxASSERT(ll.GetHi() >= 0);
863 m_hi = (unsigned long)ll.GetHi();
864 m_lo = ll.GetLo();
865 return *this;
866 }
867
868 // can't have assignment operator from 2 longs
869
870 // accessors
871 // get high part
872 unsigned long GetHi() const { return m_hi; }
873 // get low part
874 unsigned long GetLo() const { return m_lo; }
875
876 // convert to long with range checking in debug mode (only!)
877 unsigned long ToULong() const
878 {
879 wxASSERT_MSG( m_hi == 0ul,
880 _T("wxULongLong to long conversion loss of precision") );
881
882 return (unsigned long)m_lo;
883 }
884
885 // operations
886 // addition
887 wxULongLongWx operator+(const wxULongLongWx& ll) const;
888 wxULongLongWx& operator+=(const wxULongLongWx& ll);
889 wxULongLongWx operator+(unsigned long l) const;
890 wxULongLongWx& operator+=(unsigned long l);
891
892 // pre increment operator
893 wxULongLongWx& operator++();
894
895 // post increment operator
896 wxULongLongWx& operator++(int) { return ++(*this); }
897
898 // subtraction
899 wxLongLongWx operator-(const wxULongLongWx& ll) const;
900 wxULongLongWx& operator-=(const wxULongLongWx& ll);
901
902 // pre decrement operator
903 wxULongLongWx& operator--();
904
905 // post decrement operator
906 wxULongLongWx& operator--(int) { return --(*this); }
907
908 // shifts
909 // left shift
910 wxULongLongWx operator<<(int shift) const;
911 wxULongLongWx& operator<<=(int shift);
912
913 // right shift
914 wxULongLongWx operator>>(int shift) const;
915 wxULongLongWx& operator>>=(int shift);
916
917 // bitwise operators
918 wxULongLongWx operator&(const wxULongLongWx& ll) const;
919 wxULongLongWx& operator&=(const wxULongLongWx& ll);
920 wxULongLongWx operator|(const wxULongLongWx& ll) const;
921 wxULongLongWx& operator|=(const wxULongLongWx& ll);
922 wxULongLongWx operator^(const wxULongLongWx& ll) const;
923 wxULongLongWx& operator^=(const wxULongLongWx& ll);
924 wxULongLongWx operator~() const;
925
926 // comparison
927 bool operator==(const wxULongLongWx& ll) const
928 { return m_lo == ll.m_lo && m_hi == ll.m_hi; }
929 bool operator!=(const wxULongLongWx& ll) const
930 { return !(*this == ll); }
931 bool operator<(const wxULongLongWx& ll) const;
932 bool operator>(const wxULongLongWx& ll) const;
933 bool operator<=(const wxULongLongWx& ll) const
934 { return *this < ll || *this == ll; }
935 bool operator>=(const wxULongLongWx& ll) const
936 { return *this > ll || *this == ll; }
937
938 bool operator<(unsigned long l) const { return *this < wxULongLongWx(l); }
939 bool operator>(unsigned long l) const { return *this > wxULongLongWx(l); }
940 bool operator==(unsigned long l) const
941 {
942 return (m_hi == 0 && m_lo == (unsigned long)l);
943 }
944
945 bool operator<=(unsigned long l) const { return *this < l || *this == l; }
946 bool operator>=(unsigned long l) const { return *this > l || *this == l; }
947
948 // multiplication
949 wxULongLongWx operator*(const wxULongLongWx& ll) const;
950 wxULongLongWx& operator*=(const wxULongLongWx& ll);
951
952 // division
953 wxULongLongWx operator/(const wxULongLongWx& ll) const;
954 wxULongLongWx& operator/=(const wxULongLongWx& ll);
955
956 wxULongLongWx operator%(const wxULongLongWx& ll) const;
957
958 void Divide(const wxULongLongWx& divisor,
959 wxULongLongWx& quotient,
960 wxULongLongWx& remainder) const;
961
962 // input/output
963
964 // return the string representation of this number
965 wxString ToString() const;
966
967 void *asArray() const;
968
969 #if wxUSE_STD_IOSTREAM
970 friend WXDLLIMPEXP_BASE
971 wxSTD ostream& operator<<(wxSTD ostream&, const wxULongLongWx&);
972 #endif // wxUSE_STD_IOSTREAM
973
974 friend WXDLLIMPEXP_BASE
975 wxString& operator<<(wxString&, const wxULongLongWx&);
976
977 #if wxUSE_STREAMS
978 friend WXDLLIMPEXP_BASE
979 class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLongWx&);
980 friend WXDLLIMPEXP_BASE
981 class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLongWx&);
982 #endif
983
984 private:
985 // long is at least 32 bits, so represent our 64bit number as 2 longs
986
987 unsigned long m_hi;
988 unsigned long m_lo;
989
990 #ifdef wxLONGLONG_TEST_MODE
991 void Check()
992 {
993 wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo );
994 }
995
996 wxULongLong_t m_ll;
997 #endif // wxLONGLONG_TEST_MODE
998 };
999
1000 #endif // wxUSE_LONGLONG_WX
1001
1002 // ----------------------------------------------------------------------------
1003 // binary operators
1004 // ----------------------------------------------------------------------------
1005
1006 inline bool operator<(long l, const wxLongLong& ll) { return ll > l; }
1007 inline bool operator>(long l, const wxLongLong& ll) { return ll < l; }
1008 inline bool operator<=(long l, const wxLongLong& ll) { return ll >= l; }
1009 inline bool operator>=(long l, const wxLongLong& ll) { return ll <= l; }
1010 inline bool operator==(long l, const wxLongLong& ll) { return ll == l; }
1011 inline bool operator!=(long l, const wxLongLong& ll) { return ll != l; }
1012
1013 inline wxLongLong operator+(long l, const wxLongLong& ll) { return ll + l; }
1014 inline wxLongLong operator-(long l, const wxLongLong& ll)
1015 {
1016 return wxLongLong(l) - ll;
1017 }
1018
1019 inline bool operator<(unsigned long l, const wxULongLong& ull) { return ull > l; }
1020 inline bool operator>(unsigned long l, const wxULongLong& ull) { return ull < l; }
1021 inline bool operator<=(unsigned long l, const wxULongLong& ull) { return ull >= l; }
1022 inline bool operator>=(unsigned long l, const wxULongLong& ull) { return ull <= l; }
1023 inline bool operator==(unsigned long l, const wxULongLong& ull) { return ull == l; }
1024 inline bool operator!=(unsigned long l, const wxULongLong& ull) { return ull != l; }
1025
1026 inline wxULongLong operator+(unsigned long l, const wxULongLong& ull) { return ull + l; }
1027
1028 inline wxLongLong operator-(unsigned long l, const wxULongLong& ull)
1029 {
1030 wxULongLong ret = wxULongLong(l) - ull;
1031 return wxLongLong((long)ret.GetHi(),ret.GetLo());
1032 }
1033
1034 #if wxUSE_LONGLONG_NATIVE && wxUSE_STREAMS
1035
1036 WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxULongLong_t value);
1037 WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxLongLong_t value);
1038
1039 WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxULongLong_t &value);
1040 WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxLongLong_t &value);
1041
1042 #endif
1043
1044 #endif // wxUSE_LONGLONG
1045
1046 #endif // _WX_LONGLONG_H