MSW compilation fixes
[wxWidgets.git] / src / common / longlong.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/longlong.cpp
3 // Purpose: implementation of wxLongLongNative
4 // Author: Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin
5 // Remarks: this class is not public in wxWindows 2.0! It is intentionally
6 // not documented and is for private use only.
7 // Modified by:
8 // Created: 10.02.99
9 // RCS-ID: $Id$
10 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
11 // Licence: wxWindows license
12 /////////////////////////////////////////////////////////////////////////////
13
14 // ============================================================================
15 // headers
16 // ============================================================================
17
18 #ifdef __GNUG__
19 #pragma implementation "longlong.h"
20 #endif
21
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #include "wx/longlong.h"
29
30 #include <memory.h> // for memset()
31
32 // ============================================================================
33 // implementation
34 // ============================================================================
35
36 #if wxUSE_LONGLONG_NATIVE
37
38 // ----------------------------------------------------------------------------
39 // misc
40 // ----------------------------------------------------------------------------
41
42 void *wxLongLongNative::asArray(void) const
43 {
44 static unsigned char temp[8];
45
46 temp[0] = (m_ll >> 56) & 0xFF;
47 temp[1] = (m_ll >> 48) & 0xFF;
48 temp[2] = (m_ll >> 40) & 0xFF;
49 temp[3] = (m_ll >> 32) & 0xFF;
50 temp[4] = (m_ll >> 24) & 0xFF;
51 temp[5] = (m_ll >> 16) & 0xFF;
52 temp[6] = (m_ll >> 8) & 0xFF;
53 temp[7] = (m_ll >> 0) & 0xFF;
54
55 return temp;
56 }
57
58 // input/output
59 ostream& operator<< (ostream& o, const wxLongLongNative& ll)
60 {
61 char result[65];
62
63 memset(result, 'A', 64);
64
65 result[64] = '\0';
66
67 for (int i = 0; i < 64; i++)
68 {
69 result[63 - i] = '0' + (char) ((ll.m_ll >> i) & 1);
70 }
71
72 return o << result;
73 }
74
75 #endif // wxUSE_LONGLONG_NATIVE
76
77 #if wxUSE_LONGLONG_WX
78
79 wxLongLongWx wxLongLongWx::operator<<(int shift) const
80 {
81 if (shift == 0)
82 return *this;
83
84 if (shift < 32)
85 return wxLongLongWx((m_hi << shift) | (m_lo >> (32 - shift)),
86 m_lo << shift);
87 else
88 return wxLongLongWx(m_lo << (shift - 32),
89 0);
90 }
91
92 wxLongLongWx& wxLongLongWx::operator<<=(int shift)
93 {
94 if (shift == 0)
95 return *this;
96
97 if (shift < 32)
98 {
99 m_hi <<= shift;
100 m_hi |= m_lo >> (32 - shift);
101 m_lo <<= shift;
102 }
103 else
104 {
105 m_hi = m_lo << (shift - 32);
106 m_lo = 0;
107 }
108
109 return *this;
110 }
111
112 wxLongLongWx wxLongLongWx::operator>>(int shift) const
113 {
114 if (shift == 0)
115 return *this;
116
117 if (shift < 32)
118 return wxLongLongWx(m_hi >> shift,
119 (m_lo >> shift) | (m_hi << (32 - shift)));
120 else
121 return wxLongLongWx((m_hi < 0 ? -1l : 0),
122 m_hi >> (shift - 32));
123 }
124
125 wxLongLongWx& wxLongLongWx::operator>>=(int shift)
126 {
127 if (shift == 0)
128 return *this;
129
130 if (shift < 32)
131 {
132 m_lo >>= shift;
133 m_lo |= m_hi << (32 - shift);
134 m_hi >>= shift;
135 }
136 else
137 {
138 m_lo = m_hi >> (shift - 32);
139 m_hi = (m_hi < 0 ? -1L : 0);
140 }
141
142 return *this;
143 }
144
145 wxLongLongWx wxLongLongWx::operator+(const wxLongLongWx& ll) const
146 {
147 wxLongLongWx temp;
148
149 temp.m_lo = m_lo + ll.m_lo;
150 temp.m_hi = m_hi + ll.m_hi;
151 if ((temp.m_lo < m_lo) || (temp.m_lo < ll.m_lo))
152 temp.m_hi++;
153
154 return temp;
155 }
156
157 wxLongLongWx wxLongLongWx::operator+(long l) const
158 {
159 wxLongLongWx temp;
160
161 temp.m_lo = m_lo + l;
162
163 if (l < 0)
164 temp.m_hi += -1l;
165
166 if ((temp.m_lo < m_lo) || (temp.m_lo < (unsigned long)l))
167 temp.m_hi++;
168
169 return temp;
170 }
171
172 wxLongLongWx& wxLongLongWx::operator+=(const wxLongLongWx& ll)
173 {
174 unsigned long previous = m_lo;
175
176 m_lo += ll.m_lo;
177 m_hi += ll.m_hi;
178
179 if ((m_lo < previous) || (m_lo < ll.m_lo))
180 m_hi++;
181
182 return *this;
183 }
184
185 wxLongLongWx& wxLongLongWx::operator+=(long l)
186 {
187 unsigned long previous = m_lo;
188
189 m_lo += l;
190 if (l < 0)
191 m_hi += -1l;
192
193 if ((m_lo < previous) || (m_lo < (unsigned long)l))
194 m_hi++;
195
196 return *this;
197 }
198
199 // pre increment
200 wxLongLongWx& wxLongLongWx::operator++()
201 {
202 m_lo++;
203 if (m_lo == 0)
204 m_hi++;
205
206 return *this;
207 }
208
209 // post increment
210 wxLongLongWx& wxLongLongWx::operator++(int)
211 {
212 m_lo++;
213 if (m_lo == 0)
214 m_hi++;
215
216 return *this;
217 }
218
219 // negation
220 wxLongLongWx wxLongLongWx::operator-() const
221 {
222 wxLongLongWx temp(~m_hi, ~m_lo);
223
224 temp.m_lo++;
225 if (temp.m_lo == 0)
226 temp.m_hi++;
227
228 return temp;
229 }
230
231 // subtraction
232
233 wxLongLongWx wxLongLongWx::operator-(const wxLongLongWx& ll) const
234 {
235 wxLongLongWx temp;
236
237 temp.m_lo = m_lo - ll.m_lo;
238 temp.m_hi = m_hi - ll.m_hi;
239
240 if (m_lo < ll.m_lo)
241 temp.m_hi--;
242
243 return temp;
244 }
245
246 wxLongLongWx& wxLongLongWx::operator-=(const wxLongLongWx& ll)
247 {
248 unsigned long previous = m_lo;
249
250 m_lo -= ll.m_lo;
251 m_hi -= ll.m_hi;
252
253 if (previous < ll.m_lo)
254 m_hi--;
255
256 return *this;;
257 }
258
259 // pre decrement
260 wxLongLongWx& wxLongLongWx::operator--()
261 {
262 m_lo--;
263 if (m_lo == 0xFFFFFFFF)
264 m_hi--;
265
266 return *this;
267 }
268
269 // post decrement
270 wxLongLongWx& wxLongLongWx::operator--(int)
271 {
272 m_lo--;
273 if (m_lo == 0xFFFFFFFF)
274 m_hi--;
275
276 return *this;
277 }
278
279 // comparison operators
280
281 bool wxLongLongWx::operator<(const wxLongLongWx& ll) const
282 {
283 if (m_lo < ll.m_lo)
284 return 1;
285 if (m_lo > ll.m_lo)
286 return 0;
287 if (m_hi < ll.m_hi)
288 return 1;
289 if (m_hi > ll.m_hi)
290 return 0;
291 return 0;
292 }
293
294 bool wxLongLongWx::operator>(const wxLongLongWx& ll) const
295 {
296 if (m_lo < ll.m_lo)
297 return 0;
298 if (m_lo > ll.m_lo)
299 return 1;
300 if (m_hi < ll.m_hi)
301 return 0;
302 if (m_hi > ll.m_hi)
303 return 1;
304 return 0;
305 }
306
307 bool wxLongLongWx::operator<=(const wxLongLongWx& ll) const
308 {
309 if (m_lo < ll.m_lo)
310 return 1;
311 if (m_lo > ll.m_lo)
312 return 0;
313 if (m_hi < ll.m_hi)
314 return 1;
315 if (m_hi > ll.m_hi)
316 return 0;
317 return 1;
318 }
319
320 bool wxLongLongWx::operator>=(const wxLongLongWx& ll) const
321 {
322 if (m_lo < ll.m_lo)
323 return 0;
324 if (m_lo > ll.m_lo)
325 return 1;
326 if (m_hi < ll.m_hi)
327 return 0;
328 if (m_hi > ll.m_hi)
329 return 1;
330 return 1;
331 }
332
333 // bitwise operators
334
335 wxLongLongWx wxLongLongWx::operator&(const wxLongLongWx& ll) const
336 {
337 return wxLongLongWx(m_hi & ll.m_hi, m_lo & ll.m_lo);
338 }
339
340 wxLongLongWx wxLongLongWx::operator|(const wxLongLongWx& ll) const
341 {
342 return wxLongLongWx(m_hi | ll.m_hi, m_lo | ll.m_lo);
343 }
344
345 wxLongLongWx wxLongLongWx::operator^(const wxLongLongWx& ll) const
346 {
347 return wxLongLongWx(m_hi ^ ll.m_hi, m_lo ^ ll.m_lo);
348 }
349
350 wxLongLongWx& wxLongLongWx::operator&=(const wxLongLongWx& ll)
351 {
352 m_lo &= ll.m_lo;
353 m_hi &= ll.m_hi;
354
355 return *this;
356 }
357
358 wxLongLongWx& wxLongLongWx::operator|=(const wxLongLongWx& ll)
359 {
360 m_lo |= ll.m_lo;
361 m_hi |= ll.m_hi;
362
363 return *this;
364 }
365
366 wxLongLongWx& wxLongLongWx::operator^=(const wxLongLongWx& ll)
367 {
368 m_lo ^= ll.m_lo;
369 m_hi ^= ll.m_hi;
370
371 return *this;
372 }
373
374 wxLongLongWx wxLongLongWx::operator~() const
375 {
376 return wxLongLongWx(~m_hi, ~m_lo);
377 }
378
379 // multiplication
380
381 wxLongLongWx wxLongLongWx::operator*(const wxLongLongWx& ll) const
382 {
383 wxLongLongWx t(m_hi, m_lo);
384 wxLongLongWx q(ll.m_hi, ll.m_lo);
385 wxLongLongWx p;
386 int counter = 0;
387
388 do
389 {
390 if ((q.m_lo & 1) != 0)
391 p += t;
392 q >>= 1;
393 t <<= 1;
394 counter++;
395 }
396 while ((counter < 64) && ((q.m_hi != 0) || (q.m_lo != 0)));
397 return p;
398 }
399
400 wxLongLongWx& wxLongLongWx::operator*=(const wxLongLongWx& ll)
401 {
402 wxLongLongWx t(m_hi, m_lo);
403 wxLongLongWx q(ll.m_hi, ll.m_lo);
404 int counter = 0;
405
406 do
407 {
408 if ((q.m_lo & 1) != 0)
409 *this += t;
410 q >>= 1;
411 t <<= 1;
412 counter++;
413 }
414 while ((counter < 64) && ((q.m_hi != 0) || (q.m_lo != 0)));
415 return *this;
416 }
417
418 // division
419
420 void wxLongLongWx::Divide(const wxLongLongWx& divisor, wxLongLongWx& quotient, wxLongLongWx& remainder) const
421 {
422 if ((divisor.m_lo == 0) && (divisor.m_hi == 0))
423 {
424 // provoke division by zero error and silence the compilers warnings
425 // about an expression without effect and unused variable
426 long dummy = divisor.m_lo/divisor.m_hi;
427 dummy += 0;
428 }
429
430 wxFAIL_MSG("not implemented");
431 }
432
433 // temporary - just for testing
434 void *wxLongLongWx::asArray(void) const
435 {
436 static unsigned char temp[8];
437
438 temp[0] = (m_hi >> 24) & 0xFF;
439 temp[1] = (m_hi >> 16) & 0xFF;
440 temp[2] = (m_hi >> 8) & 0xFF;
441 temp[3] = (m_hi >> 0) & 0xFF;
442 temp[4] = (m_lo >> 24) & 0xFF;
443 temp[5] = (m_lo >> 16) & 0xFF;
444 temp[6] = (m_lo >> 8) & 0xFF;
445 temp[7] = (m_lo >> 0) & 0xFF;
446
447 return temp;
448 }
449
450 // input/output
451
452 ostream& operator<< (ostream& o, const wxLongLongWx& ll)
453 {
454 char result[65];
455
456 memset(result, 'A', 64);
457
458 result[64] = '\0';
459
460 for (int i = 0; i < 32; i++)
461 {
462 result[31 - i] = (char) ('0' + (int) ((ll.m_hi >> i) & 1));
463 result[63 - i] = (char) ('0' + (int) ((ll.m_lo >> i) & 1));
464 }
465
466 return o << result;
467 }
468 #endif wxUSE_LONGLONG_WX
469