1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/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 wxWidgets 2.0! It is intentionally
6 // not documented and is for private use only.
10 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
11 // Licence: wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
14 // ============================================================================
16 // ============================================================================
18 #include "wx/wxprec.h"
26 #include "wx/longlong.h"
29 #include "wx/math.h" // for fabs()
33 #include "wx/txtstrm.h"
36 #include <string.h> // for memset()
38 #include "wx/ioswrap.h"
40 // ============================================================================
42 // ============================================================================
44 #if wxUSE_LONGLONG_NATIVE
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 void *wxLongLongNative::asArray() const
52 static unsigned char temp
[8];
54 temp
[0] = wx_truncate_cast(unsigned char, ((m_ll
>> 56) & 0xFF));
55 temp
[1] = wx_truncate_cast(unsigned char, ((m_ll
>> 48) & 0xFF));
56 temp
[2] = wx_truncate_cast(unsigned char, ((m_ll
>> 40) & 0xFF));
57 temp
[3] = wx_truncate_cast(unsigned char, ((m_ll
>> 32) & 0xFF));
58 temp
[4] = wx_truncate_cast(unsigned char, ((m_ll
>> 24) & 0xFF));
59 temp
[5] = wx_truncate_cast(unsigned char, ((m_ll
>> 16) & 0xFF));
60 temp
[6] = wx_truncate_cast(unsigned char, ((m_ll
>> 8) & 0xFF));
61 temp
[7] = wx_truncate_cast(unsigned char, ((m_ll
>> 0) & 0xFF));
66 void *wxULongLongNative::asArray() const
68 static unsigned char temp
[8];
70 temp
[0] = wx_truncate_cast(unsigned char, ((m_ll
>> 56) & 0xFF));
71 temp
[1] = wx_truncate_cast(unsigned char, ((m_ll
>> 48) & 0xFF));
72 temp
[2] = wx_truncate_cast(unsigned char, ((m_ll
>> 40) & 0xFF));
73 temp
[3] = wx_truncate_cast(unsigned char, ((m_ll
>> 32) & 0xFF));
74 temp
[4] = wx_truncate_cast(unsigned char, ((m_ll
>> 24) & 0xFF));
75 temp
[5] = wx_truncate_cast(unsigned char, ((m_ll
>> 16) & 0xFF));
76 temp
[6] = wx_truncate_cast(unsigned char, ((m_ll
>> 8) & 0xFF));
77 temp
[7] = wx_truncate_cast(unsigned char, ((m_ll
>> 0) & 0xFF));
83 wxLongLongNative::wxLongLongNative(wxLongLongWx ll
)
85 // assign first to avoid precision loss!
91 wxLongLongNative
& wxLongLongNative::operator=(wxLongLongWx ll
)
93 // assign first to avoid precision loss!
100 wxLongLongNative
& wxLongLongNative::operator=(const class wxULongLongWx
&ll
)
102 // assign first to avoid precision loss!
109 wxULongLongNative::wxULongLongNative(const class wxULongLongWx
&ll
)
111 // assign first to avoid precision loss!
114 m_ll
|= ((unsigned long) ll
.GetLo());
117 wxULongLongNative
& wxULongLongNative::operator=(wxLongLongWx ll
)
119 // assign first to avoid precision loss!
122 m_ll
|= ((unsigned long) ll
.GetLo());
126 wxULongLongNative
& wxULongLongNative::operator=(const class wxULongLongWx
&ll
)
128 // assign first to avoid precision loss!
131 m_ll
|= ((unsigned long) ll
.GetLo());
137 double wxULongLongNative::ToDouble() const
139 // Work around the problem of casting unsigned __int64 to double in VC6
140 // (which for unknown reasons only manifests itself in DLL builds, i.e.
142 static const __int64 int64_t_max
= 9223372036854775807i64
;
143 if ( m_ll
<= int64_t_max
)
144 return wx_truncate_cast(double, (wxLongLong_t
)m_ll
);
146 double d
= wx_truncate_cast(double, int64_t_max
);
147 d
+= (__int64
)(m_ll
- int64_t_max
- 1); // The cast is safe because of -1
150 #endif // __VISUALC6__
152 #endif // wxUSE_LONGLONG_NATIVE
154 // ============================================================================
155 // wxLongLongWx: emulation of 'long long' using 2 longs
156 // ============================================================================
158 #if wxUSE_LONGLONG_WX
160 // Set value from unsigned wxULongLongWx
161 wxLongLongWx
&wxLongLongWx::operator=(const class wxULongLongWx
&ll
)
163 m_hi
= (unsigned long) ll
.GetHi();
169 wxLongLongWx
& wxLongLongWx::Assign(double d
)
171 bool positive
= d
>= 0;
173 if ( d
<= ULONG_MAX
)
180 m_hi
= (unsigned long)(d
/ (1.0 + (double)ULONG_MAX
));
181 m_lo
= (unsigned long)(d
- ((double)m_hi
* (1.0 + (double)ULONG_MAX
)));
184 #ifdef wxLONGLONG_TEST_MODE
185 m_ll
= (wxLongLong_t
)d
;
188 #endif // wxLONGLONG_TEST_MODE
196 double wxLongLongWx::ToDouble() const
199 d
*= 1.0 + (double)ULONG_MAX
;
202 #ifdef wxLONGLONG_TEST_MODE
203 wxASSERT( d
== m_ll
);
204 #endif // wxLONGLONG_TEST_MODE
209 double wxULongLongWx::ToDouble() const
211 unsigned double d
= m_hi
;
212 d
*= 1.0 + (double)ULONG_MAX
;
215 #ifdef wxLONGLONG_TEST_MODE
216 wxASSERT( d
== m_ll
);
217 #endif // wxLONGLONG_TEST_MODE
222 wxLongLongWx
wxLongLongWx::operator<<(int shift
) const
224 wxLongLongWx
ll(*this);
230 wxULongLongWx
wxULongLongWx::operator<<(int shift
) const
232 wxULongLongWx
ll(*this);
238 wxLongLongWx
& wxLongLongWx::operator<<=(int shift
)
245 m_hi
|= m_lo
>> (32 - shift
);
250 m_hi
= m_lo
<< (shift
- 32);
255 #ifdef wxLONGLONG_TEST_MODE
259 #endif // wxLONGLONG_TEST_MODE
264 wxULongLongWx
& wxULongLongWx::operator<<=(int shift
)
271 m_hi
|= m_lo
>> (32 - shift
);
276 m_hi
= m_lo
<< (shift
- 32);
281 #ifdef wxLONGLONG_TEST_MODE
285 #endif // wxLONGLONG_TEST_MODE
290 wxLongLongWx
wxLongLongWx::operator>>(int shift
) const
292 wxLongLongWx
ll(*this);
298 wxULongLongWx
wxULongLongWx::operator>>(int shift
) const
300 wxULongLongWx
ll(*this);
306 wxLongLongWx
& wxLongLongWx::operator>>=(int shift
)
313 m_lo
|= m_hi
<< (32 - shift
);
318 m_lo
= m_hi
>> (shift
- 32);
319 m_hi
= (m_hi
< 0 ? -1L : 0);
323 #ifdef wxLONGLONG_TEST_MODE
327 #endif // wxLONGLONG_TEST_MODE
332 wxULongLongWx
& wxULongLongWx::operator>>=(int shift
)
339 m_lo
|= m_hi
<< (32 - shift
);
344 m_lo
= m_hi
>> (shift
- 32);
349 #ifdef wxLONGLONG_TEST_MODE
353 #endif // wxLONGLONG_TEST_MODE
358 wxLongLongWx
wxLongLongWx::operator+(const wxLongLongWx
& ll
) const
360 wxLongLongWx
res(*this);
366 wxULongLongWx
wxULongLongWx::operator+(const wxULongLongWx
& ll
) const
368 wxULongLongWx
res(*this);
374 wxLongLongWx
wxLongLongWx::operator+(long l
) const
376 wxLongLongWx
res(*this);
382 wxULongLongWx
wxULongLongWx::operator+(unsigned long l
) const
384 wxULongLongWx
res(*this);
390 wxLongLongWx
& wxLongLongWx::operator+=(const wxLongLongWx
& ll
)
392 unsigned long previous
= m_lo
;
397 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
400 #ifdef wxLONGLONG_TEST_MODE
404 #endif // wxLONGLONG_TEST_MODE
409 wxULongLongWx
& wxULongLongWx::operator+=(const wxULongLongWx
& ll
)
411 unsigned long previous
= m_lo
;
416 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
419 #ifdef wxLONGLONG_TEST_MODE
423 #endif // wxLONGLONG_TEST_MODE
428 wxLongLongWx
& wxLongLongWx::operator+=(long l
)
430 unsigned long previous
= m_lo
;
436 if ((m_lo
< previous
) || (m_lo
< (unsigned long)l
))
439 #ifdef wxLONGLONG_TEST_MODE
443 #endif // wxLONGLONG_TEST_MODE
448 wxULongLongWx
& wxULongLongWx::operator+=(unsigned long l
)
450 unsigned long previous
= m_lo
;
454 if ((m_lo
< previous
) || (m_lo
< l
))
457 #ifdef wxLONGLONG_TEST_MODE
461 #endif // wxLONGLONG_TEST_MODE
467 wxLongLongWx
& wxLongLongWx::operator++()
473 #ifdef wxLONGLONG_TEST_MODE
477 #endif // wxLONGLONG_TEST_MODE
482 wxULongLongWx
& wxULongLongWx::operator++()
488 #ifdef wxLONGLONG_TEST_MODE
492 #endif // wxLONGLONG_TEST_MODE
498 wxLongLongWx
wxLongLongWx::operator-() const
500 wxLongLongWx
res(*this);
506 wxLongLongWx
& wxLongLongWx::Negate()
515 #ifdef wxLONGLONG_TEST_MODE
519 #endif // wxLONGLONG_TEST_MODE
526 wxLongLongWx
wxLongLongWx::operator-(const wxLongLongWx
& ll
) const
528 wxLongLongWx
res(*this);
534 wxLongLongWx
wxULongLongWx::operator-(const wxULongLongWx
& ll
) const
536 wxASSERT(m_hi
<= LONG_MAX
);
537 wxASSERT(ll
.m_hi
<= LONG_MAX
);
539 wxLongLongWx
res( (long)m_hi
, m_lo
);
540 wxLongLongWx
op( (long)ll
.m_hi
, ll
.m_lo
);
546 wxLongLongWx
& wxLongLongWx::operator-=(const wxLongLongWx
& ll
)
548 unsigned long previous
= m_lo
;
553 if (previous
< ll
.m_lo
)
556 #ifdef wxLONGLONG_TEST_MODE
560 #endif // wxLONGLONG_TEST_MODE
565 wxULongLongWx
& wxULongLongWx::operator-=(const wxULongLongWx
& ll
)
567 unsigned long previous
= m_lo
;
572 if (previous
< ll
.m_lo
)
575 #ifdef wxLONGLONG_TEST_MODE
579 #endif // wxLONGLONG_TEST_MODE
585 wxLongLongWx
& wxLongLongWx::operator--()
588 if (m_lo
== 0xFFFFFFFF)
591 #ifdef wxLONGLONG_TEST_MODE
595 #endif // wxLONGLONG_TEST_MODE
600 wxULongLongWx
& wxULongLongWx::operator--()
603 if (m_lo
== 0xFFFFFFFF)
606 #ifdef wxLONGLONG_TEST_MODE
610 #endif // wxLONGLONG_TEST_MODE
615 // comparison operators
617 bool wxLongLongWx::operator<(const wxLongLongWx
& ll
) const
619 if ( m_hi
< ll
.m_hi
)
621 else if ( m_hi
== ll
.m_hi
)
622 return m_lo
< ll
.m_lo
;
627 bool wxULongLongWx::operator<(const wxULongLongWx
& ll
) const
629 if ( m_hi
< ll
.m_hi
)
631 else if ( m_hi
== ll
.m_hi
)
632 return m_lo
< ll
.m_lo
;
637 bool wxLongLongWx::operator>(const wxLongLongWx
& ll
) const
639 if ( m_hi
> ll
.m_hi
)
641 else if ( m_hi
== ll
.m_hi
)
642 return m_lo
> ll
.m_lo
;
647 bool wxULongLongWx::operator>(const wxULongLongWx
& ll
) const
649 if ( m_hi
> ll
.m_hi
)
651 else if ( m_hi
== ll
.m_hi
)
652 return m_lo
> ll
.m_lo
;
659 wxLongLongWx
wxLongLongWx::operator&(const wxLongLongWx
& ll
) const
661 return wxLongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
664 wxULongLongWx
wxULongLongWx::operator&(const wxULongLongWx
& ll
) const
666 return wxULongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
669 wxLongLongWx
wxLongLongWx::operator|(const wxLongLongWx
& ll
) const
671 return wxLongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
674 wxULongLongWx
wxULongLongWx::operator|(const wxULongLongWx
& ll
) const
676 return wxULongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
679 wxLongLongWx
wxLongLongWx::operator^(const wxLongLongWx
& ll
) const
681 return wxLongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
684 wxULongLongWx
wxULongLongWx::operator^(const wxULongLongWx
& ll
) const
686 return wxULongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
689 wxLongLongWx
& wxLongLongWx::operator&=(const wxLongLongWx
& ll
)
694 #ifdef wxLONGLONG_TEST_MODE
698 #endif // wxLONGLONG_TEST_MODE
703 wxULongLongWx
& wxULongLongWx::operator&=(const wxULongLongWx
& ll
)
708 #ifdef wxLONGLONG_TEST_MODE
712 #endif // wxLONGLONG_TEST_MODE
717 wxLongLongWx
& wxLongLongWx::operator|=(const wxLongLongWx
& ll
)
722 #ifdef wxLONGLONG_TEST_MODE
726 #endif // wxLONGLONG_TEST_MODE
731 wxULongLongWx
& wxULongLongWx::operator|=(const wxULongLongWx
& ll
)
736 #ifdef wxLONGLONG_TEST_MODE
740 #endif // wxLONGLONG_TEST_MODE
745 wxLongLongWx
& wxLongLongWx::operator^=(const wxLongLongWx
& ll
)
750 #ifdef wxLONGLONG_TEST_MODE
754 #endif // wxLONGLONG_TEST_MODE
759 wxULongLongWx
& wxULongLongWx::operator^=(const wxULongLongWx
& ll
)
764 #ifdef wxLONGLONG_TEST_MODE
768 #endif // wxLONGLONG_TEST_MODE
773 wxLongLongWx
wxLongLongWx::operator~() const
775 return wxLongLongWx(~m_hi
, ~m_lo
);
778 wxULongLongWx
wxULongLongWx::operator~() const
780 return wxULongLongWx(~m_hi
, ~m_lo
);
785 wxLongLongWx
wxLongLongWx::operator*(const wxLongLongWx
& ll
) const
787 wxLongLongWx
res(*this);
793 wxULongLongWx
wxULongLongWx::operator*(const wxULongLongWx
& ll
) const
795 wxULongLongWx
res(*this);
801 wxLongLongWx
& wxLongLongWx::operator*=(const wxLongLongWx
& ll
)
803 wxLongLongWx
t(m_hi
, m_lo
);
804 wxLongLongWx
q(ll
.m_hi
, ll
.m_lo
);
808 #ifdef wxLONGLONG_TEST_MODE
809 wxLongLong_t llOld
= m_ll
;
811 #endif // wxLONGLONG_TEST_MODE
816 if ((q
.m_lo
& 1) != 0)
822 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
824 #ifdef wxLONGLONG_TEST_MODE
825 m_ll
= llOld
* ll
.m_ll
;
828 #endif // wxLONGLONG_TEST_MODE
833 wxULongLongWx
& wxULongLongWx::operator*=(const wxULongLongWx
& ll
)
835 wxULongLongWx
t(m_hi
, m_lo
);
836 wxULongLongWx
q(ll
.m_hi
, ll
.m_lo
);
840 #ifdef wxLONGLONG_TEST_MODE
841 wxULongLong_t llOld
= m_ll
;
843 #endif // wxLONGLONG_TEST_MODE
848 if ((q
.m_lo
& 1) != 0)
854 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
856 #ifdef wxLONGLONG_TEST_MODE
857 m_ll
= llOld
* ll
.m_ll
;
860 #endif // wxLONGLONG_TEST_MODE
867 #define IS_MSB_SET(ll) ((ll.GetHi()) & (1 << (8*sizeof(long) - 1)))
869 void wxLongLongWx::Divide(const wxLongLongWx
& divisorIn
,
870 wxLongLongWx
& quotient
,
871 wxLongLongWx
& remainderIO
) const
873 if ((divisorIn
.m_lo
== 0) && (divisorIn
.m_hi
== 0))
875 // provoke division by zero error and silence the compilers warnings
876 // about an expression without effect and unused variable
877 long dummy
= divisorIn
.m_lo
/divisorIn
.m_hi
;
881 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
882 // do this - any improvements are more than welcome
884 // code inspired by the snippet at
885 // http://www.bearcave.com/software/divide.htm
889 // Use of this program, for any purpose, is granted the author, Ian
890 // Kaplan, as long as this copyright notice is included in the source
891 // code or any source code derived from this program. The user assumes
892 // all responsibility for using this code.
895 wxULongLongWx dividend
, divisor
, remainder
;
900 // always do unsigned division and adjust the signs later: in C integer
901 // division, the sign of the remainder is the same as the sign of the
902 // dividend, while the sign of the quotient is the product of the signs of
903 // the dividend and divisor. Of course, we also always have
905 // dividend = quotient*divisor + remainder
907 // with 0 <= abs(remainder) < abs(divisor)
908 bool negRemainder
= GetHi() < 0;
909 bool negQuotient
= false; // assume positive
912 negQuotient
= !negQuotient
;
917 if ( divisorIn
.GetHi() < 0 )
919 negQuotient
= !negQuotient
;
920 divisor
= -divisorIn
;
925 // check for some particular cases
926 if ( divisor
> dividend
)
928 remainder
= dividend
;
930 else if ( divisor
== dividend
)
936 // here: dividend > divisor and both are positive: do unsigned division
940 while ( remainder
< divisor
)
943 if ( IS_MSB_SET(dividend
) )
954 // undo the last loop iteration
959 for ( size_t i
= 0; i
< nBits
; i
++ )
962 if ( IS_MSB_SET(dividend
) )
967 wxLongLongWx t
= remainder
- divisor
;
970 if ( !IS_MSB_SET(t
) )
979 remainderIO
= remainder
;
984 remainderIO
= -remainderIO
;
989 quotient
= -quotient
;
993 void wxULongLongWx::Divide(const wxULongLongWx
& divisorIn
,
994 wxULongLongWx
& quotient
,
995 wxULongLongWx
& remainder
) const
997 if ((divisorIn
.m_lo
== 0) && (divisorIn
.m_hi
== 0))
999 // provoke division by zero error and silence the compilers warnings
1000 // about an expression without effect and unused variable
1001 unsigned long dummy
= divisorIn
.m_lo
/divisorIn
.m_hi
;
1005 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
1006 // do this - any improvements are more than welcome
1008 // code inspired by the snippet at
1009 // http://www.bearcave.com/software/divide.htm
1011 // Copyright notice:
1013 // Use of this program, for any purpose, is granted the author, Ian
1014 // Kaplan, as long as this copyright notice is included in the source
1015 // code or any source code derived from this program. The user assumes
1016 // all responsibility for using this code.
1019 wxULongLongWx dividend
= *this,
1020 divisor
= divisorIn
;
1025 // check for some particular cases
1026 if ( divisor
> dividend
)
1028 remainder
= dividend
;
1030 else if ( divisor
== dividend
)
1036 // here: dividend > divisor
1040 while ( remainder
< divisor
)
1043 if ( IS_MSB_SET(dividend
) )
1054 // undo the last loop iteration
1059 for ( size_t i
= 0; i
< nBits
; i
++ )
1062 if ( IS_MSB_SET(dividend
) )
1067 wxULongLongWx t
= remainder
- divisor
;
1070 if ( !IS_MSB_SET(t
) )
1080 wxLongLongWx
wxLongLongWx::operator/(const wxLongLongWx
& ll
) const
1082 wxLongLongWx quotient
, remainder
;
1084 Divide(ll
, quotient
, remainder
);
1089 wxULongLongWx
wxULongLongWx::operator/(const wxULongLongWx
& ll
) const
1091 wxULongLongWx quotient
, remainder
;
1093 Divide(ll
, quotient
, remainder
);
1098 wxLongLongWx
& wxLongLongWx::operator/=(const wxLongLongWx
& ll
)
1100 wxLongLongWx quotient
, remainder
;
1102 Divide(ll
, quotient
, remainder
);
1109 wxULongLongWx
& wxULongLongWx::operator/=(const wxULongLongWx
& ll
)
1111 wxULongLongWx quotient
, remainder
;
1113 Divide(ll
, quotient
, remainder
);
1120 wxLongLongWx
wxLongLongWx::operator%(const wxLongLongWx
& ll
) const
1122 wxLongLongWx quotient
, remainder
;
1124 Divide(ll
, quotient
, remainder
);
1129 wxULongLongWx
wxULongLongWx::operator%(const wxULongLongWx
& ll
) const
1131 wxULongLongWx quotient
, remainder
;
1133 Divide(ll
, quotient
, remainder
);
1138 // ----------------------------------------------------------------------------
1140 // ----------------------------------------------------------------------------
1142 // temporary - just for testing
1143 void *wxLongLongWx::asArray(void) const
1145 static unsigned char temp
[8];
1147 temp
[0] = (char)((m_hi
>> 24) & 0xFF);
1148 temp
[1] = (char)((m_hi
>> 16) & 0xFF);
1149 temp
[2] = (char)((m_hi
>> 8) & 0xFF);
1150 temp
[3] = (char)((m_hi
>> 0) & 0xFF);
1151 temp
[4] = (char)((m_lo
>> 24) & 0xFF);
1152 temp
[5] = (char)((m_lo
>> 16) & 0xFF);
1153 temp
[6] = (char)((m_lo
>> 8) & 0xFF);
1154 temp
[7] = (char)((m_lo
>> 0) & 0xFF);
1159 void *wxULongLongWx::asArray(void) const
1161 static unsigned char temp
[8];
1163 temp
[0] = (char)((m_hi
>> 24) & 0xFF);
1164 temp
[1] = (char)((m_hi
>> 16) & 0xFF);
1165 temp
[2] = (char)((m_hi
>> 8) & 0xFF);
1166 temp
[3] = (char)((m_hi
>> 0) & 0xFF);
1167 temp
[4] = (char)((m_lo
>> 24) & 0xFF);
1168 temp
[5] = (char)((m_lo
>> 16) & 0xFF);
1169 temp
[6] = (char)((m_lo
>> 8) & 0xFF);
1170 temp
[7] = (char)((m_lo
>> 0) & 0xFF);
1175 #endif // wxUSE_LONGLONG_WX
1177 #define LL_TO_STRING(name) \
1178 wxString name::ToString() const \
1180 /* TODO: this is awfully inefficient, anything better? */ \
1185 bool neg = ll < 0; \
1190 long digit = (ll % 10).ToLong(); \
1191 result.Prepend((wxChar)(wxT('0') - digit)); \
1199 long digit = (ll % 10).ToLong(); \
1200 result.Prepend((wxChar)(wxT('0') + digit)); \
1205 if ( result.empty() ) \
1206 result = wxT('0'); \
1208 result.Prepend(wxT('-')); \
1213 #define ULL_TO_STRING(name) \
1214 wxString name::ToString() const \
1216 /* TODO: this is awfully inefficient, anything better? */ \
1223 result.Prepend((wxChar)(wxT('0') + (ll % 10).ToULong())); \
1227 if ( result.empty() ) \
1228 result = wxT('0'); \
1233 #if wxUSE_LONGLONG_NATIVE
1234 LL_TO_STRING(wxLongLongNative
)
1235 ULL_TO_STRING(wxULongLongNative
)
1238 #if wxUSE_LONGLONG_WX
1239 LL_TO_STRING(wxLongLongWx
)
1240 ULL_TO_STRING(wxULongLongWx
)
1243 #if wxUSE_STD_IOSTREAM
1247 wxSTD ostream
& operator<< (wxSTD ostream
& o
, const wxLongLong
& ll
)
1249 return o
<< ll
.ToString();
1253 wxSTD ostream
& operator<< (wxSTD ostream
& o
, const wxULongLong
& ll
)
1255 return o
<< ll
.ToString();
1258 #endif // wxUSE_STD_IOSTREAM
1260 WXDLLIMPEXP_BASE wxString
& operator<< (wxString
& s
, const wxLongLong
& ll
)
1262 return s
<< ll
.ToString();
1265 WXDLLIMPEXP_BASE wxString
& operator<< (wxString
& s
, const wxULongLong
& ll
)
1267 return s
<< ll
.ToString();
1272 WXDLLIMPEXP_BASE wxTextOutputStream
& operator<< (wxTextOutputStream
& o
, const wxULongLong
& ll
)
1274 return o
<< ll
.ToString();
1277 WXDLLIMPEXP_BASE wxTextOutputStream
& operator<< (wxTextOutputStream
& o
, const wxLongLong
& ll
)
1279 return o
<< ll
.ToString();
1282 #define READ_STRING_CHAR(s, idx, len) ((idx!=len) ? (wxChar)s[idx++] : wxT('\0'))
1284 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxULongLong
&ll
)
1286 wxString s
= o
.ReadWord();
1288 ll
= wxULongLong(0l, 0l);
1289 size_t length
= s
.length();
1292 wxChar ch
= READ_STRING_CHAR(s
, idx
, length
);
1295 while (ch
==wxT(' ') || ch
==wxT('\t'))
1296 ch
= READ_STRING_CHAR(s
, idx
, length
);
1299 wxULongLong
multiplier(0l, 10l);
1300 while (ch
>=wxT('0') && ch
<=wxT('9')) {
1301 long lValue
= (unsigned) (ch
- wxT('0'));
1302 ll
= ll
* multiplier
+ wxULongLong(0l, lValue
);
1303 ch
= READ_STRING_CHAR(s
, idx
, length
);
1309 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxLongLong
&ll
)
1311 wxString s
= o
.ReadWord();
1313 ll
= wxLongLong(0l, 0l);
1314 size_t length
= s
.length();
1317 wxChar ch
= READ_STRING_CHAR(s
, idx
, length
);
1320 while (ch
==wxT(' ') || ch
==wxT('\t'))
1321 ch
= READ_STRING_CHAR(s
, idx
, length
);
1325 if (ch
==wxT('-') || ch
==wxT('+')) {
1326 iSign
= ((ch
==wxT('-')) ? -1 : 1);
1327 ch
= READ_STRING_CHAR(s
, idx
, length
);
1331 wxLongLong
multiplier(0l, 10l);
1332 while (ch
>=wxT('0') && ch
<=wxT('9')) {
1333 long lValue
= (unsigned) (ch
- wxT('0'));
1334 ll
= ll
* multiplier
+ wxLongLong(0l, lValue
);
1335 ch
= READ_STRING_CHAR(s
, idx
, length
);
1338 #if wxUSE_LONGLONG_NATIVE
1339 ll
= ll
* wxLongLong((wxLongLong_t
) iSign
);
1341 ll
= ll
* wxLongLong((long) iSign
);
1347 #if wxUSE_LONGLONG_NATIVE
1349 WXDLLIMPEXP_BASE
class wxTextOutputStream
&operator<<(class wxTextOutputStream
&o
, wxULongLong_t value
)
1351 return o
<< wxULongLong(value
).ToString();
1354 WXDLLIMPEXP_BASE
class wxTextOutputStream
&operator<<(class wxTextOutputStream
&o
, wxLongLong_t value
)
1356 return o
<< wxLongLong(value
).ToString();
1359 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxULongLong_t
&value
)
1363 value
= ll
.GetValue();
1367 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxLongLong_t
&value
)
1371 value
= ll
.GetValue();
1375 #endif // wxUSE_LONGLONG_NATIVE
1377 #endif // wxUSE_STREAMS
1379 #endif // wxUSE_LONGLONG