/*
 * Copyright (c) 1997,1998
 * Babes-Bolyai University, Cluj-Napoca
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Babes-Bolyai University makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

#ifndef __OCL_BASIC__
#define __OCL_BASIC__

/////////////////////////////////////////////////////////////////////////////

#include <string>

#ifndef __OCL_NO_NAMESPACES
namespace ocl {
#endif

#ifndef __OCL_NO_STD
using namespace std;
#endif

/////////////////////////////////////////////////////////////////////////////
// OCL Basic Types - definitions

typedef void                    Void;
typedef double                  Real;
typedef int                     Integer;
typedef bool                    Boolean;

#ifndef __OCL_NO_UNICODE
typedef wchar_t                 Char;
#else
typedef char                    Char;
#endif

typedef basic_string<Char>      String;

template <class T>
class OclExpression {
    typedef /* typename */ T evaluationType;
    virtual evaluationType evaluate() = 0;
};

/////////////////////////////////////////////////////////////////////////////
// OCL Basic Types - inline implementation

#ifndef __OCL_NO_IMPLEMENTATION

inline Real abs(Real r)
{
    return (r >= 0) ? r : -r;
}

inline Integer floor(Real r)
{
    return (r >= 0) ?
        ((Integer) r) : ((Integer) r - ((r < (Real)(Integer) r) ? 1 : 0));
}

inline Real min(Real r1, Real r2)
{
    return (r1 <= r2) ? r1 : r2;
}

inline Real max(Real r1, Real r2)
{
    return (r1 >= r2) ? r1 : r2;
}

inline Integer abs(Integer i)
{
    return (i >= 0) ? i : -i;
}

inline Integer div(Integer i1, Integer i2)
{
    return i1 / i2;
}

inline Integer mod(Integer i1, Integer i2)
{
    return i1 % i2;
}

inline Integer min(Integer i1, Integer i2)
{
    return (i1 <= i2) ? i1 : i2;
}

inline Integer max(Integer i1, Integer i2)
{
    return (i1 >= i2) ? i1 : i2;
}

inline Boolean or(Boolean b1, Boolean b2)
{
    return b1 || b2;
}

inline Boolean xor(Boolean b1, Boolean b2)
{
    return b1 ^ b2;
}

inline Boolean and(Boolean b1, Boolean b2)
{
    return b1 && b2;
}

inline Boolean not(Boolean b)
{
    return !b;
}

inline Boolean implies(Boolean b1, Boolean b2)
{
    return !b1 || b2;
}

#endif  // !__OCL_NO_IMPLEMENTATION

/////////////////////////////////////////////////////////////////////////////

#ifndef __OCL_NO_NAMESPACES
}  // namespace ocl
#endif

/////////////////////////////////////////////////////////////////////////////

#endif  // __OCL_BASIC__
