// COPYRIGHT:
//      IBM Open Class Library
//      (C) Copyright International Business Machines Corporation 1992, 1997
//      Licensed Material - Program-Property of IBM - All Rights Reserved.
//

// ilonglng.hpp
// Revision: 52 1.17.1.4 source/core/utils/ilonglng.hpp, utilities, ioc.v400, 980918 

#ifndef _ILONGLNG_
#define _ILONGLNG_

#include <ibasepl.hpp>  // Need the base library

/*    An ILongLong class is ONLY needed with third-party compilers that
*     do not support the "long long" extension.
*/

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#if defined(__IBMCPP__) && (__IBMCPP__ >= 360 || !defined(__OS2__))

typedef long long ILongLong;

#elif defined(_AIX)

typedef long long ILongLong;

#elif defined(_MSC_VER)

typedef __int64 ILongLong;

#else

/*************************************************************************************
 *    A wide integer type : ILongLong
 *
 *    This type is ONLY needed with third-party compilers that do not support
 *    the "long long" extension.
 *
 *    ILongLong implements a signed integer data type twice as wide as the
 *    long data-type.  It supports most standard integer operations, as defined
 *    by ANSI C, thus serving as an extension of the long data-type.
 *
 *
 *    Creating a ILongLong:-
 *
 *           ILongLong can be constructed from a pair of longs.  The mostSignificant
 *           is signed and the leastSignificant is unsigned. They can be accessed through the
 *           GetMostSignificant() and GetLeastSignificant() methods.
 *
 *           ILongLong can be constructed from a single integral value (stored in
 *           any of the Standard C integral types),  treated as the leastSignificant;
 *           the constructor takes care of the mostSignificant.
 *
 *           ILongLong can also be constructed from a floating point double or long-double value.
 *           IDoubleLongMax() and IDoubleLongMin() are, respectively, the largest and smallest
 *           ILongLong values.
 *
 *    Operations supported:-
 *
 *           arithmetic operations:             +, -, *, /, %
 *           and their assignment forms: +=, -=, *=, /=, %=
 *
 *           bitwise logical operations: |, &, ^, >>, <<
 *           and their assignment forms: |=, &=, ^=, >>=, <<=
 *
 *           relational operations:             ==, !=, >, >=, <, <=
 *
 *           assignment operation:              =
 *
 *           unary operations:           +, -, ~, !
 *
 *           logical operations:         &&, ||
 *
 *           increment/decrement ops            ++a, a++, --a, a--
 *
 *           streaming operations:              >>=, <<=
 *
 *           Hashing                            Hash(ILongLong)
 *
 *           conversions:
 *                                       double -> ILongLong (constructor)
 *                                       ILongLong -> long double (type cast)
 *                                              long double -> ILongLong (constructor)
 *
 *
 *    Caveats:-
 *
 *           The operators <<= and >>= are overloaded in unrelated ways as shift
 *           and streaming operators.
 *
 *           Type casts from ILongLong -> smaller integer types are not supported.
 *
 *           The conditional and comma operators (? : and ,)  are not supported.
 *
 *           ILongLong is not subclassable (it may be replaced by a compiler built-in).
 *
 *           The conversions long double/double  -> ILongLong may raise floating-point exceptions.
 *           In particular, if a value in the long double/double format is infinite, NaN,
 *           or beyond the range of ILongLong, then the conversion will set the
 *           floating-point invalid flag. Floating point flags do not affect the
 *           user unless the user tests the flags or installs exception handlers for
 *           them.
 *
 *    NOTE:  Inline implementation of some ILongLong methods and global operators
 *           are in PrimitiveTypesImp.h, which is included by this file. The C typedefs
 *           are in CPrimitiveTypes.h which is also included by this file.
 *
 *
 *************************************************************************************/
#ifndef __OS2__
     #include <ICPTypes.h>              //includes C Types
#endif

#include <iprimtyp.hpp>

