/*!
  \file
  \brief BDM's exception-throwing macros.
  \author Vaclav Barta.

  -----------------------------------
  BDM++ - C++ library for Bayesian Decision Making under Uncertainty

  Using IT++ for numerical operations
  -----------------------------------
*/

#ifndef bdmerror_h
#define bdmerror_h

// modelled after IT++ assert macros, somewhat simplified

#include <sstream>
#include <string>

namespace bdm {

//! Helper function for the \c bdm_assert and \c bdm_assert_debug macros
void bdm_assert_f ( const std::string &ass, const std::string &msg, const std::string &file, int line );

//! Helper function for the \c bdm_error macro
void bdm_error_f ( const std::string &msg, const std::string &file, int line );

//! Helper function for the \c bdm_warning macro
void bdm_warning_f ( const std::string &msg, const std::string &file, int line );

}

//! Throw std::runtime_exception if \c t is not true
#define bdm_assert(t, s) \
	if (!(t)) { \
		std::ostringstream bdm_out; \
		bdm_out << s; \
		bdm::bdm_assert_f(#t, bdm_out.str(), __FILE__, __LINE__); \
	} else ((void) 0)

#if defined(NDEBUG)
//! Throw std::runtime_exception if \c t is not true and NDEBUG is not defined
#define bdm_assert_debug(t, s) ((void) 0)
#else
//! Throw std::runtime_exception if \c t is not true and NDEBUG is not defined
#define bdm_assert_debug(t, s) bdm_assert(t, s)
#endif // if defined(NDEBUG)

#if defined(NDEBUG)
//! DO argument if in DEBUG model
#define DEBUG(command) ((void) 0)
#else
//! DO argument if in DEBUG model
#define DEBUG(command) command
#endif // if defined(NDEBUG)

//! Unconditionally throw std::runtime_error
#define bdm_error(s) \
	if (true) { \
		std::ostringstream bdm_out; \
		bdm_out << s; \
		bdm::bdm_error_f(bdm_out.str(), __FILE__, __LINE__); \
	} else ((void) 0)

//! Display a warning message
#define bdm_warning(s) \
	if (true) { \
		std::ostringstream bdm_out; \
		bdm_out << s; \
		bdm::bdm_warning_f(bdm_out.str(), __FILE__, __LINE__); \
	} else ((void) 0)

#define NOT_IMPLEMENTED(RESULT) { bdm_error( "Not implemented" ); return RESULT; }

#define NOT_IMPLEMENTED_VOID { bdm_error( "Not implemented" ); }

#endif
