//
// LiDIA - a library for computational number theory
//   Copyright (c) 1995 by the LiDIA Group
//
// File        : lidia.h 
// Author      : Thomas Papanikolaou (TP)
// Last change : TP, Feb 7 1995, initial version
//

#ifndef LIDIA_H
#define LIDIA_H

#include <LiDIA/config.h>

/**
 ** include system files
 **/

#include <iostream.h>
#include <fstream.h>

#ifdef HAVE_STDLIB_H
#ifdef __GNUG__
#include <stdlib.h>
#endif
#endif

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_MATH_H
#include <math.h>
#endif

#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_UNISTD_H 
#include <unistd.h>
#endif

#ifdef HAVE_TIME_H
#include <time.h>
#endif

#ifdef HAVE_TIMES_H
#include <times.h>
#endif

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifdef HAVE_SYS_TIMES_H
#include <sys/times.h>
#endif

#ifdef HAVE_RESOURCE_H
#include <resource.h>
#endif

#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif

#if defined(__EMX__)
#include <sys/param.h>
#endif

#if !defined (HZ) && defined(CLK_TCK)
#define HZ CLK_TCK
#endif

/**
 ** Debug handling for templates
 **/

#ifndef LIDIA_DEBUG_LIMIT
#define LIDIA_DEBUG_LIMIT -1000
#endif
#define LDBL_VECTOR (LIDIA_DEBUG_LIMIT + 0)
#define LDBL_UNIPOL (LIDIA_DEBUG_LIMIT + 50)
#define LDBL_UNIPOW (LIDIA_DEBUG_LIMIT + 100)
#define LDBL_MATRIX (LIDIA_DEBUG_LIMIT + 150)


/**
 ** include LiDIA system files
 **/

#include <LiDIA/warning.h>
#include <LiDIA/error.h>
#include <LiDIA/debug.h>
#include <LiDIA/memory.h>

/**
 ** these are the types for machine integers
 ** define sizetify to longify if lidia_size_t == long
 **/

typedef          int lidia_size_t;
#define sizetify intify

typedef          long sdigit;
typedef unsigned long udigit;

/**
 ** LEDA compatability
 ** ------------------
 ** if LiDIA is compiled with LEDA, we assume that the user uses
 ** LEDA bools and macros.
 **/

#ifdef HAVE_LEDA
#define LIDIA_BUILTIN_BOOL
#define LIDIA_MACROS
#endif

/**
 ** definition of the type bool. gcc-2.6.x and Macintosh
 ** supports the type bool.
 **/

#if (__GNUC__ > 1 && __GNUC_MINOR__ > 5) || defined(__MWERKS__)
#ifndef  LIDIA_BUILTIN_BOOL
#define LIDIA_BUILTIN_BOOL
#endif
#endif
#if !defined(LIDIA_BUILTIN_BOOL)
typedef char bool;
enum {false=0, true=1};
#endif

/**
 ** gnu compiler -> use mutable
 ** otherwise	 -> use a cast to avoid mutable
 ** 
 ** classname is the type of *w.
 ** w is a pointer to classname.
 **
 ** The macro "returns" a pointer.
 **/

#ifndef __GNUC__ 
#ifndef LIDIA_NO_MUTABLE
#define LIDIA_NO_MUTABLE
#endif
#ifndef LIDIA_MUTABLE
#define LIDIA_MUTABLE
#define LIDIA_MUT(classname, w) \
    ((classname*) (w))
#endif
#else
#ifndef LIDIA_MUTABLE
#define LIDIA_MUTABLE mutable
#define LIDIA_MUT(classname, w) \
    (w)
#endif
#endif


/**
 ** LiDIA macros
 **/

#ifndef LIDIA_MACROS
#define LIDIA_MACROS
#define nil      0
#define newline  cout << "\n"
#define forever  for (;;)
#endif

#define lidia_rint(x) (floor((x)+(double)0.5))

#if (defined(__hpux) && !defined(__STDC__))
#define __STDC__
#endif

#ifdef __STDC__
#define LIDIA_CONCAT2(a,b) a##b
#define LIDIA_CONCAT3(a,b,c) a##b##c
#define LIDIA_CONCAT4(a,b,c,d) a##b##c##d
#else
#define LIDIA_CONCAT2(a,b) a/**/b
#define LIDIA_CONCAT3(a,b,c) a/**/b/**/c
#define LIDIA_CONCAT4(a,b,c,d) a/**/b/**/c/**/d
#endif

#if (!defined(__GNUG__) && defined(__sgi) && defined(__mips))
#define LIDIA_SIGNAL_FUNCTION(f) void f(...)
#else
#define LIDIA_SIGNAL_FUNCTION(f) void f(int)
#endif

#endif