#pragma pack(push,4)
#pragma enum(4)

class ILongLong
{
public:
      /* constructor/destructor - inlined for performance */
      //ILongLong (const ILongLong&);           //use default version
      ILongLong (long mostSignificant, unsigned long leastSignificant);
      ILongLong (unsigned long);
      ILongLong (long);
      ILongLong (unsigned int);
      ILongLong (int);
      ILongLong (){}
      ~ILongLong(){}

      /* conversions to and from floating point */
      ILongLong (long double);                  // long double -> ILongLong
      operator long double () const;                   // ILongLong -> long double

      ILongLong (double);                       // double -> ILongLong

      /* Max and Min ILongLong */
      static ILongLong ILongLongMax(void);
      static ILongLong ILongLongMin(void);


      /* ILongLong Field Access methods */
      long          GetMostSignificant() const;
      unsigned long GetLeastSignificant() const;


      /* Hash */
      HashResult    Hash() const;


      /* Operator Overloading */
      // ILongLong&        operator=  (const ILongLong& theNumber);

      ILongLong&           operator++     ();                 //prefix
      ILongLong            operator++     (int);              //postfix
      ILongLong&           operator--     ();                 //prefix
      ILongLong            operator--     (int);       //postfix

      ILongLong&           operator+= (const ILongLong&);
      ILongLong&           operator-= (const ILongLong&);
      ILongLong&           operator*= (const ILongLong&);
      ILongLong&           operator/= (const ILongLong&);

      ILongLong&           operator%= (const ILongLong&);
      ILongLong&           operator|= (const ILongLong&);
      ILongLong&           operator&= (const ILongLong&);
      ILongLong&           operator^= (const ILongLong&);

      ILongLong&           operator>>= (int);   // right shift operator
      ILongLong&           operator<<= (int);   // left shift operator

#ifndef NO_Internal

private:
      long                 fMostSignificant;
      unsigned long        fLeastSignificant;

#endif   /* NO_Internal */

};

#pragma enum(pop)
#pragma pack(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

/********************************************************************************/
/*  END OF CLASS DECLARATION.                                               */
/********************************************************************************/

/******************************************************************************    */
/*                                                                   */
/*  GLOBAL BINARY OPERATOR DECLARATIONS.                             */
/*                                                                   */
/******************************************************************************    */

ILongLong    operator+     (const ILongLong&,   const ILongLong&);
ILongLong    operator+     (const ILongLong&,   long);
ILongLong    operator+     (const ILongLong&,   unsigned long);
ILongLong    operator+     (const ILongLong&,   int);
ILongLong    operator+     (const ILongLong&,   unsigned int);
ILongLong    operator+     (long,                      const ILongLong&);
ILongLong    operator+     (unsigned long,      const ILongLong&);
ILongLong    operator+     (int,                const ILongLong&);
ILongLong    operator+     (unsigned int,              const ILongLong&);

ILongLong    operator-     (const ILongLong&,   const ILongLong&);
ILongLong    operator-     (const ILongLong&,   long);
ILongLong    operator-     (const ILongLong&,   unsigned long);
ILongLong    operator-     (const ILongLong&,   int);
ILongLong    operator-     (const ILongLong&,   unsigned int);
ILongLong    operator-     (long,                      const ILongLong&);
ILongLong    operator-     (unsigned long,      const ILongLong&);
ILongLong    operator-     (int,                const ILongLong&);
ILongLong    operator-     (unsigned int,              const ILongLong&);

ILongLong    operator*     (const ILongLong&,   const ILongLong&);
ILongLong    operator*     (const ILongLong&,   long);
ILongLong    operator*     (const ILongLong&,   unsigned long);
ILongLong    operator*     (const ILongLong&,   int);
ILongLong    operator*     (const ILongLong&,   unsigned int);
ILongLong    operator*     (long,                      const ILongLong&);
ILongLong    operator*     (unsigned long,      const ILongLong&);
ILongLong    operator*     (int,                const ILongLong&);
ILongLong    operator*     (unsigned int,              const ILongLong&);

