]> git.saurik.com Git - wxWidgets.git/blame - include/wx/longlong.h
using wxURL now enforces linking http.o, ftp.o and sckfile.o
[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>
10// Licence: wxWindows license
11/////////////////////////////////////////////////////////////////////////////
12
13#ifndef _WX_LONGLONG_H
14#define _WX_LONGLONG_H
15
16#ifdef __GNUG__
17 #pragma interface "longlong.h"
18#endif
19
1ef54dcf
VZ
20#include "wx/defs.h"
21#include "wx/wxchar.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
8b81872f
VZ
48#if defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
49 #define wxLongLong_t long
50 #define wxLongLongIsLong
cd0b1709 51#elif (defined(__VISUALC__) && defined(__WIN32__)) || defined( __VMS__ )
8b81872f 52 #define wxLongLong_t __int64
f6bcfd97 53#elif defined(__BORLANDC__) && defined(__WIN32__) && (__BORLANDC__ >= 0x520)
ad0dc53b 54 #define wxLongLong_t __int64
8b81872f
VZ
55#elif defined(__GNUG__)
56 #define wxLongLong_t long long
57#elif defined(__MWERKS__)
58 #if __option(longlong)
59 #define wxLongLong_t long long
60 #else
61 #error "The 64 bit integer support in CodeWarrior has been disabled."
62 #error "See the documentation on the 'longlong' pragma."
63 #endif
398b582f
DW
64#elif defined(__VISAGECPP__) && __IBMCPP__ >= 400
65 #define wxLongLong_t long long
cd0b1709 66#else // no native long long type
9c2882d9 67 // both warning and pragma warning are not portable, but at least an
384223b3
VZ
68 // unknown pragma should never be an error - unless the compiler is
69 // seriously broken as Watcom C++ seems to be...
403603f7 70#if (!(defined(__WATCOMC__) || defined(__VISAGECPP__)))
9c2882d9
VZ
71 #pragma warning "Your compiler does not appear to support 64 bit "\
72 "integers, using emulation class instead."
cff4a45c 73#endif
8b81872f
VZ
74 #define wxUSE_LONGLONG_WX 1
75#endif // compiler
76
77// the user may predefine wxUSE_LONGLONG_NATIVE and/or wxUSE_LONGLONG_NATIVE
78// to disable automatic testing (useful for the test program which defines
79// both classes) but by default we only use one class
2ea24d9f 80#if (defined(wxUSE_LONGLONG_WX) && wxUSE_LONGLONG_WX) || !defined(wxLongLong_t)
2a310492 81 // don't use both classes unless wxUSE_LONGLONG_NATIVE was explicitly set:
384223b3 82 // this is useful in test programs and only there
2a310492
VZ
83 #ifndef wxUSE_LONGLONG_NATIVE
84 #define wxUSE_LONGLONG_NATIVE 0
85 #endif
86
8b81872f
VZ
87 class WXDLLEXPORT wxLongLongWx;
88 typedef wxLongLongWx wxLongLong;
b76b015e
VZ
89#else
90 // if nothing is defined, use native implementation by default, of course
91 #ifndef wxUSE_LONGLONG_NATIVE
92 #define wxUSE_LONGLONG_NATIVE 1
93 #endif
8b81872f
VZ
94#endif
95
96#ifndef wxUSE_LONGLONG_WX
97 #define wxUSE_LONGLONG_WX 0
98 class WXDLLEXPORT wxLongLongNative;
99 typedef wxLongLongNative wxLongLong;
100#endif
101
102// NB: if both wxUSE_LONGLONG_WX and NATIVE are defined, the user code should
103// typedef wxLongLong as it wants, we don't do it
104
105// ----------------------------------------------------------------------------
106// choose the appropriate class
107// ----------------------------------------------------------------------------
108
109// we use iostream for wxLongLong output
110#include "wx/ioswrap.h"
111
112#if wxUSE_LONGLONG_NATIVE
113
114class WXDLLEXPORT wxLongLongNative
115{
116public:
117 // ctors
118 // default ctor initializes to 0
119 wxLongLongNative() { m_ll = 0; }
120 // from long long
121 wxLongLongNative(wxLongLong_t ll) { m_ll = ll; }
122 // from 2 longs
123 wxLongLongNative(long hi, unsigned long lo)
124 {
125 // assign first to avoid precision loss!
126 m_ll = ((wxLongLong_t) hi) << 32;
127 m_ll |= (wxLongLong_t) lo;
128 }
129
2f02cb89 130 // default copy ctor is ok
8b81872f
VZ
131
132 // no dtor
133
134 // assignment operators
135 // from native 64 bit integer
136 wxLongLongNative& operator=(wxLongLong_t ll)
137 { m_ll = ll; return *this; }
138
cd0b1709
VZ
139 // from double: this one has an explicit name because otherwise we
140 // would have ambiguity with "ll = int" and also because we don't want
141 // to have implicit conversions between doubles and wxLongLongs
142 wxLongLongNative& Assign(double d)
143 { m_ll = (wxLongLong_t)d; return *this; }
144
8b81872f
VZ
145 // assignment operators from wxLongLongNative is ok
146
147 // accessors
148 // get high part
149 long GetHi() const
2f02cb89 150 { return (long)(m_ll >> 32); }
8b81872f
VZ
151 // get low part
152 unsigned long GetLo() const
2f02cb89 153 { return (unsigned long)m_ll; }
8b81872f 154
b76b015e 155 // get absolute value
2ea24d9f 156 wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); }
b76b015e
VZ
157 wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
158
8b81872f
VZ
159 // convert to native long long
160 wxLongLong_t GetValue() const { return m_ll; }
161
1ef54dcf
VZ
162 // convert to long with range checking in the debug mode (only!)
163 long ToLong() const
164 {
165 wxASSERT_MSG( (m_ll >= LONG_MIN) && (m_ll <= LONG_MAX),
166 _T("wxLongLong to long conversion loss of precision") );
167
168 return (long)m_ll;
169 }
170
2f02cb89
VZ
171 // don't provide implicit conversion to wxLongLong_t or we will have an
172 // ambiguity for all arithmetic operations
b76b015e 173 //operator wxLongLong_t() const { return m_ll; }
8b81872f
VZ
174
175 // operations
176 // addition
177 wxLongLongNative operator+(const wxLongLongNative& ll) const
178 { return wxLongLongNative(m_ll + ll.m_ll); }
179 wxLongLongNative& operator+=(const wxLongLongNative& ll)
180 { m_ll += ll.m_ll; return *this; }
181
182 wxLongLongNative operator+(const wxLongLong_t ll) const
183 { return wxLongLongNative(m_ll + ll); }
184 wxLongLongNative& operator+=(const wxLongLong_t ll)
185 { m_ll += ll; return *this; }
186
187 // pre increment
188 wxLongLongNative& operator++()
189 { m_ll++; return *this; }
190
191 // post increment
192 wxLongLongNative& operator++(int)
193 { m_ll++; return *this; }
194
195 // negation operator
196 wxLongLongNative operator-() const
197 { return wxLongLongNative(-m_ll); }
198
199 // subtraction
200 wxLongLongNative operator-(const wxLongLongNative& ll) const
201 { return wxLongLongNative(m_ll - ll.m_ll); }
202 wxLongLongNative& operator-=(const wxLongLongNative& ll)
203 { m_ll -= ll.m_ll; return *this; }
204
205 wxLongLongNative operator-(const wxLongLong_t ll) const
206 { return wxLongLongNative(m_ll - ll); }
207 wxLongLongNative& operator-=(const wxLongLong_t ll)
208 { m_ll -= ll; return *this; }
209
210 // pre decrement
211 wxLongLongNative& operator--()
212 { m_ll--; return *this; }
213
214 // post decrement
215 wxLongLongNative& operator--(int)
216 { m_ll--; return *this; }
217
218 // shifts
219 // left shift
220 wxLongLongNative operator<<(int shift) const
221 { return wxLongLongNative(m_ll << shift);; }
222 wxLongLongNative& operator<<=(int shift)
223 { m_ll <<= shift; return *this; }
224
225 // right shift
226 wxLongLongNative operator>>(int shift) const
227 { return wxLongLongNative(m_ll >> shift);; }
228 wxLongLongNative& operator>>=(int shift)
229 { m_ll >>= shift; return *this; }
230
231 // bitwise operators
232 wxLongLongNative operator&(const wxLongLongNative& ll) const
233 { return wxLongLongNative(m_ll & ll.m_ll); }
234 wxLongLongNative& operator&=(const wxLongLongNative& ll)
235 { m_ll &= ll.m_ll; return *this; }
236
237 wxLongLongNative operator|(const wxLongLongNative& ll) const
238 { return wxLongLongNative(m_ll | ll.m_ll); }
239 wxLongLongNative& operator|=(const wxLongLongNative& ll)
240 { m_ll |= ll.m_ll; return *this; }
241
242 wxLongLongNative operator^(const wxLongLongNative& ll) const
243 { return wxLongLongNative(m_ll ^ ll.m_ll); }
244 wxLongLongNative& operator^=(const wxLongLongNative& ll)
245 { m_ll ^= ll.m_ll; return *this; }
246
b76b015e 247 // multiplication/division
8b81872f
VZ
248 wxLongLongNative operator*(const wxLongLongNative& ll) const
249 { return wxLongLongNative(m_ll * ll.m_ll); }
2f02cb89
VZ
250 wxLongLongNative operator*(long l) const
251 { return wxLongLongNative(m_ll * l); }
8b81872f
VZ
252 wxLongLongNative& operator*=(const wxLongLongNative& ll)
253 { m_ll *= ll.m_ll; return *this; }
2f02cb89
VZ
254 wxLongLongNative& operator*=(long l)
255 { m_ll *= l; return *this; }
8b81872f
VZ
256
257 wxLongLongNative operator/(const wxLongLongNative& ll) const
258 { return wxLongLongNative(m_ll / ll.m_ll); }
b76b015e
VZ
259 wxLongLongNative operator/(long l) const
260 { return wxLongLongNative(m_ll / l); }
8b81872f
VZ
261 wxLongLongNative& operator/=(const wxLongLongNative& ll)
262 { m_ll /= ll.m_ll; return *this; }
2f02cb89
VZ
263 wxLongLongNative& operator/=(long l)
264 { m_ll /= l; return *this; }
8b81872f
VZ
265
266 wxLongLongNative operator%(const wxLongLongNative& ll) const
267 { return wxLongLongNative(m_ll % ll.m_ll); }
b76b015e
VZ
268 wxLongLongNative operator%(long l) const
269 { return wxLongLongNative(m_ll % l); }
8b81872f
VZ
270
271 // comparison
272 bool operator==(const wxLongLongNative& ll) const
273 { return m_ll == ll.m_ll; }
b76b015e
VZ
274 bool operator==(long l) const
275 { return m_ll == l; }
8b81872f
VZ
276 bool operator!=(const wxLongLongNative& ll) const
277 { return m_ll != ll.m_ll; }
b76b015e
VZ
278 bool operator!=(long l) const
279 { return m_ll != l; }
8b81872f
VZ
280 bool operator<(const wxLongLongNative& ll) const
281 { return m_ll < ll.m_ll; }
b76b015e
VZ
282 bool operator<(long l) const
283 { return m_ll < l; }
8b81872f
VZ
284 bool operator>(const wxLongLongNative& ll) const
285 { return m_ll > ll.m_ll; }
b76b015e
VZ
286 bool operator>(long l) const
287 { return m_ll > l; }
8b81872f
VZ
288 bool operator<=(const wxLongLongNative& ll) const
289 { return m_ll <= ll.m_ll; }
b76b015e
VZ
290 bool operator<=(long l) const
291 { return m_ll <= l; }
8b81872f
VZ
292 bool operator>=(const wxLongLongNative& ll) const
293 { return m_ll >= ll.m_ll; }
b76b015e
VZ
294 bool operator>=(long l) const
295 { return m_ll >= l; }
8b81872f
VZ
296
297 // miscellaneous
298 // conversion to byte array: returns a pointer to static buffer!
299 void *asArray() const;
300
fcc3d7cb 301#if wxUSE_STD_IOSTREAM
8b81872f 302 // input/output
162b0c3b 303 friend ostream& operator<<(ostream&, const wxLongLongNative&);
fcc3d7cb 304#endif
8b81872f
VZ
305
306private:
307 wxLongLong_t m_ll;
308};
309
310#endif // wxUSE_LONGLONG_NATIVE
311
312#if wxUSE_LONGLONG_WX
313
314class WXDLLEXPORT wxLongLongWx
315{
316public:
317 // ctors
318 // default ctor initializes to 0
2a310492
VZ
319 wxLongLongWx()
320 {
321 m_lo = m_hi = 0;
322
323#ifdef wxLONGLONG_TEST_MODE
324 m_ll = 0;
325
326 Check();
327#endif // wxLONGLONG_TEST_MODE
328 }
8b81872f 329 // from long
2a310492 330 wxLongLongWx(long l) { *this = l; }
8b81872f
VZ
331 // from 2 longs
332 wxLongLongWx(long hi, unsigned long lo)
2a310492
VZ
333 {
334 m_hi = hi;
335 m_lo = lo;
336
337#ifdef wxLONGLONG_TEST_MODE
338 m_ll = hi;
339 m_ll <<= 32;
340 m_ll |= lo;
341
342 Check();
343#endif // wxLONGLONG_TEST_MODE
344 }
8b81872f
VZ
345
346 // default copy ctor is ok in both cases
347
348 // no dtor
349
350 // assignment operators
351 // from long
352 wxLongLongWx& operator=(long l)
2a310492
VZ
353 {
354 m_lo = l;
355 m_hi = (l < 0 ? -1l : 0l);
356
357#ifdef wxLONGLONG_TEST_MODE
358 m_ll = l;
359
360 Check();
361#endif // wxLONGLONG_TEST_MODE
362
363 return *this;
364 }
cd0b1709
VZ
365 // from double
366 wxLongLongWx& Assign(double d);
8b81872f
VZ
367 // can't have assignment operator from 2 longs
368
369 // accessors
370 // get high part
371 long GetHi() const { return m_hi; }
372 // get low part
373 unsigned long GetLo() const { return m_lo; }
374
cd0b1709 375 // get absolute value
2ea24d9f 376 wxLongLongWx Abs() const { return wxLongLongWx(*this).Abs(); }
2a310492
VZ
377 wxLongLongWx& Abs()
378 {
379 if ( m_hi < 0 )
380 m_hi = -m_hi;
381
382#ifdef wxLONGLONG_TEST_MODE
383 if ( m_ll < 0 )
384 m_ll = -m_ll;
385
386 Check();
387#endif // wxLONGLONG_TEST_MODE
388
389 return *this;
390 }
cd0b1709
VZ
391
392 // convert to long with range checking in the debug mode (only!)
393 long ToLong() const
394 {
2a310492 395 wxASSERT_MSG( (m_hi == 0l) || (m_hi == -1l),
cd0b1709
VZ
396 _T("wxLongLong to long conversion loss of precision") );
397
398 return (long)m_lo;
399 }
400
8b81872f
VZ
401 // operations
402 // addition
403 wxLongLongWx operator+(const wxLongLongWx& ll) const;
404 wxLongLongWx& operator+=(const wxLongLongWx& ll);
405 wxLongLongWx operator+(long l) const;
406 wxLongLongWx& operator+=(long l);
407
408 // pre increment operator
409 wxLongLongWx& operator++();
410
411 // post increment operator
2a310492 412 wxLongLongWx& operator++(int) { return ++(*this); }
8b81872f
VZ
413
414 // negation operator
415 wxLongLongWx operator-() const;
2a310492 416 wxLongLongWx& Negate();
8b81872f
VZ
417
418 // subraction
419 wxLongLongWx operator-(const wxLongLongWx& ll) const;
420 wxLongLongWx& operator-=(const wxLongLongWx& ll);
421
422 // pre decrement operator
423 wxLongLongWx& operator--();
424
425 // post decrement operator
2a310492 426 wxLongLongWx& operator--(int) { return --(*this); }
8b81872f
VZ
427
428 // shifts
429 // left shift
430 wxLongLongWx operator<<(int shift) const;
431 wxLongLongWx& operator<<=(int shift);
432
433 // right shift
434 wxLongLongWx operator>>(int shift) const;
435 wxLongLongWx& operator>>=(int shift);
436
437 // bitwise operators
438 wxLongLongWx operator&(const wxLongLongWx& ll) const;
439 wxLongLongWx& operator&=(const wxLongLongWx& ll);
440 wxLongLongWx operator|(const wxLongLongWx& ll) const;
441 wxLongLongWx& operator|=(const wxLongLongWx& ll);
442 wxLongLongWx operator^(const wxLongLongWx& ll) const;
443 wxLongLongWx& operator^=(const wxLongLongWx& ll);
444 wxLongLongWx operator~() const;
445
446 // comparison
2ea24d9f
VZ
447 bool operator==(const wxLongLongWx& ll) const
448 { return m_lo == ll.m_lo && m_hi == ll.m_hi; }
449 bool operator!=(const wxLongLongWx& ll) const
450 { return !(*this == ll); }
8b81872f
VZ
451 bool operator<(const wxLongLongWx& ll) const;
452 bool operator>(const wxLongLongWx& ll) const;
2ea24d9f
VZ
453 bool operator<=(const wxLongLongWx& ll) const
454 { return *this < ll || *this == ll; }
455 bool operator>=(const wxLongLongWx& ll) const
456 { return *this > ll || *this == ll; }
8b81872f 457
f6bcfd97
BP
458 bool operator<(long l) const { return *this < wxLongLongWx(l); }
459 bool operator>(long l) const { return *this > wxLongLongWx(l); }
460 bool operator==(long l) const
461 {
462 return l >= 0 ? (m_hi == 0 && m_lo == (unsigned long)l)
463 : (m_hi == -1 && m_lo == (unsigned long)l);
464 }
465
466 bool operator<=(long l) const { return *this < l || *this == l; }
467 bool operator>=(long l) const { return *this > l || *this == l; }
468
8b81872f
VZ
469 // multiplication
470 wxLongLongWx operator*(const wxLongLongWx& ll) const;
471 wxLongLongWx& operator*=(const wxLongLongWx& ll);
8b81872f
VZ
472
473 // division
cd0b1709
VZ
474 wxLongLongWx operator/(const wxLongLongWx& ll) const;
475 wxLongLongWx& operator/=(const wxLongLongWx& ll);
476
477 wxLongLongWx operator%(const wxLongLongWx& ll) const;
478
8b81872f
VZ
479 void Divide(const wxLongLongWx& divisor,
480 wxLongLongWx& quotient,
481 wxLongLongWx& remainder) const;
482
483 // input/output
cd0b1709 484#if wxUSE_STD_IOSTREAM
162b0c3b 485 friend ostream& operator<<(ostream&, const wxLongLongWx&);
fcc3d7cb 486#endif // wxUSE_STD_IOSTREAM
8b81872f 487
2a310492 488 void *asArray() const;
cd0b1709 489
8b81872f
VZ
490private:
491 // long is at least 32 bits, so represent our 64bit number as 2 longs
492
493 long m_hi; // signed bit is in the high part
494 unsigned long m_lo;
2a310492
VZ
495
496#ifdef wxLONGLONG_TEST_MODE
497 void Check()
498 {
499 wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo );
500 }
501
502 wxLongLong_t m_ll;
503#endif // wxLONGLONG_TEST_MODE
8b81872f
VZ
504};
505
506#endif // wxUSE_LONGLONG_WX
507
2ea24d9f
VZ
508// ----------------------------------------------------------------------------
509// binary operators
510// ----------------------------------------------------------------------------
511
512inline bool WXDLLEXPORT operator<(long l, const wxLongLong& ll) { return ll > l; }
513inline bool WXDLLEXPORT operator>(long l, const wxLongLong& ll) { return ll > l; }
514inline bool WXDLLEXPORT operator<=(long l, const wxLongLong& ll) { return ll > l; }
515inline bool WXDLLEXPORT operator>=(long l, const wxLongLong& ll) { return ll > l; }
516inline bool WXDLLEXPORT operator==(long l, const wxLongLong& ll) { return ll > l; }
517inline bool WXDLLEXPORT operator!=(long l, const wxLongLong& ll) { return ll > l; }
518
519inline wxLongLong WXDLLEXPORT operator+(long l, const wxLongLong& ll) { return ll + l; }
520inline wxLongLong WXDLLEXPORT operator-(long l, const wxLongLong& ll) { return ll - l; }
521
8b81872f 522#endif // _WX_LONGLONG_H