/// These are automatically generated checked C++ bindings for isl.
///
/// isl is a library for computing with integer sets and maps described by
/// Presburger formulas. On top of this, isl provides various tools for
/// polyhedral compilation, ranging from dependence analysis over scheduling
/// to AST generation.

#ifndef ISL_CPP_CHECKED
#define ISL_CPP_CHECKED

#include <stdio.h>
#include <stdlib.h>

#include <functional>
#include <memory>
#include <ostream>
#include <string>
#include <type_traits>

namespace isl {
namespace checked {

#define ISLPP_STRINGIZE_(X) #X
#define ISLPP_STRINGIZE(X) ISLPP_STRINGIZE_(X)

#define ISLPP_ASSERT(test, message)                          \
  do {                                                       \
    if (test)                                                \
      break;                                                 \
    fputs("Assertion \"" #test "\" failed at " __FILE__      \
      ":" ISLPP_STRINGIZE(__LINE__) "\n  " message "\n",     \
      stderr);                                               \
    abort();                                                 \
  } while (0)

/* Class used to check that isl::checked::boolean,
 * isl::checked::stat and isl::checked::size values are checked for errors.
 */
struct checker {
	bool checked = false;
	~checker() {
		ISLPP_ASSERT(checked, "IMPLEMENTATION ERROR: Unchecked state");
	}
};

class boolean {
private:
  mutable std::shared_ptr<checker> check = std::make_shared<checker>();
  isl_bool val;

  friend boolean manage(isl_bool val);
  boolean(isl_bool val): val(val) {}
public:
  static boolean error() {
    return boolean(isl_bool_error);
  }
  boolean()
      : val(isl_bool_error) {}

  /* implicit */ boolean(bool val)
      : val(val ? isl_bool_true : isl_bool_false) {}

  isl_bool release() {
    auto tmp = val;
    val = isl_bool_error;
    check->checked = true;
    return tmp;
  }

  bool is_error() const { check->checked = true; return val == isl_bool_error; }
  bool is_false() const { check->checked = true; return val == isl_bool_false; }
  bool is_true() const { check->checked = true; return val == isl_bool_true; }

  explicit operator bool() const {
    ISLPP_ASSERT(check->checked, "IMPLEMENTATION ERROR: Unchecked error state");
    ISLPP_ASSERT(!is_error(), "IMPLEMENTATION ERROR: Unhandled error state");
    return is_true();
  }

  boolean negate() {
    if (val == isl_bool_true)
      val = isl_bool_false;
    else if (val == isl_bool_false)
      val = isl_bool_true;
    return *this;
  }

  boolean operator!() const {
    return boolean(*this).negate();
  }
};

inline boolean manage(isl_bool val) {
  return boolean(val);
}

class ctx {
  isl_ctx *ptr;
public:
  /* implicit */ ctx(isl_ctx *ctx)
      : ptr(ctx) {}
  isl_ctx *release() {
    auto tmp = ptr;
    ptr = nullptr;
    return tmp;
  }
  isl_ctx *get() {
    return ptr;
  }
};

/* Class encapsulating an isl_stat value.
 */
class stat {
private:
	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
	isl_stat val;

	friend stat manage(isl_stat val);
	stat(isl_stat val) : val(val) {}
public:
	static stat ok() {
		return stat(isl_stat_ok);
	}
	static stat error() {
		return stat(isl_stat_error);
	}
	stat() : val(isl_stat_error) {}

	isl_stat release() {
		check->checked = true;
		return val;
	}

	bool is_error() const {
		check->checked = true;
		return val == isl_stat_error;
	}
	bool is_ok() const {
		check->checked = true;
		return val == isl_stat_ok;
	}
};

inline stat manage(isl_stat val)
{
	return stat(val);
}

/* Class encapsulating an isl_size value.
 */
class size {
private:
	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
	isl_size val;

	friend size manage(isl_size val);
	size(isl_size val) : val(val) {}
public:
	size() : val(isl_size_error) {}

	isl_size release() {
		auto tmp = val;
		val = isl_size_error;
		check->checked = true;
		return tmp;
	}

	bool is_error() const {
		check->checked = true;
		return val == isl_size_error;
	}

	explicit operator unsigned() const {
		ISLPP_ASSERT(check->checked,
			    "IMPLEMENTATION ERROR: Unchecked error state");
		ISLPP_ASSERT(!is_error(),
			    "IMPLEMENTATION ERROR: Unhandled error state");
		return val;
	}
};

inline size manage(isl_size val)
{
	return size(val);
}

}
} // namespace isl

