#pragma once
#include <iostream>

/**
#define NDEBUG true
#ifdef NDEBUG
#define db_info(mes)

#else
*/
#define db_info(mes) (std::cout << mes << std::flush)

//#endif

/** inspect macro; like ruby */
#define inspect(x) (std::cerr <<__FILE__ ":"<< __LINE__ << ": " #x << " = "<< (x)  <<std::endl)

/** These macro supply design by contract frame. */
#define require(cond) DBC_ASSERTION(cond, "precondition")
/** These macro supply design by contract frame. */
#define ensure(cond) DBC_ASSERTION(cond, "postcondition")

/** this can hold block.
 *  @USAGE: require_else( a <= 5 ){
 *       cout << "a is more than 5" << endl;
 *   }
 */
#define require_else(cond) for(; !(cond); DBC_ERROR_MESSAGE(#cond, "precondition"))
#define ensure_else(cond) for(; !(cond); DBC_ERROR_MESSAGE(#cond, "postcondition"))

/** I don't know how to use. */
#define error(mes) (std::cerr << mes << std::flush)

/** this funciton enables throw in expression. */
inline bool throwFunction(const char* message){
	throw(message);
	return false;
}

#define DBC_ASSERTION(cond, type)										\
	((cond) || DBC_ERROR_MESSAGE(#cond, type))							\

#define DBC_ERROR_MESSAGE(message, type)									\
	((std::cerr << __FILE__ << ":" << __LINE__<< ": " << type << " error: \n\t" \
	  << message << "\t\t in " << __func__ << std::endl),				\
	  throwFunction(__func__))

