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