///////////////////////////////////////////////////////////////////////////// // Name: wx/longlong.h // Purpose: Legacy support for 64-bit integers predating universal long // long availability // Author: Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin // Created: 10.02.99 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_LONGLONG_H #define _WX_LONGLONG_H #include "wx/defs.h" #include "wx/iosfwrap.h" #include "wx/string.h" #include <limits.h> // for LONG_MAX #if wxUSE_STREAMS class WXDLLIMPEXP_FWD_BASE wxTextOutputStream; class WXDLLIMPEXP_FWD_BASE wxTextInputStream; #endif class WXDLLIMPEXP_FWD_BASE wxULongLong; class WXDLLIMPEXP_BASE wxWARN_UNUSED wxLongLong { public: // ctors // default ctor initializes to 0 wxLongLong() : m_ll(0) { } // from long long wxLongLong(wxLongLong_t ll) : m_ll(ll) { } // from 2 longs wxLongLong(wxInt32 hi, wxUint32 lo) { // cast first to avoid precision loss and use unsigned shift to avoid // undefined behaviour if the high part is negative (and then cast // again to avoid warning about the possible sign change) m_ll = (wxLongLong_t)(((wxULongLong_t) hi) << 32); m_ll |= (wxLongLong_t) lo; } // default copy ctor is ok // no dtor // assignment operators // from native 64 bit integer #ifndef wxLongLongIsLong wxLongLong& operator=(wxLongLong_t ll) { m_ll = ll; return *this; } wxLongLong& operator=(wxULongLong_t ll) { m_ll = ll; return *this; } #endif // !wxLongLong wxLongLong& operator=(const wxULongLong &ll); wxLongLong& operator=(int l) { m_ll = l; return *this; } wxLongLong& operator=(long l) { m_ll = l; return *this; } wxLongLong& operator=(unsigned int l) { m_ll = l; return *this; } wxLongLong& operator=(unsigned long l) { m_ll = l; return *this; } // from double: this one has an explicit name because otherwise we // would have ambiguity with "ll = int" and also because we don't want // to have implicit conversions between doubles and wxLongLongs wxLongLong& Assign(double d) { m_ll = (wxLongLong_t)d; return *this; } // assignment operators from wxLongLong is ok // accessors // get high part wxInt32 GetHi() const { return wx_truncate_cast(wxInt32, m_ll >> 32); } // get low part wxUint32 GetLo() const { return wx_truncate_cast(wxUint32, m_ll); } // get absolute value wxLongLong Abs() const { return wxLongLong(*this).Abs(); } wxLongLong& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; } // convert to native long long wxLongLong_t GetValue() const { return m_ll; } // convert to long with range checking in debug mode (only!) long ToLong() const { // This assert is useless if long long is the same as long (which is // the case under the standard Unix LP64 model). #ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG wxASSERT_MSG( (m_ll >= LONG_MIN) && (m_ll <= LONG_MAX), wxT("wxLongLong to long conversion loss of precision") ); #endif return wx_truncate_cast(long, m_ll); } // convert to double double ToDouble() const { return wx_truncate_cast(double, m_ll); } // don't provide implicit conversion to wxLongLong_t or we will have an // ambiguity for all arithmetic operations //operator wxLongLong_t() const { return m_ll; } // operations // addition wxLongLong operator+(const wxLongLong& ll) const { return wxLongLong(m_ll + ll.m_ll); } wxLongLong& operator+=(const wxLongLong& ll) { m_ll += ll.m_ll; return *this; } friend wxLongLong operator+(long l, const wxLongLong& ll) { return ll + l; } wxLongLong operator+(const wxLongLong_t ll) const { return wxLongLong(m_ll + ll); } wxLongLong& operator+=(const wxLongLong_t ll) { m_ll += ll; return *this; } // pre increment wxLongLong& operator++() { m_ll++; return *this; } // post increment wxLongLong operator++(int) { wxLongLong value(*this); m_ll++; return value; } // negation operator wxLongLong operator-() const { return wxLongLong(-m_ll); } wxLongLong& Negate() { m_ll = -m_ll; return *this; } // subtraction wxLongLong operator-(const wxLongLong& ll) const { return wxLongLong(m_ll - ll.m_ll); } wxLongLong& operator-=(const wxLongLong& ll) { m_ll -= ll.m_ll; return *this; } friend wxLongLong operator-(long l, const wxLongLong& ll) { return wxLongLong(l) - ll; } wxLongLong operator-(const wxLongLong_t ll) const { return wxLongLong(m_ll - ll); } wxLongLong& operator-=(const wxLongLong_t ll) { m_ll -= ll; return *this; } // pre decrement wxLongLong& operator--() { m_ll--; return *this; } // post decrement wxLongLong operator--(int) { wxLongLong value(*this); m_ll--; return value; } // shifts // left shift wxLongLong operator<<(int shift) const { return wxLongLong(m_ll << shift); } wxLongLong& operator<<=(int shift) { m_ll <<= shift; return *this; } // right shift wxLongLong operator>>(int shift) const { return wxLongLong(m_ll >> shift); } wxLongLong& operator>>=(int shift) { m_ll >>= shift; return *this; } // bitwise operators wxLongLong operator&(const wxLongLong& ll) const { return wxLongLong(m_ll & ll.m_ll); } wxLongLong& operator&=(const wxLongLong& ll) { m_ll &= ll.m_ll; return *this; } wxLongLong operator|(const wxLongLong& ll) const { return wxLongLong(m_ll | ll.m_ll); } wxLongLong& operator|=(const wxLongLong& ll) { m_ll |= ll.m_ll; return *this; } wxLongLong operator^(const wxLongLong& ll) const { return wxLongLong(m_ll ^ ll.m_ll); } wxLongLong& operator^=(const wxLongLong& ll) { m_ll ^= ll.m_ll; return *this; } // multiplication/division wxLongLong operator*(const wxLongLong& ll) const { return wxLongLong(m_ll * ll.m_ll); } wxLongLong operator*(long l) const { return wxLongLong(m_ll * l); } wxLongLong& operator*=(const wxLongLong& ll) { m_ll *= ll.m_ll; return *this; } wxLongLong& operator*=(long l) { m_ll *= l; return *this; } wxLongLong operator/(const wxLongLong& ll) const { return wxLongLong(m_ll / ll.m_ll); } wxLongLong operator/(long l) const { return wxLongLong(m_ll / l); } wxLongLong& operator/=(const wxLongLong& ll) { m_ll /= ll.m_ll; return *this; } wxLongLong& operator/=(long l) { m_ll /= l; return *this; } wxLongLong operator%(const wxLongLong& ll) const { return wxLongLong(m_ll % ll.m_ll); } wxLongLong operator%(long l) const { return wxLongLong(m_ll % l); } // comparison bool operator==(const wxLongLong& ll) const { return m_ll == ll.m_ll; } bool operator==(long l) const { return m_ll == l; } bool operator!=(const wxLongLong& ll) const { return m_ll != ll.m_ll; } bool operator!=(long l) const { return m_ll != l; } bool operator<(const wxLongLong& ll) const { return m_ll < ll.m_ll; } bool operator<(long l) const { return m_ll < l; } bool operator>(const wxLongLong& ll) const { return m_ll > ll.m_ll; } bool operator>(long l) const { return m_ll > l; } bool operator<=(const wxLongLong& ll) const { return m_ll <= ll.m_ll; } bool operator<=(long l) const { return m_ll <= l; } bool operator>=(const wxLongLong& ll) const { return m_ll >= ll.m_ll; } bool operator>=(long l) const { return m_ll >= l; } friend bool operator<(long l, const wxLongLong& ll) { return ll > l; } friend bool operator>(long l, const wxLongLong& ll) { return ll < l; } friend bool operator<=(long l, const wxLongLong& ll) { return ll >= l; } friend bool operator>=(long l, const wxLongLong& ll) { return ll <= l; } friend bool operator==(long l, const wxLongLong& ll) { return ll == l; } friend bool operator!=(long l, const wxLongLong& ll) { return ll != l; } // miscellaneous // return the string representation of this number wxString ToString() const { return wxString::Format(wxASCII_STR("%" wxLongLongFmtSpec "d"), m_ll); } // conversion to byte array: returns a pointer to static buffer! void *asArray() const; #if wxUSE_STD_IOSTREAM // input/output friend WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxLongLong&); #endif friend WXDLLIMPEXP_BASE wxString& operator<<(wxString&, const wxLongLong&); #if wxUSE_STREAMS friend WXDLLIMPEXP_BASE class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLong&); friend WXDLLIMPEXP_BASE class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLong&); #endif private: wxLongLong_t m_ll; }; class WXDLLIMPEXP_BASE wxWARN_UNUSED wxULongLong { public: // ctors // default ctor initializes to 0 wxULongLong() : m_ll(0) { } // from long long wxULongLong(wxULongLong_t ll) : m_ll(ll) { } // from 2 longs wxULongLong(wxUint32 hi, wxUint32 lo) : m_ll(0) { // cast to wxLongLong_t first to avoid precision loss! m_ll = ((wxULongLong_t) hi) << 32; m_ll |= (wxULongLong_t) lo; } // default copy ctor is ok // no dtor // assignment operators // from native 64 bit integer #ifndef wxLongLongIsLong wxULongLong& operator=(wxULongLong_t ll) { m_ll = ll; return *this; } wxULongLong& operator=(wxLongLong_t ll) { m_ll = ll; return *this; } #endif // !wxLongLong wxULongLong& operator=(int l) { m_ll = l; return *this; } wxULongLong& operator=(long l) { m_ll = l; return *this; } wxULongLong& operator=(unsigned int l) { m_ll = l; return *this; } wxULongLong& operator=(unsigned long l) { m_ll = l; return *this; } wxULongLong& operator=(const wxLongLong &ll) { m_ll = ll.GetValue(); return *this; } // assignment operators from wxULongLong is ok // accessors // get high part wxUint32 GetHi() const { return wx_truncate_cast(wxUint32, m_ll >> 32); } // get low part wxUint32 GetLo() const { return wx_truncate_cast(wxUint32, m_ll); } // convert to native ulong long wxULongLong_t GetValue() const { return m_ll; } // convert to ulong with range checking in debug mode (only!) unsigned long ToULong() const { wxASSERT_MSG( m_ll <= ULONG_MAX, wxT("wxULongLong to long conversion loss of precision") ); return wx_truncate_cast(unsigned long, m_ll); } // convert to double double ToDouble() const { return wx_truncate_cast(double, m_ll); } // operations // addition wxULongLong operator+(const wxULongLong& ll) const { return wxULongLong(m_ll + ll.m_ll); } wxULongLong& operator+=(const wxULongLong& ll) { m_ll += ll.m_ll; return *this; } friend wxULongLong operator+(unsigned long l, const wxULongLong& ull) { return ull + l; } wxULongLong operator+(const wxULongLong_t ll) const { return wxULongLong(m_ll + ll); } wxULongLong& operator+=(const wxULongLong_t ll) { m_ll += ll; return *this; } // pre increment wxULongLong& operator++() { m_ll++; return *this; } // post increment wxULongLong operator++(int) { wxULongLong value(*this); m_ll++; return value; } // subtraction wxULongLong operator-(const wxULongLong& ll) const { return wxULongLong(m_ll - ll.m_ll); } wxULongLong& operator-=(const wxULongLong& ll) { m_ll -= ll.m_ll; return *this; } friend wxULongLong operator-(unsigned long l, const wxULongLong& ull) { return wxULongLong(l - ull.m_ll); } wxULongLong operator-(const wxULongLong_t ll) const { return wxULongLong(m_ll - ll); } wxULongLong& operator-=(const wxULongLong_t ll) { m_ll -= ll; return *this; } // pre decrement wxULongLong& operator--() { m_ll--; return *this; } // post decrement wxULongLong operator--(int) { wxULongLong value(*this); m_ll--; return value; } // shifts // left shift wxULongLong operator<<(int shift) const { return wxULongLong(m_ll << shift); } wxULongLong& operator<<=(int shift) { m_ll <<= shift; return *this; } // right shift wxULongLong operator>>(int shift) const { return wxULongLong(m_ll >> shift); } wxULongLong& operator>>=(int shift) { m_ll >>= shift; return *this; } // bitwise operators wxULongLong operator&(const wxULongLong& ll) const { return wxULongLong(m_ll & ll.m_ll); } wxULongLong& operator&=(const wxULongLong& ll) { m_ll &= ll.m_ll; return *this; } wxULongLong operator|(const wxULongLong& ll) const { return wxULongLong(m_ll | ll.m_ll); } wxULongLong& operator|=(const wxULongLong& ll) { m_ll |= ll.m_ll; return *this; } wxULongLong operator^(const wxULongLong& ll) const { return wxULongLong(m_ll ^ ll.m_ll); } wxULongLong& operator^=(const wxULongLong& ll) { m_ll ^= ll.m_ll; return *this; } // multiplication/division wxULongLong operator*(const wxULongLong& ll) const { return wxULongLong(m_ll * ll.m_ll); } wxULongLong operator*(unsigned long l) const { return wxULongLong(m_ll * l); } wxULongLong& operator*=(const wxULongLong& ll) { m_ll *= ll.m_ll; return *this; } wxULongLong& operator*=(unsigned long l) { m_ll *= l; return *this; } wxULongLong operator/(const wxULongLong& ll) const { return wxULongLong(m_ll / ll.m_ll); } wxULongLong operator/(unsigned long l) const { return wxULongLong(m_ll / l); } wxULongLong& operator/=(const wxULongLong& ll) { m_ll /= ll.m_ll; return *this; } wxULongLong& operator/=(unsigned long l) { m_ll /= l; return *this; } wxULongLong operator%(const wxULongLong& ll) const { return wxULongLong(m_ll % ll.m_ll); } wxULongLong operator%(unsigned long l) const { return wxULongLong(m_ll % l); } // comparison bool operator==(const wxULongLong& ll) const { return m_ll == ll.m_ll; } bool operator==(unsigned long l) const { return m_ll == l; } bool operator!=(const wxULongLong& ll) const { return m_ll != ll.m_ll; } bool operator!=(unsigned long l) const { return m_ll != l; } bool operator<(const wxULongLong& ll) const { return m_ll < ll.m_ll; } bool operator<(unsigned long l) const { return m_ll < l; } bool operator>(const wxULongLong& ll) const { return m_ll > ll.m_ll; } bool operator>(unsigned long l) const { return m_ll > l; } bool operator<=(const wxULongLong& ll) const { return m_ll <= ll.m_ll; } bool operator<=(unsigned long l) const { return m_ll <= l; } bool operator>=(const wxULongLong& ll) const { return m_ll >= ll.m_ll; } bool operator>=(unsigned long l) const { return m_ll >= l; } friend bool operator<(unsigned long l, const wxULongLong& ull) { return ull > l; } friend bool operator>(unsigned long l, const wxULongLong& ull) { return ull < l; } friend bool operator<=(unsigned long l, const wxULongLong& ull) { return ull >= l; } friend bool operator>=(unsigned long l, const wxULongLong& ull) { return ull <= l; } friend bool operator==(unsigned long l, const wxULongLong& ull) { return ull == l; } friend bool operator!=(unsigned long l, const wxULongLong& ull) { return ull != l; } // miscellaneous // return the string representation of this number wxString ToString() const { return wxString::Format(wxASCII_STR("%" wxLongLongFmtSpec "u"), m_ll); } // conversion to byte array: returns a pointer to static buffer! void *asArray() const; #if wxUSE_STD_IOSTREAM // input/output friend WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxULongLong&); #endif friend WXDLLIMPEXP_BASE wxString& operator<<(wxString&, const wxULongLong&); #if wxUSE_STREAMS friend WXDLLIMPEXP_BASE class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLong&); friend WXDLLIMPEXP_BASE class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLong&); #endif private: wxULongLong_t m_ll; }; inline wxLongLong& wxLongLong::operator=(const wxULongLong &ll) { m_ll = ll.GetValue(); return *this; } // ---------------------------------------------------------------------------- // Specialize numeric_limits<> for our long long wrapper classes. // ---------------------------------------------------------------------------- #include <limits> namespace std { template<> struct numeric_limits<wxLongLong> : numeric_limits<wxLongLong_t> {}; template<> struct numeric_limits<wxULongLong> : numeric_limits<wxULongLong_t> {}; } // namespace std // ---------------------------------------------------------------------------- // Specialize wxArgNormalizer to allow using wxLongLong directly with wx pseudo // vararg functions. // ---------------------------------------------------------------------------- // Notice that this must be done here and not in wx/strvararg.h itself because // we can't include wx/longlong.h from there as this header itself includes // wx/string.h which includes wx/strvararg.h too, so to avoid the circular // dependencies we can only do it here (or add another header just for this but // it doesn't seem necessary). #include "wx/strvararg.h" template<> struct wxFormatStringSpecifier<wxLongLong> { enum { value = wxFormatString::Arg_LongLongInt }; }; template<> struct WXDLLIMPEXP_BASE wxArgNormalizer<wxLongLong> { wxArgNormalizer(wxLongLong value, const wxFormatString *fmt, unsigned index) : m_value(value) { wxASSERT_ARG_TYPE( fmt, index, wxFormatString::Arg_LongLongInt ); } wxLongLong_t get() const { return m_value.GetValue(); } wxLongLong m_value; }; // Compatibility typedefs: these types were never supposed to be used outside // of wx itself but nevertheless appear in the existing code, so define them to // let it continue to build. using wxLongLongNative = wxLongLong; using wxULongLongNative = wxULongLong; #endif // _WX_LONGLONG_H