/////////////////////////////////////////////////////////////////////////////
// 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