]> git.saurik.com Git - wxWidgets.git/blob - include/wx/longlong.h
Don't define __STRICT_ANSI__, we should build both with and without it.
[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 // 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
111 wxLongLongNative() : m_ll(0) { }
112 // from long long
113 wxLongLongNative(wxLongLong_t ll) : m_ll(ll) { }
114 // from 2 longs
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
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
162 wxInt32 GetHi() const
163 { return wx_truncate_cast(wxInt32, m_ll >> 32); }
164 // get low part
165 wxUint32 GetLo() const
166 { return wx_truncate_cast(wxUint32, m_ll); }
167
168 // get absolute value
169 wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); }
170 wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
171
172 // convert to native long long
173 wxLongLong_t GetValue() const { return m_ll; }
174
175 // convert to long with range checking in debug mode (only!)
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
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); }
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
348 wxULongLongNative() : m_ll(0) { }
349 // from long long
350 wxULongLongNative(wxULongLong_t ll) : m_ll(ll) { }
351 // from 2 longs
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
394 wxUint32 GetHi() const
395 { return wx_truncate_cast(wxUint32, m_ll >> 32); }
396 // get low part
397 wxUint32 GetLo() const
398 { return wx_truncate_cast(wxUint32, m_ll); }
399
400 // convert to native ulong long
401 wxULongLong_t GetValue() const { return m_ll; }
402
403 // convert to ulong with range checking in debug mode (only!)
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
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
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
597 wxLongLongWx(long l) { *this = l; }
598 // from 2 longs
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
665 long GetHi() const { return m_hi; }
666 // get low part
667 unsigned long GetLo() const { return m_lo; }
668
669 // get absolute value
670 wxLongLongWx Abs() const { return wxLongLongWx(*this).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!)
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
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
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
839 wxULongLongWx(unsigned long l) { *this = l; }
840 // from 2 ulongs
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
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
907 unsigned long GetHi() const { return m_hi; }
908 // get low part
909 unsigned long GetLo() const { return m_lo; }
910
911 // convert to long with range checking in debug mode (only!)
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
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