ILongLong    operator/     (const ILongLong&,   const ILongLong&);
ILongLong    operator/     (const ILongLong&,   long);
ILongLong    operator/     (const ILongLong&,   unsigned long);
ILongLong    operator/     (const ILongLong&,   int);
ILongLong    operator/     (const ILongLong&,   unsigned int);
ILongLong    operator/     (long,                      const ILongLong&);
ILongLong    operator/     (unsigned long,      const ILongLong&);
ILongLong    operator/     (int,                const ILongLong&);
ILongLong    operator/     (unsigned int,              const ILongLong&);

ILongLong    operator%     (const ILongLong&,   const ILongLong&);
ILongLong    operator%     (const ILongLong&,   long);
ILongLong    operator%     (const ILongLong&,   unsigned long);
ILongLong    operator%     (const ILongLong&,   int);
ILongLong    operator%     (const ILongLong&,   unsigned int);
ILongLong    operator%     (long,                      const ILongLong&);
ILongLong    operator%     (unsigned long,      const ILongLong&);
ILongLong    operator%     (int,                const ILongLong&);
ILongLong    operator%     (unsigned int,              const ILongLong&);

ILongLong    operator-     (const ILongLong&);
ILongLong    operator~     (const ILongLong&);

bool         operator!     (const ILongLong&);

bool         operator||    (const ILongLong&,   const ILongLong&);
bool         operator||    (const ILongLong&,   long);
bool         operator||    (const ILongLong&,   unsigned long);
bool         operator||    (const ILongLong&,   int);
bool         operator||    (const ILongLong&,   unsigned int);
bool         operator||    (long,                      const ILongLong&);
bool         operator||    (unsigned long,      const ILongLong&);
bool         operator||    (int,                const ILongLong&);
bool         operator||    (unsigned int,              const ILongLong&);

bool         operator&&    (const ILongLong&,   const ILongLong&);
bool         operator&&    (const ILongLong&,   long);
bool         operator&&    (const ILongLong&,   unsigned long);
bool         operator&&    (const ILongLong&,   int);
bool         operator&&    (const ILongLong&,   unsigned int);
bool         operator&&    (long,                      const ILongLong&);
bool         operator&&    (unsigned long,      const ILongLong&);
bool         operator&&    (int,                const ILongLong&);
bool         operator&&    (unsigned int,              const ILongLong&);

ILongLong    operator|     (const ILongLong&,   const ILongLong&);
ILongLong    operator|     (const ILongLong&,   long);
ILongLong    operator|     (const ILongLong&,   unsigned long);
ILongLong    operator|     (const ILongLong&,   int);
ILongLong    operator|     (const ILongLong&,   unsigned int);
ILongLong    operator|     (long,                      const ILongLong&);
ILongLong    operator|     (unsigned long,      const ILongLong&);
ILongLong    operator|     (int,                const ILongLong&);
ILongLong    operator|     (unsigned int,              const ILongLong&);

ILongLong    operator&     (const ILongLong&,   const ILongLong&);
ILongLong    operator&     (const ILongLong&,   long);
ILongLong    operator&     (const ILongLong&,   unsigned long);
ILongLong    operator&     (const ILongLong&,   int);
ILongLong    operator&     (const ILongLong&,   unsigned int);
ILongLong    operator&     (long,                      const ILongLong&);
ILongLong    operator&     (unsigned long,      const ILongLong&);
ILongLong    operator&     (int,                const ILongLong&);
ILongLong    operator&     (unsigned int,              const ILongLong&);

