
#ifndef Utils_hh
#define Utils_hh

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <limits>
#include <cassert>
#include <cstdlib>
#include <cerrno>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>

#include "BackTrace.hh"

using namespace std;




/**
 * Defines customized error macros.
 * (somehow adapted from err.h and error.h)
 */

#define myerror_at_line(status, error, file, line, ...) { fprintf(stderr, "Error at %s:%i: ", file, line); fprintf(stderr, __VA_ARGS__); if (error) perror(" errno"); fprintf(stderr, "\n"); exit(status); }
#define myerr(...) myerror_at_line(EXIT_FAILURE, errno, __FILE__, __LINE__, __VA_ARGS__)
#define myerrx(...) myerror_at_line(EXIT_FAILURE, 0, __FILE__, __LINE__, __VA_ARGS__)


/**
 * Hard assert.
 */
#define check(b) { if (not (b)) {BackTrace::print(); myerror_at_line(EXIT_FAILURE, errno, __FILE__, __LINE__, "Assertion `" #b "' failed in check()."); }}


/**
 * We use a macro to specifically indicate when something is unused,
 * thus the compiler doesn't cry when using NDEBUG.
 */

#define _unused(x) ((void)x)


/**
 * We use a macro to specifically indicate when some code is unreachable,
 * thus the compiler doesn't cry when using NDEBUG.
 */
#define _unreachable() {assert(0); myerrx("unreachable code reached.");}



/**
 * Defines an infinite for doubles.
 */
const double infinite = numeric_limits<double>::infinity();

/**
 * Defines maxint, minint for ints.
 */
const int maxint = numeric_limits<int>::max();
const int minint = numeric_limits<int>::min();


/**
 * Conversion: string to int.
 */
inline int s2i (const string& s) {
    istringstream iss(s);
    int i;
    iss >> i;
    return i;
}


/**
 * Conversion: int to string
 */
inline string i2s (int i) {
    ostringstream oss;
    oss << i;
    return oss.str();
}


/**
 * Size as int.
 */
template <typename T>
inline int sze (T& x) {
    return int(x.size());
}


#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

////////////////// implies connective //////////////////////////

#define implies  % (boolean)

class boolean {

public:

  boolean(bool b = false) : val(b) { }
  operator bool() { return val; }
  friend boolean  operator %(bool b1, boolean b2);

private:
  bool val;
};

inline boolean  operator %(bool b1, boolean b2) {
  return not b1 or b2.val;
}

////////////////// print macro //////////////////////////

#ifndef PRINT
#define PRINT_AUX(ARG,SEP)  {string tmpStr(SEP # ARG # SEP); \
                             cerr << boolalpha \
                                  << tmpStr.substr(1, tmpStr.size()-5)    \
                                  << ": " << ARG << endl;}
#define PRINT(ARG)          PRINT_AUX(ARG,"\"")
#endif

/////////////////// random numbers //////////////////////

class Random_generator {

	static const int RANDOMIZE_MODULUS    = 2147483647;
	static const int RANDOMIZE_MULTIPLIER = 48271;
	static const int RANDOMIZE_DEFAULT    = 123456789;  // Initial seed.
	static const int RANDOMIZE_MAX        = RANDOMIZE_MODULUS - 2;

	long rnd_seed;

public:

	// Sets random seed.
	void srandomize(int s = RANDOMIZE_DEFAULT) {
	  if (s < 0) s = -s;
	  rnd_seed = 1 + s % (RANDOMIZE_MODULUS - 1);
	}

	// Returns pseudo-random number between 0 and RANDOMIZE_MAX
	int randomize(void) {
	  const long Q = RANDOMIZE_MODULUS / RANDOMIZE_MULTIPLIER;
	  const long R = RANDOMIZE_MODULUS % RANDOMIZE_MULTIPLIER;
	  long t;

	  t = RANDOMIZE_MULTIPLIER * (rnd_seed % Q) - R * (rnd_seed / Q);
	  if (t > 0)
		rnd_seed = t;
	  else
		rnd_seed = t + RANDOMIZE_MODULUS;
	  return rnd_seed - 1;
	}

	// Returns a random number between l and u.
	int randomize(int l, int u) {
	  return l + randomize() % (u-l+1);

	}


};

#endif
