home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / include / wx / longlong.h < prev    next >
C/C++ Source or Header  |  2002-08-31  |  31KB  |  928 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        wx/longlong.h
  3. // Purpose:     declaration of wxLongLong class - best implementation of a 64
  4. //              bit integer for the current platform.
  5. // Author:      Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin
  6. // Modified by:
  7. // Created:     10.02.99
  8. // RCS-ID:      $Id: longlong.h,v 1.43 2002/08/31 11:29:10 GD Exp $
  9. // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  10. // Licence:     wxWindows license
  11. /////////////////////////////////////////////////////////////////////////////
  12.  
  13. #ifndef _WX_LONGLONG_H
  14. #define _WX_LONGLONG_H
  15.  
  16. #if defined(__GNUG__) && !defined(__APPLE__)
  17.     #pragma interface "longlong.h"
  18. #endif
  19.  
  20. #include "wx/defs.h"
  21. #include "wx/string.h"
  22.  
  23. #include <limits.h>     // for LONG_MAX
  24.  
  25. // define this to compile wxLongLongWx in "test" mode: the results of all
  26. // calculations will be compared with the real results taken from
  27. // wxLongLongNative -- this is extremely useful to find the bugs in
  28. // wxLongLongWx class!
  29.  
  30. // #define wxLONGLONG_TEST_MODE
  31.  
  32. #ifdef wxLONGLONG_TEST_MODE
  33.     #define wxUSE_LONGLONG_WX 1
  34.     #define wxUSE_LONGLONG_NATIVE 1
  35. #endif // wxLONGLONG_TEST_MODE
  36.  
  37. // ----------------------------------------------------------------------------
  38. // decide upon which class we will use
  39. // ----------------------------------------------------------------------------
  40.  
  41. // to avoid compilation problems on 64bit machines with ambiguous method calls
  42. // we will need to define this
  43. #undef wxLongLongIsLong
  44.  
  45. // NB: we #define and not typedef wxLongLong_t because we want to be able to
  46. //     use 'unsigned wxLongLong_t' as well and because we use "#ifdef
  47. //     wxLongLong_t" below
  48.  
  49. // first check for generic cases which are long on 64bit machine and "long
  50. // long", then check for specific compilers
  51. #if defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
  52.     #define wxLongLong_t long
  53.     #define wxLongLongIsLong
  54. #elif (defined(__VISUALC__) && defined(__WIN32__)) || defined( __VMS__ )
  55.     #define wxLongLong_t __int64
  56. #elif defined(__BORLANDC__) && defined(__WIN32__) && (__BORLANDC__ >= 0x520)
  57.     #define wxLongLong_t __int64
  58. #elif defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG >= 8
  59.     #define wxLongLong_t long long
  60. #elif defined(__MINGW32__) || defined(__CYGWIN__) || defined(__WXMICROWIN__)
  61.     #define wxLongLong_t long long
  62. #elif defined(__MWERKS__)
  63.     #if __option(longlong)
  64.         #define wxLongLong_t long long
  65.     #else
  66.         #error "The 64 bit integer support in CodeWarrior has been disabled."
  67.         #error "See the documentation on the 'longlong' pragma."
  68.     #endif
  69. #elif defined(__VISAGECPP__) && __IBMCPP__ >= 400
  70.         #define wxLongLong_t long long
  71. #elif defined(__DJGPP__) && __DJGPP__ >= 2
  72.     #define wxLongLong_t long long
  73. #else // no native long long type
  74.     // both warning and pragma warning are not portable, but at least an
  75.     // unknown pragma should never be an error - except that, actually, some
  76.     // broken compilers don't like it, so we have to disable it in this case
  77.     // <sigh>
  78. #if !(defined(__WATCOMC__) || defined(__VISAGECPP__))
  79.     #pragma warning "Your compiler does not appear to support 64 bit "\
  80.                     "integers, using emulation class instead.\n" \
  81.                     "Please report your compiler version to " \
  82.                     "wx-dev@lists.wxwindows.org!"
  83. #endif
  84.  
  85.     #define wxUSE_LONGLONG_WX 1
  86. #endif // compiler
  87.  
  88. // the user may predefine wxUSE_LONGLONG_NATIVE and/or wxUSE_LONGLONG_NATIVE
  89. // to disable automatic testing (useful for the test program which defines
  90. // both classes) but by default we only use one class
  91. #if (defined(wxUSE_LONGLONG_WX) && wxUSE_LONGLONG_WX) || !defined(wxLongLong_t)
  92.     // don't use both classes unless wxUSE_LONGLONG_NATIVE was explicitly set:
  93.     // this is useful in test programs and only there
  94.     #ifndef wxUSE_LONGLONG_NATIVE
  95.         #define wxUSE_LONGLONG_NATIVE 0
  96.     #endif
  97.  
  98.     class WXDLLEXPORT wxLongLongWx;
  99.     class WXDLLEXPORT wxULongLongWx;
  100. #if defined(__VISUALC__) && !defined(__WIN32__)
  101.     #define wxLongLong wxLongLongWx
  102.     #define wxULongLong wxULongLongWx
  103. #else
  104.     typedef wxLongLongWx wxLongLong;
  105.     typedef wxULongLongWx wxULongLong;
  106. #endif
  107.  
  108. #else
  109.     // if nothing is defined, use native implementation by default, of course
  110.     #ifndef wxUSE_LONGLONG_NATIVE
  111.         #define wxUSE_LONGLONG_NATIVE 1
  112.     #endif
  113. #endif
  114.  
  115. #ifndef wxUSE_LONGLONG_WX
  116.     #define wxUSE_LONGLONG_WX 0
  117.     class WXDLLEXPORT wxLongLongNative;
  118.     class WXDLLEXPORT wxULongLongNative;
  119.     typedef wxLongLongNative wxLongLong;
  120.     typedef wxULongLongNative wxULongLong;
  121. #endif
  122.  
  123. // NB: if both wxUSE_LONGLONG_WX and NATIVE are defined, the user code should
  124. //     typedef wxLongLong as it wants, we don't do it
  125.  
  126. // ----------------------------------------------------------------------------
  127. // choose the appropriate class
  128. // ----------------------------------------------------------------------------
  129.  
  130. // we use iostream for wxLongLong output
  131. #include "wx/ioswrap.h"
  132.  
  133. #if wxUSE_LONGLONG_NATIVE
  134.  
  135. class WXDLLEXPORT wxLongLongNative
  136. {
  137. public:
  138.     // ctors
  139.         // default ctor initializes to 0
  140.     wxLongLongNative() : m_ll(0) { }
  141.         // from long long
  142.     wxLongLongNative(wxLongLong_t ll) : m_ll(ll) { }
  143.         // from 2 longs
  144.     wxLongLongNative(long hi, unsigned long lo) : m_ll(0)
  145.     {
  146.         // assign first to avoid precision loss!
  147.         m_ll = ((wxLongLong_t) hi) << 32;
  148.         m_ll |= (wxLongLong_t) lo;
  149.     }
  150.  
  151.     // default copy ctor is ok
  152.  
  153.     // no dtor
  154.  
  155.     // assignment operators
  156.         // from native 64 bit integer
  157.     wxLongLongNative& operator=(wxLongLong_t ll)
  158.         { m_ll = ll; return *this; }
  159.  
  160.         // from double: this one has an explicit name because otherwise we
  161.         // would have ambiguity with "ll = int" and also because we don't want
  162.         // to have implicit conversions between doubles and wxLongLongs
  163.     wxLongLongNative& Assign(double d)
  164.         { m_ll = (wxLongLong_t)d; return *this; }
  165.  
  166.     // assignment operators from wxLongLongNative is ok
  167.  
  168.     // accessors
  169.         // get high part
  170.     long GetHi() const
  171.         { return (long)(m_ll >> 32); }
  172.         // get low part
  173.     unsigned long GetLo() const
  174.         { return (unsigned long)m_ll; }
  175.  
  176.         // get absolute value
  177.     wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); }
  178.     wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
  179.  
  180.         // convert to native long long
  181.     wxLongLong_t GetValue() const { return m_ll; }
  182.  
  183.         // convert to long with range checking in the debug mode (only!)
  184.     long ToLong() const
  185.     {
  186.         wxASSERT_MSG( (m_ll >= LONG_MIN) && (m_ll <= LONG_MAX),
  187.                       _T("wxLongLong to long conversion loss of precision") );
  188.  
  189.         return (long)m_ll;
  190.     }
  191.  
  192.     // don't provide implicit conversion to wxLongLong_t or we will have an
  193.     // ambiguity for all arithmetic operations
  194.     //operator wxLongLong_t() const { return m_ll; }
  195.  
  196.     // operations
  197.         // addition
  198.     wxLongLongNative operator+(const wxLongLongNative& ll) const
  199.         { return wxLongLongNative(m_ll + ll.m_ll); }
  200.     wxLongLongNative& operator+=(const wxLongLongNative& ll)
  201.         { m_ll += ll.m_ll; return *this; }
  202.  
  203.     wxLongLongNative operator+(const wxLongLong_t ll) const
  204.         { return wxLongLongNative(m_ll + ll); }
  205.     wxLongLongNative& operator+=(const wxLongLong_t ll)
  206.         { m_ll += ll; return *this; }
  207.  
  208.         // pre increment
  209.     wxLongLongNative& operator++()
  210.         { m_ll++; return *this; }
  211.  
  212.         // post increment
  213.     wxLongLongNative operator++(int)
  214.         { wxLongLongNative value(*this); m_ll++; return value; }
  215.  
  216.         // negation operator
  217.     wxLongLongNative operator-() const
  218.         { return wxLongLongNative(-m_ll); }
  219.     wxLongLongNative& Negate() { m_ll = -m_ll; return *this; }
  220.  
  221.         // subtraction
  222.     wxLongLongNative operator-(const wxLongLongNative& ll) const
  223.         { return wxLongLongNative(m_ll - ll.m_ll); }
  224.     wxLongLongNative& operator-=(const wxLongLongNative& ll)
  225.         { m_ll -= ll.m_ll; return *this; }
  226.  
  227.     wxLongLongNative operator-(const wxLongLong_t ll) const
  228.         { return wxLongLongNative(m_ll - ll); }
  229.     wxLongLongNative& operator-=(const wxLongLong_t ll)
  230.         { m_ll -= ll; return *this; }
  231.  
  232.         // pre decrement
  233.     wxLongLongNative& operator--()
  234.         { m_ll--; return *this; }
  235.  
  236.         // post decrement
  237.     wxLongLongNative operator--(int)
  238.         { wxLongLongNative value(*this); m_ll--; return value; }
  239.  
  240.     // shifts
  241.         // left shift
  242.     wxLongLongNative operator<<(int shift) const
  243.         { return wxLongLongNative(m_ll << shift);; }
  244.     wxLongLongNative& operator<<=(int shift)
  245.         { m_ll <<= shift; return *this; }
  246.  
  247.         // right shift
  248.     wxLongLongNative operator>>(int shift) const
  249.         { return wxLongLongNative(m_ll >> shift);; }
  250.     wxLongLongNative& operator>>=(int shift)
  251.         { m_ll >>= shift; return *this; }
  252.  
  253.     // bitwise operators
  254.     wxLongLongNative operator&(const wxLongLongNative& ll) const
  255.         { return wxLongLongNative(m_ll & ll.m_ll); }
  256.     wxLongLongNative& operator&=(const wxLongLongNative& ll)
  257.         { m_ll &= ll.m_ll; return *this; }
  258.  
  259.     wxLongLongNative operator|(const wxLongLongNative& ll) const
  260.         { return wxLongLongNative(m_ll | ll.m_ll); }
  261.     wxLongLongNative& operator|=(const wxLongLongNative& ll)
  262.         { m_ll |= ll.m_ll; return *this; }
  263.  
  264.     wxLongLongNative operator^(const wxLongLongNative& ll) const
  265.         { return wxLongLongNative(m_ll ^ ll.m_ll); }
  266.     wxLongLongNative& operator^=(const wxLongLongNative& ll)
  267.         { m_ll ^= ll.m_ll; return *this; }
  268.  
  269.     // multiplication/division
  270.     wxLongLongNative operator*(const wxLongLongNative& ll) const
  271.         { return wxLongLongNative(m_ll * ll.m_ll); }
  272.     wxLongLongNative operator*(long l) const
  273.         { return wxLongLongNative(m_ll * l); }
  274.     wxLongLongNative& operator*=(const wxLongLongNative& ll)
  275.         { m_ll *= ll.m_ll; return *this; }
  276.     wxLongLongNative& operator*=(long l)
  277.         { m_ll *= l; return *this; }
  278.  
  279.     wxLongLongNative operator/(const wxLongLongNative& ll) const
  280.         { return wxLongLongNative(m_ll / ll.m_ll); }
  281.     wxLongLongNative operator/(long l) const
  282.         { return wxLongLongNative(m_ll / l); }
  283.     wxLongLongNative& operator/=(const wxLongLongNative& ll)
  284.         { m_ll /= ll.m_ll; return *this; }
  285.     wxLongLongNative& operator/=(long l)
  286.         { m_ll /= l; return *this; }
  287.  
  288.     wxLongLongNative operator%(const wxLongLongNative& ll) const
  289.         { return wxLongLongNative(m_ll % ll.m_ll); }
  290.     wxLongLongNative operator%(long l) const
  291.         { return wxLongLongNative(m_ll % l); }
  292.  
  293.     // comparison
  294.     bool operator==(const wxLongLongNative& ll) const
  295.         { return m_ll == ll.m_ll; }
  296.     bool operator==(long l) const
  297.         { return m_ll == l; }
  298.     bool operator!=(const wxLongLongNative& ll) const
  299.         { return m_ll != ll.m_ll; }
  300.     bool operator!=(long l) const
  301.         { return m_ll != l; }
  302.     bool operator<(const wxLongLongNative& ll) const
  303.         { return m_ll < ll.m_ll; }
  304.     bool operator<(long l) const
  305.         { return m_ll < l; }
  306.     bool operator>(const wxLongLongNative& ll) const
  307.         { return m_ll > ll.m_ll; }
  308.     bool operator>(long l) const
  309.         { return m_ll > l; }
  310.     bool operator<=(const wxLongLongNative& ll) const
  311.         { return m_ll <= ll.m_ll; }
  312.     bool operator<=(long l) const
  313.         { return m_ll <= l; }
  314.     bool operator>=(const wxLongLongNative& ll) const
  315.         { return m_ll >= ll.m_ll; }
  316.     bool operator>=(long l) const
  317.         { return m_ll >= l; }
  318.  
  319.     // miscellaneous
  320.  
  321.         // return the string representation of this number
  322.     wxString ToString() const;
  323.  
  324.         // conversion to byte array: returns a pointer to static buffer!
  325.     void *asArray() const;
  326.  
  327. #if wxUSE_STD_IOSTREAM
  328.         // input/output
  329.     friend wxSTD ostream& operator<<(wxSTD ostream&, const wxLongLongNative&);
  330. #endif
  331.  
  332. private:
  333.     wxLongLong_t  m_ll;
  334. };
  335.  
  336.  
  337. class WXDLLEXPORT wxULongLongNative
  338. {
  339. public:
  340.     // ctors
  341.         // default ctor initializes to 0
  342.     wxULongLongNative() : m_ll(0) { }
  343.         // from long long
  344.     wxULongLongNative(unsigned wxLongLong_t ll) : m_ll(ll) { }
  345.         // from 2 longs
  346.     wxULongLongNative(unsigned long hi, unsigned long lo) : m_ll(0)
  347.     {
  348.         // assign first to avoid precision loss!
  349.         m_ll = ((unsigned wxLongLong_t) hi) << 32;
  350.         m_ll |= (unsigned wxLongLong_t) lo;
  351.     }
  352.  
  353.     // default copy ctor is ok
  354.  
  355.     // no dtor
  356.  
  357.     // assignment operators
  358.         // from native 64 bit integer
  359.     wxULongLongNative& operator=(unsigned wxLongLong_t ll)
  360.         { m_ll = ll; return *this; }
  361.  
  362.     // assignment operators from wxULongLongNative is ok
  363.  
  364.     // accessors
  365.         // get high part
  366.     unsigned long GetHi() const
  367.         { return (unsigned long)(m_ll >> 32); }
  368.         // get low part
  369.     unsigned long GetLo() const
  370.         { return (unsigned long)m_ll; }
  371.  
  372.         // convert to native ulong long
  373.     unsigned wxLongLong_t GetValue() const { return m_ll; }
  374.  
  375.         // convert to ulong with range checking in the debug mode (only!)
  376.     unsigned long ToULong() const
  377.     {
  378.         wxASSERT_MSG( m_ll <= LONG_MAX,
  379.                       _T("wxULongLong to long conversion loss of precision") );
  380.  
  381.         return (unsigned long)m_ll;
  382.     }
  383.  
  384.     // operations
  385.         // addition
  386.     wxULongLongNative operator+(const wxULongLongNative& ll) const
  387.         { return wxULongLongNative(m_ll + ll.m_ll); }
  388.     wxULongLongNative& operator+=(const wxULongLongNative& ll)
  389.         { m_ll += ll.m_ll; return *this; }
  390.  
  391.     wxULongLongNative operator+(const unsigned wxLongLong_t ll) const
  392.         { return wxULongLongNative(m_ll + ll); }
  393.     wxULongLongNative& operator+=(const unsigned wxLongLong_t ll)
  394.         { m_ll += ll; return *this; }
  395.  
  396.         // pre increment
  397.     wxULongLongNative& operator++()
  398.         { m_ll++; return *this; }
  399.  
  400.         // post increment
  401.     wxULongLongNative operator++(int)
  402.         { wxULongLongNative value(*this); m_ll++; return value; }
  403.  
  404.         // subtraction
  405.     wxULongLongNative operator-(const wxULongLongNative& ll) const
  406.         { return wxULongLongNative(m_ll - ll.m_ll); }
  407.     wxULongLongNative& operator-=(const wxULongLongNative& ll)
  408.         { m_ll -= ll.m_ll; return *this; }
  409.  
  410.     wxULongLongNative operator-(const unsigned wxLongLong_t ll) const
  411.         { return wxULongLongNative(m_ll - ll); }
  412.     wxULongLongNative& operator-=(const unsigned wxLongLong_t ll)
  413.         { m_ll -= ll; return *this; }
  414.  
  415.         // pre decrement
  416.     wxULongLongNative& operator--()
  417.         { m_ll--; return *this; }
  418.  
  419.         // post decrement
  420.     wxULongLongNative operator--(int)
  421.         { wxULongLongNative value(*this); m_ll--; return value; }
  422.  
  423.     // shifts
  424.         // left shift
  425.     wxULongLongNative operator<<(int shift) const
  426.         { return wxULongLongNative(m_ll << shift);; }
  427.     wxULongLongNative& operator<<=(int shift)
  428.         { m_ll <<= shift; return *this; }
  429.  
  430.         // right shift
  431.     wxULongLongNative operator>>(int shift) const
  432.         { return wxULongLongNative(m_ll >> shift);; }
  433.     wxULongLongNative& operator>>=(int shift)
  434.         { m_ll >>= shift; return *this; }
  435.  
  436.     // bitwise operators
  437.     wxULongLongNative operator&(const wxULongLongNative& ll) const
  438.         { return wxULongLongNative(m_ll & ll.m_ll); }
  439.     wxULongLongNative& operator&=(const wxULongLongNative& ll)
  440.         { m_ll &= ll.m_ll; return *this; }
  441.  
  442.     wxULongLongNative operator|(const wxULongLongNative& ll) const
  443.         { return wxULongLongNative(m_ll | ll.m_ll); }
  444.     wxULongLongNative& operator|=(const wxULongLongNative& ll)
  445.         { m_ll |= ll.m_ll; return *this; }
  446.  
  447.     wxULongLongNative operator^(const wxULongLongNative& ll) const
  448.         { return wxULongLongNative(m_ll ^ ll.m_ll); }
  449.     wxULongLongNative& operator^=(const wxULongLongNative& ll)
  450.         { m_ll ^= ll.m_ll; return *this; }
  451.  
  452.     // multiplication/division
  453.     wxULongLongNative operator*(const wxULongLongNative& ll) const
  454.         { return wxULongLongNative(m_ll * ll.m_ll); }
  455.     wxULongLongNative operator*(unsigned long l) const
  456.         { return wxULongLongNative(m_ll * l); }
  457.     wxULongLongNative& operator*=(const wxULongLongNative& ll)
  458.         { m_ll *= ll.m_ll; return *this; }
  459.     wxULongLongNative& operator*=(unsigned long l)
  460.         { m_ll *= l; return *this; }
  461.  
  462.     wxULongLongNative operator/(const wxULongLongNative& ll) const
  463.         { return wxULongLongNative(m_ll / ll.m_ll); }
  464.     wxULongLongNative operator/(unsigned long l) const
  465.         { return wxULongLongNative(m_ll / l); }
  466.     wxULongLongNative& operator/=(const wxULongLongNative& ll)
  467.         { m_ll /= ll.m_ll; return *this; }
  468.     wxULongLongNative& operator/=(unsigned long l)
  469.         { m_ll /= l; return *this; }
  470.  
  471.     wxULongLongNative operator%(const wxULongLongNative& ll) const
  472.         { return wxULongLongNative(m_ll % ll.m_ll); }
  473.     wxULongLongNative operator%(unsigned long l) const
  474.         { return wxULongLongNative(m_ll % l); }
  475.  
  476.     // comparison
  477.     bool operator==(const wxULongLongNative& ll) const
  478.         { return m_ll == ll.m_ll; }
  479.     bool operator==(unsigned long l) const
  480.         { return m_ll == l; }
  481.     bool operator!=(const wxULongLongNative& ll) const
  482.         { return m_ll != ll.m_ll; }
  483.     bool operator!=(unsigned long l) const
  484.         { return m_ll != l; }
  485.     bool operator<(const wxULongLongNative& ll) const
  486.         { return m_ll < ll.m_ll; }
  487.     bool operator<(unsigned long l) const
  488.         { return m_ll < l; }
  489.     bool operator>(const wxULongLongNative& ll) const
  490.         { return m_ll > ll.m_ll; }
  491.     bool operator>(unsigned long l) const
  492.         { return m_ll > l; }
  493.     bool operator<=(const wxULongLongNative& ll) const
  494.         { return m_ll <= ll.m_ll; }
  495.     bool operator<=(unsigned long l) const
  496.         { return m_ll <= l; }
  497.     bool operator>=(const wxULongLongNative& ll) const
  498.         { return m_ll >= ll.m_ll; }
  499.     bool operator>=(unsigned long l) const
  500.         { return m_ll >= l; }
  501.  
  502.     // miscellaneous
  503.  
  504.         // return the string representation of this number
  505.     wxString ToString() const;
  506.  
  507.         // conversion to byte array: returns a pointer to static buffer!
  508.     void *asArray() const;
  509.  
  510. #if wxUSE_STD_IOSTREAM
  511.         // input/output
  512.     friend wxSTD ostream& operator<<(wxSTD ostream&, const wxULongLongNative&);
  513. #endif
  514.  
  515. private:
  516.     unsigned wxLongLong_t  m_ll;
  517. };
  518.  
  519. #endif // wxUSE_LONGLONG_NATIVE
  520.  
  521. #if wxUSE_LONGLONG_WX
  522.  
  523. class WXDLLEXPORT wxLongLongWx
  524. {
  525. public:
  526.     // ctors
  527.         // default ctor initializes to 0
  528.     wxLongLongWx()
  529.     {
  530.         m_lo = m_hi = 0;
  531.  
  532. #ifdef wxLONGLONG_TEST_MODE
  533.         m_ll = 0;
  534.  
  535.         Check();
  536. #endif // wxLONGLONG_TEST_MODE
  537.     }
  538.         // from long
  539.     wxLongLongWx(long l) { *this = l; }
  540.         // from 2 longs
  541.     wxLongLongWx(long hi, unsigned long lo)
  542.     {
  543.         m_hi = hi;
  544.         m_lo = lo;
  545.  
  546. #ifdef wxLONGLONG_TEST_MODE
  547.         m_ll = hi;
  548.         m_ll <<= 32;
  549.         m_ll |= lo;
  550.  
  551.         Check();
  552. #endif // wxLONGLONG_TEST_MODE
  553.     }
  554.  
  555.     // default copy ctor is ok in both cases
  556.  
  557.     // no dtor
  558.  
  559.     // assignment operators
  560.         // from long
  561.     wxLongLongWx& operator=(long l)
  562.     {
  563.         m_lo = l;
  564.         m_hi = (l < 0 ? -1l : 0l);
  565.  
  566. #ifdef wxLONGLONG_TEST_MODE
  567.         m_ll = l;
  568.  
  569.         Check();
  570. #endif // wxLONGLONG_TEST_MODE
  571.  
  572.         return *this;
  573.     }
  574.         // from double
  575.     wxLongLongWx& Assign(double d);
  576.         // can't have assignment operator from 2 longs
  577.  
  578.     // accessors
  579.         // get high part
  580.     long GetHi() const { return m_hi; }
  581.         // get low part
  582.     unsigned long GetLo() const { return m_lo; }
  583.  
  584.         // get absolute value
  585.     wxLongLongWx Abs() const { return wxLongLongWx(*this).Abs(); }
  586.     wxLongLongWx& Abs()
  587.     {
  588.         if ( m_hi < 0 )
  589.             m_hi = -m_hi;
  590.  
  591. #ifdef wxLONGLONG_TEST_MODE
  592.         if ( m_ll < 0 )
  593.             m_ll = -m_ll;
  594.  
  595.         Check();
  596. #endif // wxLONGLONG_TEST_MODE
  597.  
  598.         return *this;
  599.     }
  600.  
  601.         // convert to long with range checking in the debug mode (only!)
  602.     long ToLong() const
  603.     {
  604.         wxASSERT_MSG( (m_hi == 0l) || (m_hi == -1l),
  605.                       _T("wxLongLong to long conversion loss of precision") );
  606.  
  607.         return (long)m_lo;
  608.     }
  609.  
  610.     // operations
  611.         // addition
  612.     wxLongLongWx operator+(const wxLongLongWx& ll) const;
  613.     wxLongLongWx& operator+=(const wxLongLongWx& ll);
  614.     wxLongLongWx operator+(long l) const;
  615.     wxLongLongWx& operator+=(long l);
  616.  
  617.         // pre increment operator
  618.     wxLongLongWx& operator++();
  619.  
  620.         // post increment operator
  621.     wxLongLongWx& operator++(int) { return ++(*this); }
  622.  
  623.         // negation operator
  624.     wxLongLongWx operator-() const;
  625.     wxLongLongWx& Negate();
  626.  
  627.         // subraction
  628.     wxLongLongWx operator-(const wxLongLongWx& ll) const;
  629.     wxLongLongWx& operator-=(const wxLongLongWx& ll);
  630.  
  631.         // pre decrement operator
  632.     wxLongLongWx& operator--();
  633.  
  634.         // post decrement operator
  635.     wxLongLongWx& operator--(int) { return --(*this); }
  636.  
  637.     // shifts
  638.         // left shift
  639.     wxLongLongWx operator<<(int shift) const;
  640.     wxLongLongWx& operator<<=(int shift);
  641.  
  642.         // right shift
  643.     wxLongLongWx operator>>(int shift) const;
  644.     wxLongLongWx& operator>>=(int shift);
  645.  
  646.     // bitwise operators
  647.     wxLongLongWx operator&(const wxLongLongWx& ll) const;
  648.     wxLongLongWx& operator&=(const wxLongLongWx& ll);
  649.     wxLongLongWx operator|(const wxLongLongWx& ll) const;
  650.     wxLongLongWx& operator|=(const wxLongLongWx& ll);
  651.     wxLongLongWx operator^(const wxLongLongWx& ll) const;
  652.     wxLongLongWx& operator^=(const wxLongLongWx& ll);
  653.     wxLongLongWx operator~() const;
  654.  
  655.     // comparison
  656.     bool operator==(const wxLongLongWx& ll) const
  657.         { return m_lo == ll.m_lo && m_hi == ll.m_hi; }
  658.     bool operator!=(const wxLongLongWx& ll) const
  659.         { return !(*this == ll); }
  660.     bool operator<(const wxLongLongWx& ll) const;
  661.     bool operator>(const wxLongLongWx& ll) const;
  662.     bool operator<=(const wxLongLongWx& ll) const
  663.         { return *this < ll || *this == ll; }
  664.     bool operator>=(const wxLongLongWx& ll) const
  665.         { return *this > ll || *this == ll; }
  666.  
  667.     bool operator<(long l) const { return *this < wxLongLongWx(l); }
  668.     bool operator>(long l) const { return *this > wxLongLongWx(l); }
  669.     bool operator==(long l) const
  670.     {
  671.         return l >= 0 ? (m_hi == 0 && m_lo == (unsigned long)l)
  672.                       : (m_hi == -1 && m_lo == (unsigned long)l);
  673.     }
  674.  
  675.     bool operator<=(long l) const { return *this < l || *this == l; }
  676.     bool operator>=(long l) const { return *this > l || *this == l; }
  677.  
  678.     // multiplication
  679.     wxLongLongWx operator*(const wxLongLongWx& ll) const;
  680.     wxLongLongWx& operator*=(const wxLongLongWx& ll);
  681.  
  682.     // division
  683.     wxLongLongWx operator/(const wxLongLongWx& ll) const;
  684.     wxLongLongWx& operator/=(const wxLongLongWx& ll);
  685.  
  686.     wxLongLongWx operator%(const wxLongLongWx& ll) const;
  687.  
  688.     void Divide(const wxLongLongWx& divisor,
  689.                 wxLongLongWx& quotient,
  690.                 wxLongLongWx& remainder) const;
  691.  
  692.     // input/output
  693.  
  694.     // return the string representation of this number
  695.     wxString ToString() const;
  696.  
  697.     void *asArray() const;
  698.  
  699. #if wxUSE_STD_IOSTREAM
  700.     friend wxSTD ostream& operator<<(wxSTD ostream&, const wxLongLongWx&);
  701. #endif // wxUSE_STD_IOSTREAM
  702.  
  703. private:
  704.     // long is at least 32 bits, so represent our 64bit number as 2 longs
  705.  
  706.     long m_hi;                // signed bit is in the high part
  707.     unsigned long m_lo;
  708.  
  709. #ifdef wxLONGLONG_TEST_MODE
  710.     void Check()
  711.     {
  712.         wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo );
  713.     }
  714.  
  715.     wxLongLong_t m_ll;
  716. #endif // wxLONGLONG_TEST_MODE
  717. };
  718.  
  719.  
  720. class WXDLLEXPORT wxULongLongWx
  721. {
  722. public:
  723.     // ctors
  724.         // default ctor initializes to 0
  725.     wxULongLongWx()
  726.     {
  727.         m_lo = m_hi = 0;
  728.  
  729. #ifdef wxLONGLONG_TEST_MODE
  730.         m_ll = 0;
  731.  
  732.         Check();
  733. #endif // wxLONGLONG_TEST_MODE
  734.     }
  735.         // from ulong
  736.     wxULongLongWx(unsigned long l) { *this = l; }
  737.         // from 2 ulongs
  738.     wxULongLongWx(unsigned long hi, unsigned long lo)
  739.     {
  740.         m_hi = hi;
  741.         m_lo = lo;
  742.  
  743. #ifdef wxLONGLONG_TEST_MODE
  744.         m_ll = hi;
  745.         m_ll <<= 32;
  746.         m_ll |= lo;
  747.  
  748.         Check();
  749. #endif // wxLONGLONG_TEST_MODE
  750.     }
  751.  
  752.     // default copy ctor is ok in both cases
  753.  
  754.     // no dtor
  755.  
  756.     // assignment operators
  757.         // from long
  758.     wxULongLongWx& operator=(unsigned long l)
  759.     {
  760.         m_lo = l;
  761.         m_hi = 0;
  762.  
  763. #ifdef wxLONGLONG_TEST_MODE
  764.         m_ll = l;
  765.  
  766.         Check();
  767. #endif // wxLONGLONG_TEST_MODE
  768.  
  769.         return *this;
  770.     }
  771.  
  772.     // can't have assignment operator from 2 longs
  773.  
  774.     // accessors
  775.         // get high part
  776.     unsigned long GetHi() const { return m_hi; }
  777.         // get low part
  778.     unsigned long GetLo() const { return m_lo; }
  779.  
  780.         // convert to long with range checking in the debug mode (only!)
  781.     unsigned long ToULong() const
  782.     {
  783.         wxASSERT_MSG( m_hi == 0ul,
  784.                       _T("wxULongLong to long conversion loss of precision") );
  785.  
  786.         return (unsigned long)m_lo;
  787.     }
  788.  
  789.     // operations
  790.         // addition
  791.     wxULongLongWx operator+(const wxULongLongWx& ll) const;
  792.     wxULongLongWx& operator+=(const wxULongLongWx& ll);
  793.     wxULongLongWx operator+(unsigned long l) const;
  794.     wxULongLongWx& operator+=(unsigned long l);
  795.  
  796.         // pre increment operator
  797.     wxULongLongWx& operator++();
  798.  
  799.         // post increment operator
  800.     wxULongLongWx& operator++(int) { return ++(*this); }
  801.  
  802.         // subraction (FIXME: should return wxLongLong)
  803.     wxULongLongWx operator-(const wxULongLongWx& ll) const;
  804.     wxULongLongWx& operator-=(const wxULongLongWx& ll);
  805.  
  806.         // pre decrement operator
  807.     wxULongLongWx& operator--();
  808.  
  809.         // post decrement operator
  810.     wxULongLongWx& operator--(int) { return --(*this); }
  811.  
  812.     // shifts
  813.         // left shift
  814.     wxULongLongWx operator<<(int shift) const;
  815.     wxULongLongWx& operator<<=(int shift);
  816.  
  817.         // right shift
  818.     wxULongLongWx operator>>(int shift) const;
  819.     wxULongLongWx& operator>>=(int shift);
  820.  
  821.     // bitwise operators
  822.     wxULongLongWx operator&(const wxULongLongWx& ll) const;
  823.     wxULongLongWx& operator&=(const wxULongLongWx& ll);
  824.     wxULongLongWx operator|(const wxULongLongWx& ll) const;
  825.     wxULongLongWx& operator|=(const wxULongLongWx& ll);
  826.     wxULongLongWx operator^(const wxULongLongWx& ll) const;
  827.     wxULongLongWx& operator^=(const wxULongLongWx& ll);
  828.     wxULongLongWx operator~() const;
  829.  
  830.     // comparison
  831.     bool operator==(const wxULongLongWx& ll) const
  832.         { return m_lo == ll.m_lo && m_hi == ll.m_hi; }
  833.     bool operator!=(const wxULongLongWx& ll) const
  834.         { return !(*this == ll); }
  835.     bool operator<(const wxULongLongWx& ll) const;
  836.     bool operator>(const wxULongLongWx& ll) const;
  837.     bool operator<=(const wxULongLongWx& ll) const
  838.         { return *this < ll || *this == ll; }
  839.     bool operator>=(const wxULongLongWx& ll) const
  840.         { return *this > ll || *this == ll; }
  841.  
  842.     bool operator<(unsigned long l) const { return *this < wxULongLongWx(l); }
  843.     bool operator>(unsigned long l) const { return *this > wxULongLongWx(l); }
  844.     bool operator==(unsigned long l) const
  845.     {
  846.         return (m_hi == 0 && m_lo == (unsigned long)l);
  847.     }
  848.  
  849.     bool operator<=(unsigned long l) const { return *this < l || *this == l; }
  850.     bool operator>=(unsigned long l) const { return *this > l || *this == l; }
  851.  
  852.     // multiplication
  853.     wxULongLongWx operator*(const wxULongLongWx& ll) const;
  854.     wxULongLongWx& operator*=(const wxULongLongWx& ll);
  855.  
  856.     // division
  857.     wxULongLongWx operator/(const wxULongLongWx& ll) const;
  858.     wxULongLongWx& operator/=(const wxULongLongWx& ll);
  859.  
  860.     wxULongLongWx operator%(const wxULongLongWx& ll) const;
  861.  
  862.     void Divide(const wxULongLongWx& divisor,
  863.                 wxULongLongWx& quotient,
  864.                 wxULongLongWx& remainder) const;
  865.  
  866.     // input/output
  867.  
  868.     // return the string representation of this number
  869.     wxString ToString() const;
  870.  
  871.     void *asArray() const;
  872.  
  873. #if wxUSE_STD_IOSTREAM
  874.     friend wxSTD ostream& operator<<(wxSTD ostream&, const wxULongLongWx&);
  875. #endif // wxUSE_STD_IOSTREAM
  876.  
  877. private:
  878.     // long is at least 32 bits, so represent our 64bit number as 2 longs
  879.  
  880.     unsigned long m_hi;
  881.     unsigned long m_lo;
  882.  
  883. #ifdef wxLONGLONG_TEST_MODE
  884.     void Check()
  885.     {
  886.         wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo );
  887.     }
  888.  
  889.     unsigned wxLongLong_t m_ll;
  890. #endif // wxLONGLONG_TEST_MODE
  891. };
  892.  
  893. #endif // wxUSE_LONGLONG_WX
  894.  
  895. // ----------------------------------------------------------------------------
  896. // binary operators
  897. // ----------------------------------------------------------------------------
  898.  
  899. inline bool operator<(long l, const wxLongLong& ll) { return ll > l; }
  900. inline bool operator>(long l, const wxLongLong& ll) { return ll < l; }
  901. inline bool operator<=(long l, const wxLongLong& ll) { return ll >= l; }
  902. inline bool operator>=(long l, const wxLongLong& ll) { return ll <= l; }
  903. inline bool operator==(long l, const wxLongLong& ll) { return ll == l; }
  904. inline bool operator!=(long l, const wxLongLong& ll) { return ll != l; }
  905.  
  906. inline wxLongLong operator+(long l, const wxLongLong& ll) { return ll + l; }
  907. inline wxLongLong operator-(long l, const wxLongLong& ll)
  908. {
  909.     return wxLongLong(l) - ll;
  910. }
  911.  
  912. inline bool operator<(unsigned long l, const wxULongLong& ull) { return ull > l; }
  913. inline bool operator>(unsigned long l, const wxULongLong& ull) { return ull < l; }
  914. inline bool operator<=(unsigned long l, const wxULongLong& ull) { return ull >= l; }
  915. inline bool operator>=(unsigned long l, const wxULongLong& ull) { return ull <= l; }
  916. inline bool operator==(unsigned long l, const wxULongLong& ull) { return ull == l; }
  917. inline bool operator!=(unsigned long l, const wxULongLong& ull) { return ull != l; }
  918.  
  919. inline wxULongLong operator+(unsigned long l, const wxULongLong& ull) { return ull + l; }
  920.  
  921. // FIXME: this should return wxLongLong
  922. inline wxULongLong operator-(unsigned long l, const wxULongLong& ull)
  923. {
  924.     return wxULongLong(l) - ull;
  925. }
  926.  
  927. #endif // _WX_LONGLONG_H
  928.