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
107class WXDLLIMPEXP_BASE wxLongLongNative
108{
109public:
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(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
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
163    wxInt32 GetHi() const
164        { return wx_truncate_cast(wxInt32, m_ll >> 32); }
165        // get low part
166    wxUint32 GetLo() const
167        { return wx_truncate_cast(wxUint32, m_ll); }
168
169        // get absolute value
170    wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); }
171    wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
172
173        // convert to native long long
174    wxLongLong_t GetValue() const { return m_ll; }
175
176        // convert to long with range checking in debug mode (only!)
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
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); }
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
339private:
340    wxLongLong_t  m_ll;
341};
342
343
344class WXDLLIMPEXP_BASE wxULongLongNative
345{
346public:
347    // ctors
348        // default ctor initializes to 0
349    wxULongLongNative() : m_ll(0) { }
350        // from long long
351    wxULongLongNative(wxULongLong_t ll) : m_ll(ll) { }
352        // from 2 longs
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
395    wxUint32 GetHi() const
396        { return wx_truncate_cast(wxUint32, m_ll >> 32); }
397        // get low part
398    wxUint32 GetLo() const
399        { return wx_truncate_cast(wxUint32, m_ll); }
400
401        // convert to native ulong long
402    wxULongLong_t GetValue() const { return m_ll; }
403
404        // convert to ulong with range checking in debug mode (only!)
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
415    double ToDouble() const { return wx_truncate_cast(double, (__int64) m_ll); }
416#else
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
562private:
563    wxULongLong_t  m_ll;
564};
565
566inline
567wxLongLongNative& 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
577class WXDLLIMPEXP_BASE wxLongLongWx
578{
579public:
580    // ctors
581        // default ctor initializes to 0
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
593    wxLongLongWx(long l) { *this = l; }
594        // from 2 longs
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
661    long GetHi() const { return m_hi; }
662        // get low part
663    unsigned long GetLo() const { return m_lo; }
664
665        // get absolute value
666    wxLongLongWx Abs() const { return wxLongLongWx(*this).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!)
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
802private:
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
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
819class WXDLLIMPEXP_BASE wxULongLongWx
820{
821public:
822    // ctors
823        // default ctor initializes to 0
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
835    wxULongLongWx(unsigned long l) { *this = l; }
836        // from 2 ulongs
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
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
903    unsigned long GetHi() const { return m_hi; }
904        // get low part
905    unsigned long GetLo() const { return m_lo; }
906
907        // convert to long with range checking in debug mode (only!)
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
1018private:
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
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
1040inline bool operator<(long l, const wxLongLong& ll) { return ll > l; }
1041inline bool operator>(long l, const wxLongLong& ll) { return ll < l; }
1042inline bool operator<=(long l, const wxLongLong& ll) { return ll >= l; }
1043inline bool operator>=(long l, const wxLongLong& ll) { return ll <= l; }
1044inline bool operator==(long l, const wxLongLong& ll) { return ll == l; }
1045inline bool operator!=(long l, const wxLongLong& ll) { return ll != l; }
1046
1047inline wxLongLong operator+(long l, const wxLongLong& ll) { return ll + l; }
1048inline wxLongLong operator-(long l, const wxLongLong& ll)
1049{
1050    return wxLongLong(l) - ll;
1051}
1052
1053inline bool operator<(unsigned long l, const wxULongLong& ull) { return ull > l; }
1054inline bool operator>(unsigned long l, const wxULongLong& ull) { return ull < l; }
1055inline bool operator<=(unsigned long l, const wxULongLong& ull) { return ull >= l; }
1056inline bool operator>=(unsigned long l, const wxULongLong& ull) { return ull <= l; }
1057inline bool operator==(unsigned long l, const wxULongLong& ull) { return ull == l; }
1058inline bool operator!=(unsigned long l, const wxULongLong& ull) { return ull != l; }
1059
1060inline wxULongLong operator+(unsigned long l, const wxULongLong& ull) { return ull + l; }
1061
1062inline 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
1070WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxULongLong_t value);
1071WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxLongLong_t value);
1072
1073WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxULongLong_t &value);
1074WXDLLIMPEXP_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