]> git.saurik.com Git - wxWidgets.git/blob - include/wx/longlong.h
This is how wxPlotWindow would look like with the
[wxWidgets.git] / include / wx / longlong.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/longlong.h
3 // Purpose: declaration of wxLongLong class - best implementation of a 64
4 // bit integer for the current platform.
5 // Author: Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin
6 // Modified by:
7 // Created: 10.02.99
8 // 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
20 #include "wx/defs.h"
21 #include "wx/wxchar.h"
22
23 #include <limits.h> // for LONG_MAX
24
25 // define this to compile wxLongLongWx in "test" mode: the results of all
26 // calculations will be compared with the real results taken from
27 // wxLongLongNative -- this is extremely useful to find the bugs in
28 // wxLongLongWx class!
29
30 // #define wxLONGLONG_TEST_MODE
31
32 #ifdef wxLONGLONG_TEST_MODE
33 #define wxUSE_LONGLONG_WX 1
34 #define wxUSE_LONGLONG_NATIVE 1
35 #endif // wxLONGLONG_TEST_MODE
36
37 // ----------------------------------------------------------------------------
38 // decide upon which class we will use
39 // ----------------------------------------------------------------------------
40
41 // to avoid compilation problems on 64bit machines with ambiguous method calls
42 // we will need to define this
43 #undef wxLongLongIsLong
44
45 // NB: we #define and not typedef wxLongLong_t because we want to be able to
46 // use 'unsigned wxLongLong_t' as well and because we use "#ifdef
47 // wxLongLong_t" below
48 #if defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
49 #define wxLongLong_t long
50 #define wxLongLongIsLong
51 #elif (defined(__VISUALC__) && defined(__WIN32__)) || defined( __VMS__ )
52 #define wxLongLong_t __int64
53 #elif defined(__BORLANDC__) && defined(__WIN32__) && (__BORLANDC__ >= 0x520)
54 #define wxLongLong_t __int64
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
64 #elif defined(__VISAGECPP__) && __IBMCPP__ >= 400
65 #define wxLongLong_t long long
66 #else // no native long long type
67 // both warning and pragma warning are not portable, but at least an
68 // unknown pragma should never be an error - unless the compiler is
69 // seriously broken as Watcom C++ seems to be...
70 #ifndef __WATCOMC__
71 #pragma warning "Your compiler does not appear to support 64 bit "\
72 "integers, using emulation class instead."
73 #endif
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
80 #if (defined(wxUSE_LONGLONG_WX) && wxUSE_LONGLONG_WX) || !defined(wxLongLong_t)
81 // don't use both classes unless wxUSE_LONGLONG_NATIVE was explicitly set:
82 // this is useful in test programs and only there
83 #ifndef wxUSE_LONGLONG_NATIVE
84 #define wxUSE_LONGLONG_NATIVE 0
85 #endif
86
87 class WXDLLEXPORT wxLongLongWx;
88 typedef wxLongLongWx wxLongLong;
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
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
114 class WXDLLEXPORT wxLongLongNative
115 {
116 public:
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
130 // default copy ctor is ok
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
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
145 // assignment operators from wxLongLongNative is ok
146
147 // accessors
148 // get high part
149 long GetHi() const
150 { return (long)(m_ll >> 32); }
151 // get low part
152 unsigned long GetLo() const
153 { return (unsigned long)m_ll; }
154
155 // get absolute value
156 wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); }
157 wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
158
159 // convert to native long long
160 wxLongLong_t GetValue() const { return m_ll; }
161
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
171 // don't provide implicit conversion to wxLongLong_t or we will have an
172 // ambiguity for all arithmetic operations
173 //operator wxLongLong_t() const { return m_ll; }
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
247 // multiplication/division
248 wxLongLongNative operator*(const wxLongLongNative& ll) const
249 { return wxLongLongNative(m_ll * ll.m_ll); }
250 wxLongLongNative operator*(long l) const
251 { return wxLongLongNative(m_ll * l); }
252 wxLongLongNative& operator*=(const wxLongLongNative& ll)
253 { m_ll *= ll.m_ll; return *this; }
254 wxLongLongNative& operator*=(long l)
255 { m_ll *= l; return *this; }
256
257 wxLongLongNative operator/(const wxLongLongNative& ll) const
258 { return wxLongLongNative(m_ll / ll.m_ll); }
259 wxLongLongNative operator/(long l) const
260 { return wxLongLongNative(m_ll / l); }
261 wxLongLongNative& operator/=(const wxLongLongNative& ll)
262 { m_ll /= ll.m_ll; return *this; }
263 wxLongLongNative& operator/=(long l)
264 { m_ll /= l; return *this; }
265
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
271 // comparison
272 bool operator==(const wxLongLongNative& ll) const
273 { return m_ll == ll.m_ll; }
274 bool operator==(long l) const
275 { return m_ll == l; }
276 bool operator!=(const wxLongLongNative& ll) const
277 { return m_ll != ll.m_ll; }
278 bool operator!=(long l) const
279 { return m_ll != l; }
280 bool operator<(const wxLongLongNative& ll) const
281 { return m_ll < ll.m_ll; }
282 bool operator<(long l) const
283 { return m_ll < l; }
284 bool operator>(const wxLongLongNative& ll) const
285 { return m_ll > ll.m_ll; }
286 bool operator>(long l) const
287 { return m_ll > l; }
288 bool operator<=(const wxLongLongNative& ll) const
289 { return m_ll <= ll.m_ll; }
290 bool operator<=(long l) const
291 { return m_ll <= l; }
292 bool operator>=(const wxLongLongNative& ll) const
293 { return m_ll >= ll.m_ll; }
294 bool operator>=(long l) const
295 { return m_ll >= l; }
296
297 // miscellaneous
298 // conversion to byte array: returns a pointer to static buffer!
299 void *asArray() const;
300
301 #if wxUSE_STD_IOSTREAM
302 // input/output
303 friend ostream& operator<<(ostream&, const wxLongLongNative&);
304 #endif
305
306 private:
307 wxLongLong_t m_ll;
308 };
309
310 #endif // wxUSE_LONGLONG_NATIVE
311
312 #if wxUSE_LONGLONG_WX
313
314 class WXDLLEXPORT wxLongLongWx
315 {
316 public:
317 // ctors
318 // default ctor initializes to 0
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 }
329 // from long
330 wxLongLongWx(long l) { *this = l; }
331 // from 2 longs
332 wxLongLongWx(long hi, unsigned long lo)
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 }
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)
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 }
365 // from double
366 wxLongLongWx& Assign(double d);
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
375 // get absolute value
376 wxLongLongWx Abs() const { return wxLongLongWx(*this).Abs(); }
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 }
391
392 // convert to long with range checking in the debug mode (only!)
393 long ToLong() const
394 {
395 wxASSERT_MSG( (m_hi == 0l) || (m_hi == -1l),
396 _T("wxLongLong to long conversion loss of precision") );
397
398 return (long)m_lo;
399 }
400
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
412 wxLongLongWx& operator++(int) { return ++(*this); }
413
414 // negation operator
415 wxLongLongWx operator-() const;
416 wxLongLongWx& Negate();
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
426 wxLongLongWx& operator--(int) { return --(*this); }
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
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); }
451 bool operator<(const wxLongLongWx& ll) const;
452 bool operator>(const wxLongLongWx& ll) const;
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; }
457
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
469 // multiplication
470 wxLongLongWx operator*(const wxLongLongWx& ll) const;
471 wxLongLongWx& operator*=(const wxLongLongWx& ll);
472
473 // division
474 wxLongLongWx operator/(const wxLongLongWx& ll) const;
475 wxLongLongWx& operator/=(const wxLongLongWx& ll);
476
477 wxLongLongWx operator%(const wxLongLongWx& ll) const;
478
479 void Divide(const wxLongLongWx& divisor,
480 wxLongLongWx& quotient,
481 wxLongLongWx& remainder) const;
482
483 // input/output
484 #if wxUSE_STD_IOSTREAM
485 friend ostream& operator<<(ostream&, const wxLongLongWx&);
486 #endif // wxUSE_STD_IOSTREAM
487
488 void *asArray() const;
489
490 private:
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;
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
504 };
505
506 #endif // wxUSE_LONGLONG_WX
507
508 // ----------------------------------------------------------------------------
509 // binary operators
510 // ----------------------------------------------------------------------------
511
512 inline bool WXDLLEXPORT operator<(long l, const wxLongLong& ll) { return ll > l; }
513 inline bool WXDLLEXPORT operator>(long l, const wxLongLong& ll) { return ll > l; }
514 inline bool WXDLLEXPORT operator<=(long l, const wxLongLong& ll) { return ll > l; }
515 inline bool WXDLLEXPORT operator>=(long l, const wxLongLong& ll) { return ll > l; }
516 inline bool WXDLLEXPORT operator==(long l, const wxLongLong& ll) { return ll > l; }
517 inline bool WXDLLEXPORT operator!=(long l, const wxLongLong& ll) { return ll > l; }
518
519 inline wxLongLong WXDLLEXPORT operator+(long l, const wxLongLong& ll) { return ll + l; }
520 inline wxLongLong WXDLLEXPORT operator-(long l, const wxLongLong& ll) { return ll - l; }
521
522 #endif // _WX_LONGLONG_H