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