ILongLong    operator^     (const ILongLong&,   const ILongLong&);
ILongLong    operator^     (const ILongLong&,   long);
ILongLong    operator^     (const ILongLong&,   unsigned long);
ILongLong    operator^     (const ILongLong&,   int);
ILongLong    operator^     (const ILongLong&,   unsigned int);
ILongLong    operator^     (long,                      const ILongLong&);
ILongLong    operator^     (unsigned long,      const ILongLong&);
ILongLong    operator^     (int,                const ILongLong&);
ILongLong    operator^     (unsigned int,              const ILongLong&);

bool         operator==    (const ILongLong&,   const ILongLong&);
bool         operator==    (const ILongLong&,   long);
bool         operator==    (const ILongLong&,   unsigned long);
bool         operator==    (const ILongLong&,   int);
bool         operator==    (const ILongLong&,   unsigned int);
bool         operator==    (long,                      const ILongLong&);
bool         operator==    (unsigned long,      const ILongLong&);
bool         operator==    (int,                const ILongLong&);
bool         operator==    (unsigned int,              const ILongLong&);

bool         operator!=    (const ILongLong&,   const ILongLong&);
bool         operator!=    (const ILongLong&,   long);
bool         operator!=    (const ILongLong&,   unsigned long);
bool         operator!=    (const ILongLong&,   int);
bool         operator!=    (const ILongLong&,   unsigned int);
bool         operator!=    (long,                      const ILongLong&);
bool         operator!=    (unsigned long,      const ILongLong&);
bool         operator!=    (int,                const ILongLong&);
bool         operator!=    (unsigned int,              const ILongLong&);

bool         operator>     (const ILongLong&,   const ILongLong&);
bool         operator>     (const ILongLong&,   long);
bool         operator>     (const ILongLong&,   unsigned long);
bool         operator>     (const ILongLong&,   int);
bool         operator>     (const ILongLong&,   unsigned int);
bool         operator>     (long,                      const ILongLong&);
bool         operator>     (unsigned long,      const ILongLong&);
bool         operator>     (int,                const ILongLong&);
bool         operator>     (unsigned int,              const ILongLong&);

bool         operator>=    (const ILongLong&,   const ILongLong&);
bool         operator>=    (const ILongLong&,   long);
bool         operator>=    (const ILongLong&,   unsigned long);
bool         operator>=    (const ILongLong&,   int);
bool         operator>=    (const ILongLong&,   unsigned int);
bool         operator>=    (long,                      const ILongLong&);
bool         operator>=    (unsigned long,      const ILongLong&);
bool         operator>=    (int,                const ILongLong&);
bool         operator>=    (unsigned int,              const ILongLong&);

bool         operator<     (const ILongLong&,   const ILongLong&);
bool         operator<     (const ILongLong&,   long);
bool         operator<     (const ILongLong&,   unsigned long);
bool         operator<     (const ILongLong&,   int);
bool         operator<     (const ILongLong&,   unsigned int);
bool         operator<     (long,                      const ILongLong&);
bool         operator<     (unsigned long,      const ILongLong&);
bool         operator<     (int,                const ILongLong&);
bool         operator<     (unsigned int,              const ILongLong&);

bool         operator<=    (const ILongLong&,   const ILongLong&);
bool         operator<=    (const ILongLong&,   long);
bool         operator<=    (const ILongLong&,   unsigned long);
bool         operator<=    (const ILongLong&,   int);
bool         operator<=    (const ILongLong&,   unsigned int);
bool         operator<=    (long,                      const ILongLong&);
bool         operator<=    (unsigned long,      const ILongLong&);
bool         operator<=    (int,                const ILongLong&);
bool         operator<=    (unsigned int,              const ILongLong&);


ILongLong operator>>              (const ILongLong&,   int);
ILongLong operator<<              (const ILongLong&,   int);

/****************************************************************************/
/*  END OF GLOBAL BINARY OPERATOR DECLARATIONS.                             */
/****************************************************************************/

#include <ilonglng.inl>

#endif // __IBMCPP__

#endif // _ILONGLNG_

