/* Copyright (c) 1997-2005
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
*/

#ifndef _POLYMAKE_PLAUSIBLE_CHECKS_H
#define _POLYMAKE_PLAUSIBLE_CHECKS_H "$Project: polymake $$Id: plausible_checks.h,v 1.12 2005/12/14 11:41:57 gawrilow Exp $"

#include <iostream>
#include <sstream>
#include <stdexcept>

// This is a dummy function where you can set a breakpoint in a debugger.
extern void break_on_throw(const char *t);

// Test the condition, compose the message, and throw an exception
#define PLAUSIBLE_CHECK(cond,stream,text) \
do                                        \
 if (cond) {                              \
    std::ostringstream s; stream << text; \
    break_on_throw(s.str().c_str());      \
    if (std::uncaught_exception()) {      \
       std::cerr << "nested error during stack unwind: " << s.str() << std::endl;  \
       abort();                           \
    } else {                              \
       throw std::logic_error(s.str());   \
    }                                     \
 }                                        \
while (0)

#define WARN_PLAUSIBLE !defined(ALL_PLAUSIBLE_CHECKS)
#if WARN_PLAUSIBLE
#  warning plausibility checks enabled
#  define ALL_PLAUSIBLE_CHECKS 1
#endif

// This checks the index arguments of various random-access functions to be in the defined range
#ifndef INDEX_CHECKS
#  if WARN_PLAUSIBLE
#    warning index range checks enabled
#  endif
#  define INDEX_CHECKS ALL_PLAUSIBLE_CHECKS
#endif

// This checks whether the dimensions of vector/matrix objects involved
// in an operation match each other and/or make sense for the specific operation.
#ifndef DIMENSION_CHECKS
#  if WARN_PLAUSIBLE
#    warning vector/matrix dimension checks enabled
#  endif
#  define DIMENSION_CHECKS ALL_PLAUSIBLE_CHECKS
#endif

// This checks the proper ordering of elements included in AVL trees.
#ifndef AVL_CHECKS
#  if WARN_PLAUSIBLE
#    warning AVL checks enabled
#  endif
#  define AVL_CHECKS ALL_PLAUSIBLE_CHECKS
#endif

#if INDEX_CHECKS
#  define INDEX_CHECK(cond,text) PLAUSIBLE_CHECK(cond,s,text)
#  define INDEX_CHECK_WRAP(cond,text) PLAUSIBLE_CHECK(cond,pm::wrap(s),text)
#else
#  define INDEX_CHECK(cond,text)
#  define INDEX_CHECK_WRAP(cond,text)
#endif

#if DIMENSION_CHECKS
#  define DIMENSION_CHECK(cond,text) PLAUSIBLE_CHECK(cond,s,text)
#  define DIMENSION_CHECK_WRAP(cond,text) PLAUSIBLE_CHECK(cond,pm::wrap(s),text)
#else
#  define DIMENSION_CHECK(cond,text)
#  define DIMENSION_CHECK_WRAP(cond,text)
#endif

#if AVL_CHECKS
#  define AVL_CHECK(cond,text) PLAUSIBLE_CHECK(cond,s,text)
#  define AVL_CHECK_WRAP(cond,text) PLAUSIBLE_CHECK(cond,pm::wrap(s),text)
#else
#  define AVL_CHECK(cond,text)
#  define AVL_CHECK_WRAP(cond,text)
#endif

#ifdef POLY_DEBUG
#define POLY_DEBUG_METHOD(Class,Name) static void (Class::* Name##_dummy)() const=&Class::Name; if (false) Name##_dummy=0
#endif

#endif // _POLYMAKE_PLAUSIBLE_CHECKS_H

// Local Variables:
// mode:C++
// End:
