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.
9 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 // ============================================================================
15 // ============================================================================
17 #include "wx/wxprec.h"
25 #include "wx/longlong.h"
28 #include "wx/math.h" // for fabs()
32 #include "wx/txtstrm.h"
35 #include <string.h> // for memset()
37 #include "wx/ioswrap.h"
39 // ============================================================================
41 // ============================================================================
43 #if wxUSE_LONGLONG_NATIVE
45 // ----------------------------------------------------------------------------
47 // ----------------------------------------------------------------------------
49 void *wxLongLongNative::asArray() const
51 static unsigned char temp
[8];
53 temp
[0] = wx_truncate_cast(unsigned char, ((m_ll
>> 56) & 0xFF));
54 temp
[1] = wx_truncate_cast(unsigned char, ((m_ll
>> 48) & 0xFF));
55 temp
[2] = wx_truncate_cast(unsigned char, ((m_ll
>> 40) & 0xFF));
56 temp
[3] = wx_truncate_cast(unsigned char, ((m_ll
>> 32) & 0xFF));
57 temp
[4] = wx_truncate_cast(unsigned char, ((m_ll
>> 24) & 0xFF));
58 temp
[5] = wx_truncate_cast(unsigned char, ((m_ll
>> 16) & 0xFF));
59 temp
[6] = wx_truncate_cast(unsigned char, ((m_ll
>> 8) & 0xFF));
60 temp
[7] = wx_truncate_cast(unsigned char, ((m_ll
>> 0) & 0xFF));
65 void *wxULongLongNative::asArray() const
67 static unsigned char temp
[8];
69 temp
[0] = wx_truncate_cast(unsigned char, ((m_ll
>> 56) & 0xFF));
70 temp
[1] = wx_truncate_cast(unsigned char, ((m_ll
>> 48) & 0xFF));
71 temp
[2] = wx_truncate_cast(unsigned char, ((m_ll
>> 40) & 0xFF));
72 temp
[3] = wx_truncate_cast(unsigned char, ((m_ll
>> 32) & 0xFF));
73 temp
[4] = wx_truncate_cast(unsigned char, ((m_ll
>> 24) & 0xFF));
74 temp
[5] = wx_truncate_cast(unsigned char, ((m_ll
>> 16) & 0xFF));
75 temp
[6] = wx_truncate_cast(unsigned char, ((m_ll
>> 8) & 0xFF));
76 temp
[7] = wx_truncate_cast(unsigned char, ((m_ll
>> 0) & 0xFF));
82 wxLongLongNative::wxLongLongNative(wxLongLongWx ll
)
84 // assign first to avoid precision loss!
90 wxLongLongNative
& wxLongLongNative::operator=(wxLongLongWx ll
)
92 // assign first to avoid precision loss!
99 wxLongLongNative
& wxLongLongNative::operator=(const class wxULongLongWx
&ll
)
101 // assign first to avoid precision loss!
108 wxULongLongNative::wxULongLongNative(const class wxULongLongWx
&ll
)
110 // assign first to avoid precision loss!
113 m_ll
|= ((unsigned long) ll
.GetLo());
116 wxULongLongNative
& wxULongLongNative::operator=(wxLongLongWx ll
)
118 // assign first to avoid precision loss!
121 m_ll
|= ((unsigned long) ll
.GetLo());
125 wxULongLongNative
& wxULongLongNative::operator=(const class wxULongLongWx
&ll
)
127 // assign first to avoid precision loss!
130 m_ll
|= ((unsigned long) ll
.GetLo());
136 double wxULongLongNative::ToDouble() const
138 // Work around the problem of casting unsigned __int64 to double in VC6
139 // (which for unknown reasons only manifests itself in DLL builds, i.e.
141 static const __int64 int64_t_max
= 9223372036854775807i64
;
142 if ( m_ll
<= int64_t_max
)
143 return wx_truncate_cast(double, (wxLongLong_t
)m_ll
);
145 double d
= wx_truncate_cast(double, int64_t_max
);
146 d
+= (__int64
)(m_ll
- int64_t_max
- 1); // The cast is safe because of -1
149 #endif // __VISUALC6__
151 #endif // wxUSE_LONGLONG_NATIVE
153 // ============================================================================
154 // wxLongLongWx: emulation of 'long long' using 2 longs
155 // ============================================================================
157 #if wxUSE_LONGLONG_WX
159 // Set value from unsigned wxULongLongWx
160 wxLongLongWx
&wxLongLongWx::operator=(const class wxULongLongWx
&ll
)
162 m_hi
= (unsigned long) ll
.GetHi();
168 wxLongLongWx
& wxLongLongWx::Assign(double d
)
170 bool positive
= d
>= 0;
172 if ( d
<= ULONG_MAX
)
179 m_hi
= (unsigned long)(d
/ (1.0 + (double)ULONG_MAX
));
180 m_lo
= (unsigned long)(d
- ((double)m_hi
* (1.0 + (double)ULONG_MAX
)));
183 #ifdef wxLONGLONG_TEST_MODE
184 m_ll
= (wxLongLong_t
)d
;
187 #endif // wxLONGLONG_TEST_MODE
195 double wxLongLongWx::ToDouble() const
198 d
*= 1.0 + (double)ULONG_MAX
;
201 #ifdef wxLONGLONG_TEST_MODE
202 wxASSERT( d
== m_ll
);
203 #endif // wxLONGLONG_TEST_MODE
208 double wxULongLongWx::ToDouble() const
210 unsigned double d
= m_hi
;
211 d
*= 1.0 + (double)ULONG_MAX
;
214 #ifdef wxLONGLONG_TEST_MODE
215 wxASSERT( d
== m_ll
);
216 #endif // wxLONGLONG_TEST_MODE
221 wxLongLongWx
wxLongLongWx::operator<<(int shift
) const
223 wxLongLongWx
ll(*this);
229 wxULongLongWx
wxULongLongWx::operator<<(int shift
) const
231 wxULongLongWx
ll(*this);
237 wxLongLongWx
& wxLongLongWx::operator<<=(int shift
)
244 m_hi
|= m_lo
>> (32 - shift
);
249 m_hi
= m_lo
<< (shift
- 32);
254 #ifdef wxLONGLONG_TEST_MODE
258 #endif // wxLONGLONG_TEST_MODE
263 wxULongLongWx
& wxULongLongWx::operator<<=(int shift
)
270 m_hi
|= m_lo
>> (32 - shift
);
275 m_hi
= m_lo
<< (shift
- 32);
280 #ifdef wxLONGLONG_TEST_MODE
284 #endif // wxLONGLONG_TEST_MODE
289 wxLongLongWx
wxLongLongWx::operator>>(int shift
) const
291 wxLongLongWx
ll(*this);
297 wxULongLongWx
wxULongLongWx::operator>>(int shift
) const
299 wxULongLongWx
ll(*this);
305 wxLongLongWx
& wxLongLongWx::operator>>=(int shift
)
312 m_lo
|= m_hi
<< (32 - shift
);
317 m_lo
= m_hi
>> (shift
- 32);
318 m_hi
= (m_hi
< 0 ? -1L : 0);
322 #ifdef wxLONGLONG_TEST_MODE
326 #endif // wxLONGLONG_TEST_MODE
331 wxULongLongWx
& wxULongLongWx::operator>>=(int shift
)
338 m_lo
|= m_hi
<< (32 - shift
);
343 m_lo
= m_hi
>> (shift
- 32);
348 #ifdef wxLONGLONG_TEST_MODE
352 #endif // wxLONGLONG_TEST_MODE
357 wxLongLongWx
wxLongLongWx::operator+(const wxLongLongWx
& ll
) const
359 wxLongLongWx
res(*this);
365 wxULongLongWx
wxULongLongWx::operator+(const wxULongLongWx
& ll
) const
367 wxULongLongWx
res(*this);
373 wxLongLongWx
wxLongLongWx::operator+(long l
) const
375 wxLongLongWx
res(*this);
381 wxULongLongWx
wxULongLongWx::operator+(unsigned long l
) const
383 wxULongLongWx
res(*this);
389 wxLongLongWx
& wxLongLongWx::operator+=(const wxLongLongWx
& ll
)
391 unsigned long previous
= m_lo
;
396 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
399 #ifdef wxLONGLONG_TEST_MODE
403 #endif // wxLONGLONG_TEST_MODE
408 wxULongLongWx
& wxULongLongWx::operator+=(const wxULongLongWx
& ll
)
410 unsigned long previous
= m_lo
;
415 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
418 #ifdef wxLONGLONG_TEST_MODE
422 #endif // wxLONGLONG_TEST_MODE
427 wxLongLongWx
& wxLongLongWx::operator+=(long l
)
429 unsigned long previous
= m_lo
;
435 if ((m_lo
< previous
) || (m_lo
< (unsigned long)l
))
438 #ifdef wxLONGLONG_TEST_MODE
442 #endif // wxLONGLONG_TEST_MODE
447 wxULongLongWx
& wxULongLongWx::operator+=(unsigned long l
)
449 unsigned long previous
= m_lo
;
453 if ((m_lo
< previous
) || (m_lo
< l
))
456 #ifdef wxLONGLONG_TEST_MODE
460 #endif // wxLONGLONG_TEST_MODE
466 wxLongLongWx
& wxLongLongWx::operator++()
472 #ifdef wxLONGLONG_TEST_MODE
476 #endif // wxLONGLONG_TEST_MODE
481 wxULongLongWx
& wxULongLongWx::operator++()
487 #ifdef wxLONGLONG_TEST_MODE
491 #endif // wxLONGLONG_TEST_MODE
497 wxLongLongWx
wxLongLongWx::operator-() const
499 wxLongLongWx
res(*this);
505 wxLongLongWx
& wxLongLongWx::Negate()
514 #ifdef wxLONGLONG_TEST_MODE
518 #endif // wxLONGLONG_TEST_MODE
525 wxLongLongWx
wxLongLongWx::operator-(const wxLongLongWx
& ll
) const
527 wxLongLongWx
res(*this);
533 wxLongLongWx
wxULongLongWx::operator-(const wxULongLongWx
& ll
) const
535 wxASSERT(m_hi
<= LONG_MAX
);
536 wxASSERT(ll
.m_hi
<= LONG_MAX
);
538 wxLongLongWx
res( (long)m_hi
, m_lo
);
539 wxLongLongWx
op( (long)ll
.m_hi
, ll
.m_lo
);
545 wxLongLongWx
& wxLongLongWx::operator-=(const wxLongLongWx
& ll
)
547 unsigned long previous
= m_lo
;
552 if (previous
< ll
.m_lo
)
555 #ifdef wxLONGLONG_TEST_MODE
559 #endif // wxLONGLONG_TEST_MODE
564 wxULongLongWx
& wxULongLongWx::operator-=(const wxULongLongWx
& ll
)
566 unsigned long previous
= m_lo
;
571 if (previous
< ll
.m_lo
)
574 #ifdef wxLONGLONG_TEST_MODE
578 #endif // wxLONGLONG_TEST_MODE
584 wxLongLongWx
& wxLongLongWx::operator--()
587 if (m_lo
== 0xFFFFFFFF)
590 #ifdef wxLONGLONG_TEST_MODE
594 #endif // wxLONGLONG_TEST_MODE
599 wxULongLongWx
& wxULongLongWx::operator--()
602 if (m_lo
== 0xFFFFFFFF)
605 #ifdef wxLONGLONG_TEST_MODE
609 #endif // wxLONGLONG_TEST_MODE
614 // comparison operators
616 bool wxLongLongWx::operator<(const wxLongLongWx
& ll
) const
618 if ( m_hi
< ll
.m_hi
)
620 else if ( m_hi
== ll
.m_hi
)
621 return m_lo
< ll
.m_lo
;
626 bool wxULongLongWx::operator<(const wxULongLongWx
& ll
) const
628 if ( m_hi
< ll
.m_hi
)
630 else if ( m_hi
== ll
.m_hi
)
631 return m_lo
< ll
.m_lo
;
636 bool wxLongLongWx::operator>(const wxLongLongWx
& ll
) const
638 if ( m_hi
> ll
.m_hi
)
640 else if ( m_hi
== ll
.m_hi
)
641 return m_lo
> ll
.m_lo
;
646 bool wxULongLongWx::operator>(const wxULongLongWx
& ll
) const
648 if ( m_hi
> ll
.m_hi
)
650 else if ( m_hi
== ll
.m_hi
)
651 return m_lo
> ll
.m_lo
;
658 wxLongLongWx
wxLongLongWx::operator&(const wxLongLongWx
& ll
) const
660 return wxLongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
663 wxULongLongWx
wxULongLongWx::operator&(const wxULongLongWx
& ll
) const
665 return wxULongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
668 wxLongLongWx
wxLongLongWx::operator|(const wxLongLongWx
& ll
) const
670 return wxLongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
673 wxULongLongWx
wxULongLongWx::operator|(const wxULongLongWx
& ll
) const
675 return wxULongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
678 wxLongLongWx
wxLongLongWx::operator^(const wxLongLongWx
& ll
) const
680 return wxLongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
683 wxULongLongWx
wxULongLongWx::operator^(const wxULongLongWx
& ll
) const
685 return wxULongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
688 wxLongLongWx
& wxLongLongWx::operator&=(const wxLongLongWx
& ll
)
693 #ifdef wxLONGLONG_TEST_MODE
697 #endif // wxLONGLONG_TEST_MODE
702 wxULongLongWx
& wxULongLongWx::operator&=(const wxULongLongWx
& ll
)
707 #ifdef wxLONGLONG_TEST_MODE
711 #endif // wxLONGLONG_TEST_MODE
716 wxLongLongWx
& wxLongLongWx::operator|=(const wxLongLongWx
& ll
)
721 #ifdef wxLONGLONG_TEST_MODE
725 #endif // wxLONGLONG_TEST_MODE
730 wxULongLongWx
& wxULongLongWx::operator|=(const wxULongLongWx
& ll
)
735 #ifdef wxLONGLONG_TEST_MODE
739 #endif // wxLONGLONG_TEST_MODE
744 wxLongLongWx
& wxLongLongWx::operator^=(const wxLongLongWx
& ll
)
749 #ifdef wxLONGLONG_TEST_MODE
753 #endif // wxLONGLONG_TEST_MODE
758 wxULongLongWx
& wxULongLongWx::operator^=(const wxULongLongWx
& ll
)
763 #ifdef wxLONGLONG_TEST_MODE
767 #endif // wxLONGLONG_TEST_MODE
772 wxLongLongWx
wxLongLongWx::operator~() const
774 return wxLongLongWx(~m_hi
, ~m_lo
);
777 wxULongLongWx
wxULongLongWx::operator~() const
779 return wxULongLongWx(~m_hi
, ~m_lo
);
784 wxLongLongWx
wxLongLongWx::operator*(const wxLongLongWx
& ll
) const
786 wxLongLongWx
res(*this);
792 wxULongLongWx
wxULongLongWx::operator*(const wxULongLongWx
& ll
) const
794 wxULongLongWx
res(*this);
800 wxLongLongWx
& wxLongLongWx::operator*=(const wxLongLongWx
& ll
)
802 wxLongLongWx
t(m_hi
, m_lo
);
803 wxLongLongWx
q(ll
.m_hi
, ll
.m_lo
);
807 #ifdef wxLONGLONG_TEST_MODE
808 wxLongLong_t llOld
= m_ll
;
810 #endif // wxLONGLONG_TEST_MODE
815 if ((q
.m_lo
& 1) != 0)
821 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
823 #ifdef wxLONGLONG_TEST_MODE
824 m_ll
= llOld
* ll
.m_ll
;
827 #endif // wxLONGLONG_TEST_MODE
832 wxULongLongWx
& wxULongLongWx::operator*=(const wxULongLongWx
& ll
)
834 wxULongLongWx
t(m_hi
, m_lo
);
835 wxULongLongWx
q(ll
.m_hi
, ll
.m_lo
);
839 #ifdef wxLONGLONG_TEST_MODE
840 wxULongLong_t llOld
= m_ll
;
842 #endif // wxLONGLONG_TEST_MODE
847 if ((q
.m_lo
& 1) != 0)
853 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
855 #ifdef wxLONGLONG_TEST_MODE
856 m_ll
= llOld
* ll
.m_ll
;
859 #endif // wxLONGLONG_TEST_MODE
866 #define IS_MSB_SET(ll) ((ll.GetHi()) & (1 << (8*sizeof(long) - 1)))
868 void wxLongLongWx::Divide(const wxLongLongWx
& divisorIn
,
869 wxLongLongWx
& quotient
,
870 wxLongLongWx
& remainderIO
) const
872 if ((divisorIn
.m_lo
== 0) && (divisorIn
.m_hi
== 0))
874 // provoke division by zero error and silence the compilers warnings
875 // about an expression without effect and unused variable
876 long dummy
= divisorIn
.m_lo
/divisorIn
.m_hi
;
880 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
881 // do this - any improvements are more than welcome
883 // code inspired by the snippet at
884 // http://www.bearcave.com/software/divide.htm
888 // Use of this program, for any purpose, is granted the author, Ian
889 // Kaplan, as long as this copyright notice is included in the source
890 // code or any source code derived from this program. The user assumes
891 // all responsibility for using this code.
894 wxULongLongWx dividend
, divisor
, remainder
;
899 // always do unsigned division and adjust the signs later: in C integer
900 // division, the sign of the remainder is the same as the sign of the
901 // dividend, while the sign of the quotient is the product of the signs of
902 // the dividend and divisor. Of course, we also always have
904 // dividend = quotient*divisor + remainder
906 // with 0 <= abs(remainder) < abs(divisor)
907 bool negRemainder
= GetHi() < 0;
908 bool negQuotient
= false; // assume positive
911 negQuotient
= !negQuotient
;
916 if ( divisorIn
.GetHi() < 0 )
918 negQuotient
= !negQuotient
;
919 divisor
= -divisorIn
;
924 // check for some particular cases
925 if ( divisor
> dividend
)
927 remainder
= dividend
;
929 else if ( divisor
== dividend
)
935 // here: dividend > divisor and both are positive: do unsigned division
939 while ( remainder
< divisor
)
942 if ( IS_MSB_SET(dividend
) )
953 // undo the last loop iteration
958 for ( size_t i
= 0; i
< nBits
; i
++ )
961 if ( IS_MSB_SET(dividend
) )
966 wxLongLongWx t
= remainder
- divisor
;
969 if ( !IS_MSB_SET(t
) )
978 remainderIO
= remainder
;
983 remainderIO
= -remainderIO
;
988 quotient
= -quotient
;
992 void wxULongLongWx::Divide(const wxULongLongWx
& divisorIn
,
993 wxULongLongWx
& quotient
,
994 wxULongLongWx
& remainder
) const
996 if ((divisorIn
.m_lo
== 0) && (divisorIn
.m_hi
== 0))
998 // provoke division by zero error and silence the compilers warnings
999 // about an expression without effect and unused variable
1000 unsigned long dummy
= divisorIn
.m_lo
/divisorIn
.m_hi
;
1004 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
1005 // do this - any improvements are more than welcome
1007 // code inspired by the snippet at
1008 // http://www.bearcave.com/software/divide.htm
1010 // Copyright notice:
1012 // Use of this program, for any purpose, is granted the author, Ian
1013 // Kaplan, as long as this copyright notice is included in the source
1014 // code or any source code derived from this program. The user assumes
1015 // all responsibility for using this code.
1018 wxULongLongWx dividend
= *this,
1019 divisor
= divisorIn
;
1024 // check for some particular cases
1025 if ( divisor
> dividend
)
1027 remainder
= dividend
;
1029 else if ( divisor
== dividend
)
1035 // here: dividend > divisor
1039 while ( remainder
< divisor
)
1042 if ( IS_MSB_SET(dividend
) )
1053 // undo the last loop iteration
1058 for ( size_t i
= 0; i
< nBits
; i
++ )
1061 if ( IS_MSB_SET(dividend
) )
1066 wxULongLongWx t
= remainder
- divisor
;
1069 if ( !IS_MSB_SET(t
) )
1079 wxLongLongWx
wxLongLongWx::operator/(const wxLongLongWx
& ll
) const
1081 wxLongLongWx quotient
, remainder
;
1083 Divide(ll
, quotient
, remainder
);
1088 wxULongLongWx
wxULongLongWx::operator/(const wxULongLongWx
& ll
) const
1090 wxULongLongWx quotient
, remainder
;
1092 Divide(ll
, quotient
, remainder
);
1097 wxLongLongWx
& wxLongLongWx::operator/=(const wxLongLongWx
& ll
)
1099 wxLongLongWx quotient
, remainder
;
1101 Divide(ll
, quotient
, remainder
);
1108 wxULongLongWx
& wxULongLongWx::operator/=(const wxULongLongWx
& ll
)
1110 wxULongLongWx quotient
, remainder
;
1112 Divide(ll
, quotient
, remainder
);
1119 wxLongLongWx
wxLongLongWx::operator%(const wxLongLongWx
& ll
) const
1121 wxLongLongWx quotient
, remainder
;
1123 Divide(ll
, quotient
, remainder
);
1128 wxULongLongWx
wxULongLongWx::operator%(const wxULongLongWx
& ll
) const
1130 wxULongLongWx quotient
, remainder
;
1132 Divide(ll
, quotient
, remainder
);
1137 // ----------------------------------------------------------------------------
1139 // ----------------------------------------------------------------------------
1141 // temporary - just for testing
1142 void *wxLongLongWx::asArray(void) const
1144 static unsigned char temp
[8];
1146 temp
[0] = (char)((m_hi
>> 24) & 0xFF);
1147 temp
[1] = (char)((m_hi
>> 16) & 0xFF);
1148 temp
[2] = (char)((m_hi
>> 8) & 0xFF);
1149 temp
[3] = (char)((m_hi
>> 0) & 0xFF);
1150 temp
[4] = (char)((m_lo
>> 24) & 0xFF);
1151 temp
[5] = (char)((m_lo
>> 16) & 0xFF);
1152 temp
[6] = (char)((m_lo
>> 8) & 0xFF);
1153 temp
[7] = (char)((m_lo
>> 0) & 0xFF);
1158 void *wxULongLongWx::asArray(void) const
1160 static unsigned char temp
[8];
1162 temp
[0] = (char)((m_hi
>> 24) & 0xFF);
1163 temp
[1] = (char)((m_hi
>> 16) & 0xFF);
1164 temp
[2] = (char)((m_hi
>> 8) & 0xFF);
1165 temp
[3] = (char)((m_hi
>> 0) & 0xFF);
1166 temp
[4] = (char)((m_lo
>> 24) & 0xFF);
1167 temp
[5] = (char)((m_lo
>> 16) & 0xFF);
1168 temp
[6] = (char)((m_lo
>> 8) & 0xFF);
1169 temp
[7] = (char)((m_lo
>> 0) & 0xFF);
1174 #endif // wxUSE_LONGLONG_WX
1176 #define LL_TO_STRING(name) \
1177 wxString name::ToString() const \
1179 /* TODO: this is awfully inefficient, anything better? */ \
1184 bool neg = ll < 0; \
1189 long digit = (ll % 10).ToLong(); \
1190 result.Prepend((wxChar)(wxT('0') - digit)); \
1198 long digit = (ll % 10).ToLong(); \
1199 result.Prepend((wxChar)(wxT('0') + digit)); \
1204 if ( result.empty() ) \
1205 result = wxT('0'); \
1207 result.Prepend(wxT('-')); \
1212 #define ULL_TO_STRING(name) \
1213 wxString name::ToString() const \
1215 /* TODO: this is awfully inefficient, anything better? */ \
1222 result.Prepend((wxChar)(wxT('0') + (ll % 10).ToULong())); \
1226 if ( result.empty() ) \
1227 result = wxT('0'); \
1232 #if wxUSE_LONGLONG_NATIVE
1233 LL_TO_STRING(wxLongLongNative
)
1234 ULL_TO_STRING(wxULongLongNative
)
1237 #if wxUSE_LONGLONG_WX
1238 LL_TO_STRING(wxLongLongWx
)
1239 ULL_TO_STRING(wxULongLongWx
)
1242 #if wxUSE_STD_IOSTREAM
1246 wxSTD ostream
& operator<< (wxSTD ostream
& o
, const wxLongLong
& ll
)
1248 return o
<< ll
.ToString();
1252 wxSTD ostream
& operator<< (wxSTD ostream
& o
, const wxULongLong
& ll
)
1254 return o
<< ll
.ToString();
1257 #endif // wxUSE_STD_IOSTREAM
1259 WXDLLIMPEXP_BASE wxString
& operator<< (wxString
& s
, const wxLongLong
& ll
)
1261 return s
<< ll
.ToString();
1264 WXDLLIMPEXP_BASE wxString
& operator<< (wxString
& s
, const wxULongLong
& ll
)
1266 return s
<< ll
.ToString();
1271 WXDLLIMPEXP_BASE wxTextOutputStream
& operator<< (wxTextOutputStream
& o
, const wxULongLong
& ll
)
1273 return o
<< ll
.ToString();
1276 WXDLLIMPEXP_BASE wxTextOutputStream
& operator<< (wxTextOutputStream
& o
, const wxLongLong
& ll
)
1278 return o
<< ll
.ToString();
1281 #define READ_STRING_CHAR(s, idx, len) ((idx!=len) ? (wxChar)s[idx++] : wxT('\0'))
1283 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxULongLong
&ll
)
1285 wxString s
= o
.ReadWord();
1287 ll
= wxULongLong(0l, 0l);
1288 size_t length
= s
.length();
1291 wxChar ch
= READ_STRING_CHAR(s
, idx
, length
);
1294 while (ch
==wxT(' ') || ch
==wxT('\t'))
1295 ch
= READ_STRING_CHAR(s
, idx
, length
);
1298 wxULongLong
multiplier(0l, 10l);
1299 while (ch
>=wxT('0') && ch
<=wxT('9')) {
1300 long lValue
= (unsigned) (ch
- wxT('0'));
1301 ll
= ll
* multiplier
+ wxULongLong(0l, lValue
);
1302 ch
= READ_STRING_CHAR(s
, idx
, length
);
1308 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxLongLong
&ll
)
1310 wxString s
= o
.ReadWord();
1312 ll
= wxLongLong(0l, 0l);
1313 size_t length
= s
.length();
1316 wxChar ch
= READ_STRING_CHAR(s
, idx
, length
);
1319 while (ch
==wxT(' ') || ch
==wxT('\t'))
1320 ch
= READ_STRING_CHAR(s
, idx
, length
);
1324 if (ch
==wxT('-') || ch
==wxT('+')) {
1325 iSign
= ((ch
==wxT('-')) ? -1 : 1);
1326 ch
= READ_STRING_CHAR(s
, idx
, length
);
1330 wxLongLong
multiplier(0l, 10l);
1331 while (ch
>=wxT('0') && ch
<=wxT('9')) {
1332 long lValue
= (unsigned) (ch
- wxT('0'));
1333 ll
= ll
* multiplier
+ wxLongLong(0l, lValue
);
1334 ch
= READ_STRING_CHAR(s
, idx
, length
);
1337 #if wxUSE_LONGLONG_NATIVE
1338 ll
= ll
* wxLongLong((wxLongLong_t
) iSign
);
1340 ll
= ll
* wxLongLong((long) iSign
);
1346 #if wxUSE_LONGLONG_NATIVE
1348 WXDLLIMPEXP_BASE
class wxTextOutputStream
&operator<<(class wxTextOutputStream
&o
, wxULongLong_t value
)
1350 return o
<< wxULongLong(value
).ToString();
1353 WXDLLIMPEXP_BASE
class wxTextOutputStream
&operator<<(class wxTextOutputStream
&o
, wxLongLong_t value
)
1355 return o
<< wxLongLong(value
).ToString();
1358 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxULongLong_t
&value
)
1362 value
= ll
.GetValue();
1366 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxLongLong_t
&value
)
1370 value
= ll
.GetValue();
1374 #endif // wxUSE_LONGLONG_NATIVE
1376 #endif // wxUSE_STREAMS
1378 #endif // wxUSE_LONGLONG