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 #if defined(__MWERKS__) && defined(__WXMSW__)
37 #include <string.h> // for memset()
39 #include <memory.h> // for memset()
42 #include "wx/ioswrap.h"
44 // ============================================================================
46 // ============================================================================
48 #if wxUSE_LONGLONG_NATIVE
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 void *wxLongLongNative::asArray() const
56 static unsigned char temp
[8];
58 temp
[0] = wx_truncate_cast(unsigned char, ((m_ll
>> 56) & 0xFF));
59 temp
[1] = wx_truncate_cast(unsigned char, ((m_ll
>> 48) & 0xFF));
60 temp
[2] = wx_truncate_cast(unsigned char, ((m_ll
>> 40) & 0xFF));
61 temp
[3] = wx_truncate_cast(unsigned char, ((m_ll
>> 32) & 0xFF));
62 temp
[4] = wx_truncate_cast(unsigned char, ((m_ll
>> 24) & 0xFF));
63 temp
[5] = wx_truncate_cast(unsigned char, ((m_ll
>> 16) & 0xFF));
64 temp
[6] = wx_truncate_cast(unsigned char, ((m_ll
>> 8) & 0xFF));
65 temp
[7] = wx_truncate_cast(unsigned char, ((m_ll
>> 0) & 0xFF));
70 void *wxULongLongNative::asArray() const
72 static unsigned char temp
[8];
74 temp
[0] = wx_truncate_cast(unsigned char, ((m_ll
>> 56) & 0xFF));
75 temp
[1] = wx_truncate_cast(unsigned char, ((m_ll
>> 48) & 0xFF));
76 temp
[2] = wx_truncate_cast(unsigned char, ((m_ll
>> 40) & 0xFF));
77 temp
[3] = wx_truncate_cast(unsigned char, ((m_ll
>> 32) & 0xFF));
78 temp
[4] = wx_truncate_cast(unsigned char, ((m_ll
>> 24) & 0xFF));
79 temp
[5] = wx_truncate_cast(unsigned char, ((m_ll
>> 16) & 0xFF));
80 temp
[6] = wx_truncate_cast(unsigned char, ((m_ll
>> 8) & 0xFF));
81 temp
[7] = wx_truncate_cast(unsigned char, ((m_ll
>> 0) & 0xFF));
87 wxLongLongNative::wxLongLongNative(wxLongLongWx ll
)
89 // assign first to avoid precision loss!
95 wxLongLongNative
& wxLongLongNative::operator=(wxLongLongWx ll
)
97 // assign first to avoid precision loss!
104 wxLongLongNative
& wxLongLongNative::operator=(const class wxULongLongWx
&ll
)
106 // assign first to avoid precision loss!
113 wxULongLongNative::wxULongLongNative(const class wxULongLongWx
&ll
)
115 // assign first to avoid precision loss!
118 m_ll
|= ((unsigned long) ll
.GetLo());
121 wxULongLongNative
& wxULongLongNative::operator=(wxLongLongWx ll
)
123 // assign first to avoid precision loss!
126 m_ll
|= ((unsigned long) ll
.GetLo());
130 wxULongLongNative
& wxULongLongNative::operator=(const class wxULongLongWx
&ll
)
132 // assign first to avoid precision loss!
135 m_ll
|= ((unsigned long) ll
.GetLo());
140 #endif // wxUSE_LONGLONG_NATIVE
142 // ============================================================================
143 // wxLongLongWx: emulation of 'long long' using 2 longs
144 // ============================================================================
146 #if wxUSE_LONGLONG_WX
148 // Set value from unsigned wxULongLongWx
149 wxLongLongWx
&wxLongLongWx::operator=(const class wxULongLongWx
&ll
)
151 m_hi
= (unsigned long) ll
.GetHi();
157 wxLongLongWx
& wxLongLongWx::Assign(double d
)
159 bool positive
= d
>= 0;
161 if ( d
<= ULONG_MAX
)
168 m_hi
= (unsigned long)(d
/ (1.0 + (double)ULONG_MAX
));
169 m_lo
= (unsigned long)(d
- ((double)m_hi
* (1.0 + (double)ULONG_MAX
)));
172 #ifdef wxLONGLONG_TEST_MODE
173 m_ll
= (wxLongLong_t
)d
;
176 #endif // wxLONGLONG_TEST_MODE
184 double wxLongLongWx::ToDouble() const
187 d
*= 1.0 + (double)ULONG_MAX
;
190 #ifdef wxLONGLONG_TEST_MODE
191 wxASSERT( d
== m_ll
);
192 #endif // wxLONGLONG_TEST_MODE
197 wxLongLongWx
wxLongLongWx::operator<<(int shift
) const
199 wxLongLongWx
ll(*this);
205 wxULongLongWx
wxULongLongWx::operator<<(int shift
) const
207 wxULongLongWx
ll(*this);
213 wxLongLongWx
& wxLongLongWx::operator<<=(int shift
)
220 m_hi
|= m_lo
>> (32 - shift
);
225 m_hi
= m_lo
<< (shift
- 32);
230 #ifdef wxLONGLONG_TEST_MODE
234 #endif // wxLONGLONG_TEST_MODE
239 wxULongLongWx
& wxULongLongWx::operator<<=(int shift
)
246 m_hi
|= m_lo
>> (32 - shift
);
251 m_hi
= m_lo
<< (shift
- 32);
256 #ifdef wxLONGLONG_TEST_MODE
260 #endif // wxLONGLONG_TEST_MODE
265 wxLongLongWx
wxLongLongWx::operator>>(int shift
) const
267 wxLongLongWx
ll(*this);
273 wxULongLongWx
wxULongLongWx::operator>>(int shift
) const
275 wxULongLongWx
ll(*this);
281 wxLongLongWx
& wxLongLongWx::operator>>=(int shift
)
288 m_lo
|= m_hi
<< (32 - shift
);
293 m_lo
= m_hi
>> (shift
- 32);
294 m_hi
= (m_hi
< 0 ? -1L : 0);
298 #ifdef wxLONGLONG_TEST_MODE
302 #endif // wxLONGLONG_TEST_MODE
307 wxULongLongWx
& wxULongLongWx::operator>>=(int shift
)
314 m_lo
|= m_hi
<< (32 - shift
);
319 m_lo
= m_hi
>> (shift
- 32);
324 #ifdef wxLONGLONG_TEST_MODE
328 #endif // wxLONGLONG_TEST_MODE
333 wxLongLongWx
wxLongLongWx::operator+(const wxLongLongWx
& ll
) const
335 wxLongLongWx
res(*this);
341 wxULongLongWx
wxULongLongWx::operator+(const wxULongLongWx
& ll
) const
343 wxULongLongWx
res(*this);
349 wxLongLongWx
wxLongLongWx::operator+(long l
) const
351 wxLongLongWx
res(*this);
357 wxULongLongWx
wxULongLongWx::operator+(unsigned long l
) const
359 wxULongLongWx
res(*this);
365 wxLongLongWx
& wxLongLongWx::operator+=(const wxLongLongWx
& ll
)
367 unsigned long previous
= m_lo
;
372 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
375 #ifdef wxLONGLONG_TEST_MODE
379 #endif // wxLONGLONG_TEST_MODE
384 wxULongLongWx
& wxULongLongWx::operator+=(const wxULongLongWx
& ll
)
386 unsigned long previous
= m_lo
;
391 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
394 #ifdef wxLONGLONG_TEST_MODE
398 #endif // wxLONGLONG_TEST_MODE
403 wxLongLongWx
& wxLongLongWx::operator+=(long l
)
405 unsigned long previous
= m_lo
;
411 if ((m_lo
< previous
) || (m_lo
< (unsigned long)l
))
414 #ifdef wxLONGLONG_TEST_MODE
418 #endif // wxLONGLONG_TEST_MODE
423 wxULongLongWx
& wxULongLongWx::operator+=(unsigned long l
)
425 unsigned long previous
= m_lo
;
429 if ((m_lo
< previous
) || (m_lo
< l
))
432 #ifdef wxLONGLONG_TEST_MODE
436 #endif // wxLONGLONG_TEST_MODE
442 wxLongLongWx
& wxLongLongWx::operator++()
448 #ifdef wxLONGLONG_TEST_MODE
452 #endif // wxLONGLONG_TEST_MODE
457 wxULongLongWx
& wxULongLongWx::operator++()
463 #ifdef wxLONGLONG_TEST_MODE
467 #endif // wxLONGLONG_TEST_MODE
473 wxLongLongWx
wxLongLongWx::operator-() const
475 wxLongLongWx
res(*this);
481 wxLongLongWx
& wxLongLongWx::Negate()
490 #ifdef wxLONGLONG_TEST_MODE
494 #endif // wxLONGLONG_TEST_MODE
501 wxLongLongWx
wxLongLongWx::operator-(const wxLongLongWx
& ll
) const
503 wxLongLongWx
res(*this);
509 wxLongLongWx
wxULongLongWx::operator-(const wxULongLongWx
& ll
) const
511 wxASSERT(m_hi
<= LONG_MAX
);
512 wxASSERT(ll
.m_hi
<= LONG_MAX
);
514 wxLongLongWx
res( (long)m_hi
, m_lo
);
515 wxLongLongWx
op( (long)ll
.m_hi
, ll
.m_lo
);
521 wxLongLongWx
& wxLongLongWx::operator-=(const wxLongLongWx
& ll
)
523 unsigned long previous
= m_lo
;
528 if (previous
< ll
.m_lo
)
531 #ifdef wxLONGLONG_TEST_MODE
535 #endif // wxLONGLONG_TEST_MODE
540 wxULongLongWx
& wxULongLongWx::operator-=(const wxULongLongWx
& ll
)
542 unsigned long previous
= m_lo
;
547 if (previous
< ll
.m_lo
)
550 #ifdef wxLONGLONG_TEST_MODE
554 #endif // wxLONGLONG_TEST_MODE
560 wxLongLongWx
& wxLongLongWx::operator--()
563 if (m_lo
== 0xFFFFFFFF)
566 #ifdef wxLONGLONG_TEST_MODE
570 #endif // wxLONGLONG_TEST_MODE
575 wxULongLongWx
& wxULongLongWx::operator--()
578 if (m_lo
== 0xFFFFFFFF)
581 #ifdef wxLONGLONG_TEST_MODE
585 #endif // wxLONGLONG_TEST_MODE
590 // comparison operators
592 bool wxLongLongWx::operator<(const wxLongLongWx
& ll
) const
594 if ( m_hi
< ll
.m_hi
)
596 else if ( m_hi
== ll
.m_hi
)
597 return m_lo
< ll
.m_lo
;
602 bool wxULongLongWx::operator<(const wxULongLongWx
& ll
) const
604 if ( m_hi
< ll
.m_hi
)
606 else if ( m_hi
== ll
.m_hi
)
607 return m_lo
< ll
.m_lo
;
612 bool wxLongLongWx::operator>(const wxLongLongWx
& ll
) const
614 if ( m_hi
> ll
.m_hi
)
616 else if ( m_hi
== ll
.m_hi
)
617 return m_lo
> ll
.m_lo
;
622 bool wxULongLongWx::operator>(const wxULongLongWx
& ll
) const
624 if ( m_hi
> ll
.m_hi
)
626 else if ( m_hi
== ll
.m_hi
)
627 return m_lo
> ll
.m_lo
;
634 wxLongLongWx
wxLongLongWx::operator&(const wxLongLongWx
& ll
) const
636 return wxLongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
639 wxULongLongWx
wxULongLongWx::operator&(const wxULongLongWx
& ll
) const
641 return wxULongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
644 wxLongLongWx
wxLongLongWx::operator|(const wxLongLongWx
& ll
) const
646 return wxLongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
649 wxULongLongWx
wxULongLongWx::operator|(const wxULongLongWx
& ll
) const
651 return wxULongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
654 wxLongLongWx
wxLongLongWx::operator^(const wxLongLongWx
& ll
) const
656 return wxLongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
659 wxULongLongWx
wxULongLongWx::operator^(const wxULongLongWx
& ll
) const
661 return wxULongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
664 wxLongLongWx
& wxLongLongWx::operator&=(const wxLongLongWx
& ll
)
669 #ifdef wxLONGLONG_TEST_MODE
673 #endif // wxLONGLONG_TEST_MODE
678 wxULongLongWx
& wxULongLongWx::operator&=(const wxULongLongWx
& ll
)
683 #ifdef wxLONGLONG_TEST_MODE
687 #endif // wxLONGLONG_TEST_MODE
692 wxLongLongWx
& wxLongLongWx::operator|=(const wxLongLongWx
& ll
)
697 #ifdef wxLONGLONG_TEST_MODE
701 #endif // wxLONGLONG_TEST_MODE
706 wxULongLongWx
& wxULongLongWx::operator|=(const wxULongLongWx
& ll
)
711 #ifdef wxLONGLONG_TEST_MODE
715 #endif // wxLONGLONG_TEST_MODE
720 wxLongLongWx
& wxLongLongWx::operator^=(const wxLongLongWx
& ll
)
725 #ifdef wxLONGLONG_TEST_MODE
729 #endif // wxLONGLONG_TEST_MODE
734 wxULongLongWx
& wxULongLongWx::operator^=(const wxULongLongWx
& ll
)
739 #ifdef wxLONGLONG_TEST_MODE
743 #endif // wxLONGLONG_TEST_MODE
748 wxLongLongWx
wxLongLongWx::operator~() const
750 return wxLongLongWx(~m_hi
, ~m_lo
);
753 wxULongLongWx
wxULongLongWx::operator~() const
755 return wxULongLongWx(~m_hi
, ~m_lo
);
760 wxLongLongWx
wxLongLongWx::operator*(const wxLongLongWx
& ll
) const
762 wxLongLongWx
res(*this);
768 wxULongLongWx
wxULongLongWx::operator*(const wxULongLongWx
& ll
) const
770 wxULongLongWx
res(*this);
776 wxLongLongWx
& wxLongLongWx::operator*=(const wxLongLongWx
& ll
)
778 wxLongLongWx
t(m_hi
, m_lo
);
779 wxLongLongWx
q(ll
.m_hi
, ll
.m_lo
);
783 #ifdef wxLONGLONG_TEST_MODE
784 wxLongLong_t llOld
= m_ll
;
786 #endif // wxLONGLONG_TEST_MODE
791 if ((q
.m_lo
& 1) != 0)
797 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
799 #ifdef wxLONGLONG_TEST_MODE
800 m_ll
= llOld
* ll
.m_ll
;
803 #endif // wxLONGLONG_TEST_MODE
808 wxULongLongWx
& wxULongLongWx::operator*=(const wxULongLongWx
& ll
)
810 wxULongLongWx
t(m_hi
, m_lo
);
811 wxULongLongWx
q(ll
.m_hi
, ll
.m_lo
);
815 #ifdef wxLONGLONG_TEST_MODE
816 wxULongLong_t llOld
= m_ll
;
818 #endif // wxLONGLONG_TEST_MODE
823 if ((q
.m_lo
& 1) != 0)
829 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
831 #ifdef wxLONGLONG_TEST_MODE
832 m_ll
= llOld
* ll
.m_ll
;
835 #endif // wxLONGLONG_TEST_MODE
842 #define IS_MSB_SET(ll) ((ll.GetHi()) & (1 << (8*sizeof(long) - 1)))
844 void wxLongLongWx::Divide(const wxLongLongWx
& divisorIn
,
845 wxLongLongWx
& quotient
,
846 wxLongLongWx
& remainderIO
) const
848 if ((divisorIn
.m_lo
== 0) && (divisorIn
.m_hi
== 0))
850 // provoke division by zero error and silence the compilers warnings
851 // about an expression without effect and unused variable
852 long dummy
= divisorIn
.m_lo
/divisorIn
.m_hi
;
856 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
857 // do this - any improvements are more than welcome
859 // code inspired by the snippet at
860 // http://www.bearcave.com/software/divide.htm
864 // Use of this program, for any purpose, is granted the author, Ian
865 // Kaplan, as long as this copyright notice is included in the source
866 // code or any source code derived from this program. The user assumes
867 // all responsibility for using this code.
870 wxULongLongWx dividend
, divisor
, remainder
;
875 // always do unsigned division and adjust the signs later: in C integer
876 // division, the sign of the remainder is the same as the sign of the
877 // dividend, while the sign of the quotient is the product of the signs of
878 // the dividend and divisor. Of course, we also always have
880 // dividend = quotient*divisor + remainder
882 // with 0 <= abs(remainder) < abs(divisor)
883 bool negRemainder
= GetHi() < 0;
884 bool negQuotient
= false; // assume positive
887 negQuotient
= !negQuotient
;
892 if ( divisorIn
.GetHi() < 0 )
894 negQuotient
= !negQuotient
;
895 divisor
= -divisorIn
;
900 // check for some particular cases
901 if ( divisor
> dividend
)
903 remainder
= dividend
;
905 else if ( divisor
== dividend
)
911 // here: dividend > divisor and both are positive: do unsigned division
915 while ( remainder
< divisor
)
918 if ( IS_MSB_SET(dividend
) )
929 // undo the last loop iteration
934 for ( size_t i
= 0; i
< nBits
; i
++ )
937 if ( IS_MSB_SET(dividend
) )
942 wxLongLongWx t
= remainder
- divisor
;
945 if ( !IS_MSB_SET(t
) )
954 remainderIO
= remainder
;
959 remainderIO
= -remainderIO
;
964 quotient
= -quotient
;
968 void wxULongLongWx::Divide(const wxULongLongWx
& divisorIn
,
969 wxULongLongWx
& quotient
,
970 wxULongLongWx
& remainder
) const
972 if ((divisorIn
.m_lo
== 0) && (divisorIn
.m_hi
== 0))
974 // provoke division by zero error and silence the compilers warnings
975 // about an expression without effect and unused variable
976 unsigned long dummy
= divisorIn
.m_lo
/divisorIn
.m_hi
;
980 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
981 // do this - any improvements are more than welcome
983 // code inspired by the snippet at
984 // http://www.bearcave.com/software/divide.htm
988 // Use of this program, for any purpose, is granted the author, Ian
989 // Kaplan, as long as this copyright notice is included in the source
990 // code or any source code derived from this program. The user assumes
991 // all responsibility for using this code.
994 wxULongLongWx dividend
= *this,
1000 // check for some particular cases
1001 if ( divisor
> dividend
)
1003 remainder
= dividend
;
1005 else if ( divisor
== dividend
)
1011 // here: dividend > divisor
1015 while ( remainder
< divisor
)
1018 if ( IS_MSB_SET(dividend
) )
1029 // undo the last loop iteration
1034 for ( size_t i
= 0; i
< nBits
; i
++ )
1037 if ( IS_MSB_SET(dividend
) )
1042 wxULongLongWx t
= remainder
- divisor
;
1045 if ( !IS_MSB_SET(t
) )
1055 wxLongLongWx
wxLongLongWx::operator/(const wxLongLongWx
& ll
) const
1057 wxLongLongWx quotient
, remainder
;
1059 Divide(ll
, quotient
, remainder
);
1064 wxULongLongWx
wxULongLongWx::operator/(const wxULongLongWx
& ll
) const
1066 wxULongLongWx quotient
, remainder
;
1068 Divide(ll
, quotient
, remainder
);
1073 wxLongLongWx
& wxLongLongWx::operator/=(const wxLongLongWx
& ll
)
1075 wxLongLongWx quotient
, remainder
;
1077 Divide(ll
, quotient
, remainder
);
1084 wxULongLongWx
& wxULongLongWx::operator/=(const wxULongLongWx
& ll
)
1086 wxULongLongWx quotient
, remainder
;
1088 Divide(ll
, quotient
, remainder
);
1095 wxLongLongWx
wxLongLongWx::operator%(const wxLongLongWx
& ll
) const
1097 wxLongLongWx quotient
, remainder
;
1099 Divide(ll
, quotient
, remainder
);
1104 wxULongLongWx
wxULongLongWx::operator%(const wxULongLongWx
& ll
) const
1106 wxULongLongWx quotient
, remainder
;
1108 Divide(ll
, quotient
, remainder
);
1113 // ----------------------------------------------------------------------------
1115 // ----------------------------------------------------------------------------
1117 // temporary - just for testing
1118 void *wxLongLongWx::asArray(void) const
1120 static unsigned char temp
[8];
1122 temp
[0] = (char)((m_hi
>> 24) & 0xFF);
1123 temp
[1] = (char)((m_hi
>> 16) & 0xFF);
1124 temp
[2] = (char)((m_hi
>> 8) & 0xFF);
1125 temp
[3] = (char)((m_hi
>> 0) & 0xFF);
1126 temp
[4] = (char)((m_lo
>> 24) & 0xFF);
1127 temp
[5] = (char)((m_lo
>> 16) & 0xFF);
1128 temp
[6] = (char)((m_lo
>> 8) & 0xFF);
1129 temp
[7] = (char)((m_lo
>> 0) & 0xFF);
1134 void *wxULongLongWx::asArray(void) const
1136 static unsigned char temp
[8];
1138 temp
[0] = (char)((m_hi
>> 24) & 0xFF);
1139 temp
[1] = (char)((m_hi
>> 16) & 0xFF);
1140 temp
[2] = (char)((m_hi
>> 8) & 0xFF);
1141 temp
[3] = (char)((m_hi
>> 0) & 0xFF);
1142 temp
[4] = (char)((m_lo
>> 24) & 0xFF);
1143 temp
[5] = (char)((m_lo
>> 16) & 0xFF);
1144 temp
[6] = (char)((m_lo
>> 8) & 0xFF);
1145 temp
[7] = (char)((m_lo
>> 0) & 0xFF);
1150 #endif // wxUSE_LONGLONG_WX
1152 #define LL_TO_STRING(name) \
1153 wxString name::ToString() const \
1155 /* TODO: this is awfully inefficient, anything better? */ \
1160 bool neg = ll < 0; \
1165 long digit = (ll % 10).ToLong(); \
1166 result.Prepend((wxChar)(_T('0') - digit)); \
1174 long digit = (ll % 10).ToLong(); \
1175 result.Prepend((wxChar)(_T('0') + digit)); \
1180 if ( result.empty() ) \
1183 result.Prepend(_T('-')); \
1188 #define ULL_TO_STRING(name) \
1189 wxString name::ToString() const \
1191 /* TODO: this is awfully inefficient, anything better? */ \
1198 result.Prepend((wxChar)(_T('0') + (ll % 10).ToULong())); \
1202 if ( result.empty() ) \
1208 #if wxUSE_LONGLONG_NATIVE
1209 LL_TO_STRING(wxLongLongNative
)
1210 ULL_TO_STRING(wxULongLongNative
)
1213 #if wxUSE_LONGLONG_WX
1214 LL_TO_STRING(wxLongLongWx
)
1215 ULL_TO_STRING(wxULongLongWx
)
1218 #if wxUSE_STD_IOSTREAM
1222 wxSTD ostream
& operator<< (wxSTD ostream
& o
, const wxLongLong
& ll
)
1224 return o
<< ll
.ToString();
1228 wxSTD ostream
& operator<< (wxSTD ostream
& o
, const wxULongLong
& ll
)
1230 return o
<< ll
.ToString();
1233 #endif // wxUSE_STD_IOSTREAM
1235 WXDLLIMPEXP_BASE wxString
& operator<< (wxString
& s
, const wxLongLong
& ll
)
1237 return s
<< ll
.ToString();
1240 WXDLLIMPEXP_BASE wxString
& operator<< (wxString
& s
, const wxULongLong
& ll
)
1242 return s
<< ll
.ToString();
1247 WXDLLIMPEXP_BASE wxTextOutputStream
& operator<< (wxTextOutputStream
& o
, const wxULongLong
& ll
)
1249 return o
<< ll
.ToString();
1252 WXDLLIMPEXP_BASE wxTextOutputStream
& operator<< (wxTextOutputStream
& o
, const wxLongLong
& ll
)
1254 return o
<< ll
.ToString();
1257 #define READ_STRING_CHAR(s, idx, len) ((wxChar) ((idx!=len) ? s[idx++] : 0))
1259 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxULongLong
&ll
)
1261 wxString s
= o
.ReadWord();
1263 ll
= wxULongLong(0l, 0l);
1264 size_t length
= s
.length();
1267 wxChar ch
= READ_STRING_CHAR(s
, idx
, length
);
1270 while (ch
==wxT(' ') || ch
==wxT('\t'))
1271 ch
= READ_STRING_CHAR(s
, idx
, length
);
1274 wxULongLong
multiplier(0l, 10l);
1275 while (ch
>=wxT('0') && ch
<=wxT('9')) {
1276 long lValue
= (unsigned) (ch
- wxT('0'));
1277 ll
= ll
* multiplier
+ wxULongLong(0l, lValue
);
1278 ch
= READ_STRING_CHAR(s
, idx
, length
);
1284 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxLongLong
&ll
)
1286 wxString s
= o
.ReadWord();
1288 ll
= wxLongLong(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
);
1300 if (ch
==wxT('-') || ch
==wxT('+')) {
1301 iSign
= ((ch
==wxT('-')) ? -1 : 1);
1302 ch
= READ_STRING_CHAR(s
, idx
, length
);
1306 wxLongLong
multiplier(0l, 10l);
1307 while (ch
>=wxT('0') && ch
<=wxT('9')) {
1308 long lValue
= (unsigned) (ch
- wxT('0'));
1309 ll
= ll
* multiplier
+ wxLongLong(0l, lValue
);
1310 ch
= READ_STRING_CHAR(s
, idx
, length
);
1313 #if wxUSE_LONGLONG_NATIVE
1314 ll
= ll
* wxLongLong((wxLongLong_t
) iSign
);
1316 ll
= ll
* wxLongLong((long) iSign
);
1322 #if wxUSE_LONGLONG_NATIVE
1324 WXDLLIMPEXP_BASE
class wxTextOutputStream
&operator<<(class wxTextOutputStream
&o
, wxULongLong_t value
)
1326 return o
<< wxULongLong(value
).ToString();
1329 WXDLLIMPEXP_BASE
class wxTextOutputStream
&operator<<(class wxTextOutputStream
&o
, wxLongLong_t value
)
1331 return o
<< wxLongLong(value
).ToString();
1334 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxULongLong_t
&value
)
1338 value
= ll
.GetValue();
1342 WXDLLIMPEXP_BASE
class wxTextInputStream
&operator>>(class wxTextInputStream
&o
, wxLongLong_t
&value
)
1346 value
= ll
.GetValue();
1350 #endif // wxUSE_LONGLONG_NATIVE
1352 #endif // wxUSE_STREAMS
1354 #endif // wxUSE_LONGLONG