From 342f5c2ca9f7c44820957caf06cfed5aabcc8f9b Mon Sep 17 00:00:00 2001 From: Alexis Breust Date: Fri, 3 May 2019 08:26:40 +0200 Subject: [PATCH 1/2] Base for error/debug/contracts cleanup --- interfaces/driver/lb-utilities.h | 1 + interfaces/maple/lb-maple-utilities.h | 2 + .../rational-cra-builder-early-single.h | 1 + .../smith-form-sparseelim-poweroftwo.h | 18 +- linbox/matrix/sparse-formats.h | 10 - linbox/util/contracts.h | 84 ----- linbox/util/debug.h | 327 +++--------------- linbox/util/error.h | 220 +++++++++++- linbox/vector/light_container.h | 48 +-- 9 files changed, 288 insertions(+), 423 deletions(-) delete mode 100644 linbox/util/contracts.h diff --git a/interfaces/driver/lb-utilities.h b/interfaces/driver/lb-utilities.h index c7214186a..e0127c7e0 100644 --- a/interfaces/driver/lb-utilities.h +++ b/interfaces/driver/lb-utilities.h @@ -36,6 +36,7 @@ /************************************** * definition of LinBox's exceptions * **************************************/ +// @fixme CONSIDER MERGING IN error.h typedef LinBox::LinboxError lb_runtime_error; diff --git a/interfaces/maple/lb-maple-utilities.h b/interfaces/maple/lb-maple-utilities.h index 8ac04bc44..942bb451d 100644 --- a/interfaces/maple/lb-maple-utilities.h +++ b/interfaces/maple/lb-maple-utilities.h @@ -67,6 +67,8 @@ extern "C" { /********************************* * Raising LinBox error in Maple * *********************************/ + // @fixme CONSIDER merging in error.h + // We could print an arbitrary object on error static void lbRaiseError(MKernelVector kv, lb_runtime_error &t){ std::ostringstream out; out< psizes; for(p=k; p( (long)LigneA[(size_t)p].size(), (long)p) ); @@ -441,8 +441,8 @@ namespace LinBox TWOK >>= 1; TWOKMONE >>=1; - ENSURE( TWOK == (UInt_t(1U) << EXPONENT) ); - ENSURE( TWOKMONE == (TWOK - 1U) ); + ASSERT( TWOK == (UInt_t(1U) << EXPONENT) ); + ASSERT( TWOKMONE == (TWOK - 1U) ); ranks.push_back( indcol ); ++ind_pow; @@ -463,7 +463,7 @@ namespace LinBox if (c != -1) { // Pivot has been found REQUIRE( indcol > 0); - const size_t currentrank(indcol-1); + const size_t currentrank(indcol-1); if (c != (long)currentrank) { #ifdef LINBOX_pp_gauss_steps_OUT @@ -481,7 +481,7 @@ namespace LinBox for(size_t l=k + 1; (l < Ni) && (col_density[currentrank]); ++l) FaireElimination(EXPONENT, TWOK, TWOKMONE, LigneA[(size_t)l], LigneA[(size_t)k], invpiv, currentrank, c, col_density); } - + #ifdef LINBOX_pp_gauss_steps_OUT std::cerr << "step[" << k << "], pivot: " << c << std::endl; # ifdef LINBOX_pp_gauss_intermediate_OUT diff --git a/linbox/matrix/sparse-formats.h b/linbox/matrix/sparse-formats.h index 351190c81..2cca4da98 100644 --- a/linbox/matrix/sparse-formats.h +++ b/linbox/matrix/sparse-formats.h @@ -30,16 +30,6 @@ #include "linbox/linbox-tags.h" namespace LinBox { - - /** Exception class for invalid matrix input - */ - namespace Exceptions { - class InvalidMatrixInput {}; - } - - - - //! Sparse matrix format (memory storage) namespace SparseMatrixFormat { class ANY {} ; diff --git a/linbox/util/contracts.h b/linbox/util/contracts.h deleted file mode 100644 index e41e08535..000000000 --- a/linbox/util/contracts.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) LinBox - * - * - * - * ========LICENCE======== - * This file is part of the library LinBox. - * - * LinBox is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * ========LICENCE======== - */ - -#ifndef __LINBOX_util_contracts_H -#define __LINBOX_util_contracts_H - -// Object class is the base class for all -// objects in the system. All classes inheriting from this class need -// to define a method IsValid. This method should perform a -// consistency check on the state of the object. Note that -// this method needs to be defined only when a debug build is made -#include -#include -#if 0 -class Object { -public: -#ifdef _DEBUG - virtual bool IsValid() const = 0; -#endif - -}; -#endif -#if _DEBUG == 2 - -// The debug mode also defines the following macros. Failure of any of these macros leads to -// program termination. The user is notified of the error condition with the right file name -// and line number. The actual failing operation is also printed using the stringizing operator # - -#define ASSERT(bool_expression) assert(bool_expression) -#define IS_VALID(obj) ASSERT((obj) != NULL && (obj)->IsValid()) -#define REQUIRE(bool_expression) ASSERT(bool_expression) -#define ENSURE(bool_expression) ASSERT(bool_expression) -#define STATE(expression) expression - -#elif _DEBUG == 1 - -#define ASSERT(bool_expression) assert(bool_expression) -#define IS_VALID(obj) ASSERT((obj) != NULL && (obj)->IsValid()) -#define REQUIRE(bool_expression) if( ! bool_expression ) throw InvalidOperationException(__FILE__,__LINE__); -#define ENSURE(bool_expression) ASSERT(bool_expression) -#define STATE(expression) expression - -#elif _DEBUG == 0 - -// When built in release mode, the _DEBUG flag would not be defined, thus there will be no overhead -// in the final release from these checks. - -#define ASSERT(ignore) ((void) 0) -#define IS_VALID(ignore) ((void) 0) -#define REQUIRE(ignore) ((void) 0) -#define ENSURE(ignore) ((void) 0) -#define STATE(ignore) ((void) 0) - -#endif - -#endif //__LINBOX_util_contracts_H - -// Local Variables: -// mode: C++ -// tab-width: 4 -// indent-tabs-mode: nil -// c-basic-offset: 4 -// End: -// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s diff --git a/linbox/util/debug.h b/linbox/util/debug.h index d515aa919..de01e3452 100644 --- a/linbox/util/debug.h +++ b/linbox/util/debug.h @@ -36,313 +36,78 @@ #ifndef __LINBOX_util_debug_H #define __LINBOX_util_debug_H +#include "linbox/util/error.h" #include +#include #include -#include "linbox/util/error.h" #include -#include -/*! Check an assertion (à la \c std::assert). +/** + * Check an assertion (à la \c std::assert). + * * If in DEBUG mode, throws a \ref PreconditionFailed exception. - * In REALEASE mode, nothing is checked. + * In RELEASE mode, nothing is checked. * @param check assertion to be checked. */ #ifdef NDEBUG // à la assert. -# define linbox_check(check) +#define linbox_check(check) +#else +#ifdef __GNUC__ +#define linbox_check(check) \ + if (!(check)) throw ::LinBox::PreconditionFailed(__func__, __FILE__, __LINE__, #check); #else -# ifdef __GNUC__ -# define linbox_check(check) \ - if (!(check)) \ - throw ::LinBox::PreconditionFailed (__func__, __FILE__, __LINE__, #check); //BB : should work on non gnu compilers too -# else -# define linbox_check(check) \ - if (!(check)) \ - throw ::LinBox::PreconditionFailed (__FILE__, __LINE__, #check); -# endif +#define linbox_check(check) \ + if (!(check)) throw ::LinBox::PreconditionFailed(__FILE__, __LINE__, #check); +#endif #endif -#define THIS_CODE_COMPILES_BUT_IS_NOT_TESTED \ - std::cout << "*** Warning *** " << std::endl << __func__ << " in " << __FILE__ << ':' << __LINE__ << " is not tested" << std::endl; - -#define THIS_CODE_MAY_NOT_COMPILE_AND_IS_NOT_TESTED \ -throw(" *** Warning *** this piece of code is not compiled by default and may not work") - -#define LB_FILE_LOC \ - __func__,__FILE__,__LINE__ - -namespace LinBox -{ /* Preconditions,Error,Failure,NotImplementedYet */ - /*! A precondition failed. - * @ingroup util - * The \c throw mechanism is usually used here as in - \code - if (!check) - throw(PreconditionFailed(__func__,__LINE__,"this check just failed"); - \endcode - * The parameters of the constructor help debugging. - */ - class PreconditionFailed {//: public LinboxError BB: otherwise, error.h:39 segfaults - static std::ostream *_errorStream; - - public: - /*! @internal - * A precondtion failed. - * @param function usually \c __func__, the function that threw the error - * @param line usually \c __LINE__, the line where it happened - * @param check a string telling what failed. - */ - PreconditionFailed (const char *function, int line, const char *check) - { - if (_errorStream == (std::ostream *) 0) - _errorStream = &std::cerr; - - (*_errorStream) << std::endl << std::endl; - (*_errorStream) << "ERROR (" << function << ":" << line << "): "; - (*_errorStream) << "Precondition not met:" << check << std::endl; - } - - /*! @internal - * A precondtion failed. - * The parameter help debugging. This is not much different from the previous - * except we can digg faster in the file where the exception was triggered. - * @param function usually \c __func__, the function that threw the error - * @param file usually \c __FILE__, the file where this function is - * @param line usually \c __LINE__, the line where it happened - * @param check a string telling what failed. - */ - PreconditionFailed (const char* function, const char *file, int line, const char *check) - { - if (_errorStream == (std::ostream *) 0) - _errorStream = &std::cerr; - - (*_errorStream) << std::endl << std::endl; - (*_errorStream) << "ERROR (at " << function << " in " << file << ':' << line << "): " << std::endl; - (*_errorStream) << "Precondition not met:" << check << std::endl; - } - - static void setErrorStream (std::ostream &stream); - - /*! @internal overload the virtual print of LinboxError. - * @param o output stream - */ - std::ostream &print (std::ostream &o) const - { - if (std::ostringstream * str = dynamic_cast(_errorStream)) - return o << str->str() ; - else - throw LinboxError("LinBox ERROR: PreconditionFailed exception is not initialized correctly"); - } - }; - - /*! @internal A function is "not implemented yet(tm)". - * where, why ? - */ - class NotImplementedYet { - protected: - static std::ostream *_errorStream; - - public: - /*! @internal - * A precondtion failed. - * The parameter help debugging. This is not much different from the previous - * except we can digg faster in the file where the exception was triggered. - * @param function usually \c __func__, the function that threw the error - * @param file usually \c __FILE__, the file where this function is - * @param line usually \c __LINE__, the line where it happened - * @param why by default, lazy people don't provide an explanation. - */ - NotImplementedYet() {} - - NotImplementedYet(const std::string& why) - : NotImplementedYet(why.c_str()) - {} - - NotImplementedYet( const char * why) - { - if (_errorStream == (std::ostream *) 0) - _errorStream = &std::cerr; - - (*_errorStream) << std::endl << std::endl; - (*_errorStream) << "*** ERROR ***" << std::endl; - (*_errorStream) << " This function is not implemented yet " ; - (*_errorStream) << " (" << why << ")" <=0) - (*_errorStream) << ':' << line ; - (*_errorStream) << ")" ; - } - } - else if (file) { // extremely unlikely... - (*_errorStream) << "(in " << file ; - if (line>=0) - (*_errorStream) << ':' << line ; - (*_errorStream) << ")" ; - } - (*_errorStream) << std::endl; - } - }; -} - +// @fixme THIS IS UGLY +#define THIS_CODE_COMPILES_BUT_IS_NOT_TESTED \ + std::cout << "*** Warning *** " << std::endl \ + << __func__ << " in " << __FILE__ << ':' << __LINE__ << " is not tested" << std::endl; -namespace LinBox -{ /* Exceptions. */ +#define THIS_CODE_MAY_NOT_COMPILE_AND_IS_NOT_TESTED \ + throw(" *** Warning *** this piece of code is not compiled by default and may not work") - /*! @defgroup exceptions Exceptions. - * @brief Exceptions in LinBox (proposal, example in \c algorithms/hermite.h). - * If the algorithms cannot return as expected, then an exception is - * thrown. Hopefully it is catched later on. Execptions, when thrown, - * don't write to any stream except in debug mode. However, they can - * explain what they are for with the - * const char *what(void) member. - * - * Any exception derives from the \c LinBox::Exception class. - */ +#define LB_FILE_LOC __func__, __FILE__, __LINE__ - /*! This is the exception class in LinBox. - * Any LinBox exception can derive from it. - */ - class Exception { - // public: - // Exception() {}; - } ; +#if defined(LinBoxSrcOnly) or defined(LinBoxTestOnly) +// for all-source compilation +#include "linbox/util/debug.C" +#endif - /*! Algorithmic exception. - */ - class algoException : public Exception { - // public: - // algoException() {}; - }; +#include - /*! Not implemented yet. - * This piece of code is not fully implemented. - */ - class NotImplementedYetException : public Exception { - }; +// @note Taken from contracts.h +#if _DEBUG == 2 - /*! Something bad an unexpected happened. - */ - class IrrecuperableException : public Exception { - }; +// The debug mode also defines the following macros. Failure of any of these macros leads to +// program termination. The user is notified of the error condition with the right file name +// and line number. The actual failing operation is also printed using the stringizing operator # - /*! The input is not as expected. - */ - class BadInputException : public Exception { - }; -} +#define ASSERT(bool_expression) assert(bool_expression) +#define REQUIRE(bool_expression) ASSERT(bool_expression) +#define STATE(expression) expression -#define CONC(a,b) a ## b +#elif _DEBUG == 1 -#define LINBOX_SILENT_EXCEPTION(name) \ - throw CONC(name,Exception) () +// @fixme InvalidOperationException does not exists +#define ASSERT(bool_expression) assert(bool_expression) +#define REQUIRE(bool_expression) \ + if (!bool_expression) throw InvalidOperationException(__FILE__, __LINE__); +#define STATE(expression) expression -#ifndef DEBUG -#define LINBOX_RAISE_EXCEPTION(name,why) \ - throw CONC(name,Exception) () -#else -#define LINBOX_RAISE_EXCEPTION(name,why) \ - do { \ - std::cerr << " *** EXCEPTION *** (at " << __func__ << " in " << __FILE__ << ':' << __LINE__ << ") " << std::endl; \ - std::cerr << " " << why << std::endl; \ - throw CONC(name,Exception) () ; \ - } while(0) -#endif +#elif _DEBUG == 0 +// When built in release mode, the _DEBUG flag would not be defined, thus there will be no overhead +// in the final release from these checks. +#define ASSERT(ignore) ((void)0) +#define REQUIRE(ignore) ((void)0) +#define STATE(ignore) ((void)0) -#if defined(LinBoxSrcOnly) or defined(LinBoxTestOnly) -// for all-source compilation -#include "linbox/util/debug.C" #endif -#include - #endif // __LINBOX_util_debug_H // Local Variables: diff --git a/linbox/util/error.h b/linbox/util/error.h index 4a373a2b3..5f24714f4 100644 --- a/linbox/util/error.h +++ b/linbox/util/error.h @@ -6,7 +6,7 @@ * ========LICENCE======== * This file is part of the library LinBox. * - * LinBox is free software: you can redistribute it and/or modify + * LinBox is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. @@ -28,6 +28,202 @@ #include #include +/** + * I feel like we need: + * CheckFailed (old PreconditionFailed, only throw by linbox_check() + * NotImplementedYet + * NotTested (old THIS_CODE_COMPILES_BUT_IS_NOT_TESTED) + * ?? (NO PROBABLY NOT AN EXCEPTION) + * InternalError (old LinBoxFailure) + * Error (old LinBoxError/LinboxError/lb_runtime_error) + * ?? (OR RuntimeError) + * InconsistentSystem (old InconsistentSystem/MathInconsistentSystem) + * ?? (SHOULD WE KEEP CERTIFICATE INSIDE? SHOULD IT BE A CHILD OF SOLVEFAILED?) + * SolveFailed + * InvalidInput (old InvalidMatrixInput) + * + * Also feels like we need a auto __LINE__ __FILE__, + * so Error(msg) might be a macro expanding to ErrorException(msg, __LINE__, __FILE__) being a class. + */ + +namespace LinBox { /* Preconditions,Error,Failure,NotImplementedYet */ + /*! A precondition failed. + * @ingroup util + * The \c throw mechanism is usually used here as in + \code + if (!check) + throw(PreconditionFailed(__func__,__LINE__,"this check just failed"); + \endcode + * The parameters of the constructor help debugging. + */ + class PreconditionFailed { //: public LinboxError BB: otherwise, error.h:39 segfaults + static std::ostream* _errorStream; + + public: + /*! @internal + * A precondtion failed. + * @param function usually \c __func__, the function that threw the error + * @param line usually \c __LINE__, the line where it happened + * @param check a string telling what failed. + */ + PreconditionFailed(const char* function, int line, const char* check) + { + if (_errorStream == (std::ostream*)0) _errorStream = &std::cerr; + + (*_errorStream) << std::endl << std::endl; + (*_errorStream) << "ERROR (" << function << ":" << line << "): "; + (*_errorStream) << "Precondition not met:" << check << std::endl; + } + + /*! @internal + * A precondtion failed. + * The parameter help debugging. This is not much different from the previous + * except we can digg faster in the file where the exception was triggered. + * @param function usually \c __func__, the function that threw the error + * @param file usually \c __FILE__, the file where this function is + * @param line usually \c __LINE__, the line where it happened + * @param check a string telling what failed. + */ + PreconditionFailed(const char* function, const char* file, int line, const char* check) + { + if (_errorStream == (std::ostream*)0) _errorStream = &std::cerr; + + (*_errorStream) << std::endl << std::endl; + (*_errorStream) << "ERROR (at " << function << " in " << file << ':' << line << "): " << std::endl; + (*_errorStream) << "Precondition not met:" << check << std::endl; + } + + static void setErrorStream(std::ostream& stream); + + /*! @internal overload the virtual print of LinboxError. + * @param o output stream + */ + std::ostream& print(std::ostream& o) const + { + if (std::ostringstream* str = dynamic_cast(_errorStream)) + return o << str->str(); + else + throw LinboxError("LinBox ERROR: PreconditionFailed exception is not initialized correctly"); + } + }; + + /*! @internal A function is "not implemented yet(tm)". + * where, why ? + */ + class NotImplementedYet { + protected: + static std::ostream* _errorStream; + + public: + /*! @internal + * A precondtion failed. + * The parameter help debugging. This is not much different from the previous + * except we can digg faster in the file where the exception was triggered. + * @param function usually \c __func__, the function that threw the error + * @param file usually \c __FILE__, the file where this function is + * @param line usually \c __LINE__, the line where it happened + * @param why by default, lazy people don't provide an explanation. + */ + NotImplementedYet() {} + + NotImplementedYet(const std::string& why) + : NotImplementedYet(why.c_str()) + { + } + + NotImplementedYet(const char* why) + { + if (_errorStream == (std::ostream*)0) _errorStream = &std::cerr; + + (*_errorStream) << std::endl << std::endl; + (*_errorStream) << "*** ERROR ***" << std::endl; + (*_errorStream) << " This function is not implemented yet "; + (*_errorStream) << " (" << why << ")" << std::endl; + } + + NotImplementedYet(const char* function, const char* file, int line, const char* why = "\0") + { + if (_errorStream == (std::ostream*)0) _errorStream = &std::cerr; + + (*_errorStream) << std::endl << std::endl; + (*_errorStream) << " *** ERROR *** (at " << function << " in " << file << ':' << line << "): " << std::endl; + (*_errorStream) << " This function is not implemented yet"; + if (why) + (*_errorStream) << " (" << why << ")" << std::endl; + else + (*_errorStream) << "." << std::endl; + } + }; + + /*! @internal Something went wrong. + * what ? + */ + class LinBoxFailure : public NotImplementedYet { + public: + /*! @internal + * LinBox failed. + * The parameter help debugging/explaining. + * @param function usually \c __func__, the function that threw the error + * @param file usually \c __FILE__, the file where this function is + * @param line usually \c __LINE__, the line where it happened + * @param what what happened ? should not be NULL... + */ + LinBoxFailure(const char* function, const char* file = "\0", int line = -1, const char* what = "\0") + { + if (_errorStream == (std::ostream*)0) _errorStream = &std::cerr; + + (*_errorStream) << std::endl << std::endl; + (*_errorStream) << "ERROR (at " << function << " in " << file << ':' << line << "): " << std::endl; + (*_errorStream) << " failure : "; + if (what) + (*_errorStream) << what << "." << std::endl; + else + (*_errorStream) << "no explanation." << std::endl; + } + }; + + /*! @internal Something is wrong. + * what ? + */ + class LinBoxError : public NotImplementedYet { + public: + LinBoxError(const std::string& what, const char* function = "\0", const char* file = "\0", int line = -1) + : LinBoxError(what.c_str(), function, file, line) + { + } + + /*! @internal + * User failed. + * The parameter help debugging/explaining. + * @param function usually \c __func__, the function that threw the error + * @param file usually \c __FILE__, the file where this function is + * @param line usually \c __LINE__, the line where it happened + * @param what what happened ? should not be NULL... + */ + LinBoxError(const char* what, const char* function = "\0", const char* file = "\0", int line = -1) + { + if (_errorStream == (std::ostream*)0) _errorStream = &std::cerr; + + (*_errorStream) << std::endl << std::endl; + (*_errorStream) << " *** ERROR *** : " << what << std::endl; + if (function) { + (*_errorStream) << "(at " << function; + if (file) { + (*_errorStream) << " in " << file; + if (line >= 0) (*_errorStream) << ':' << line; + (*_errorStream) << ")"; + } + } + else if (file) { // extremely unlikely... + (*_errorStream) << "(in " << file; + if (line >= 0) (*_errorStream) << ':' << line; + (*_errorStream) << ")"; + } + (*_errorStream) << std::endl; + } + }; +} + namespace LinBox { // ------------------------------- LinboxError @@ -72,25 +268,12 @@ namespace LinBox { : LinboxError(msg){}; }; - class LinboxMathDivZero : public LinboxMathError { - public: - LinboxMathDivZero(const char* msg) - : LinboxMathError(msg){}; - }; - class LinboxMathInconsistentSystem : public LinboxMathError { public: LinboxMathInconsistentSystem(const char* msg) : LinboxMathError(msg){}; }; - // -- Exception thrown in input of data structure - class LinboxBadFormat : public LinboxError { - public: - LinboxBadFormat(const char* msg) - : LinboxError(msg){}; - }; - // -- Exception thrown when probabilistic solve fails class SolveFailed : public LinboxError { public: @@ -119,11 +302,18 @@ namespace LinBox { }; } +/** Exception class for invalid matrix input + */ +namespace Exceptions { + class InvalidMatrixInput { + }; +} + #ifdef LinBoxSrcOnly // for all-source compilation #include "linbox/util/error.C" #endif -#endif // __LINBOX_util_error_H +#endif // Local Variables: // mode: C++ diff --git a/linbox/vector/light_container.h b/linbox/vector/light_container.h index 89a80e5dc..09e5e73c8 100644 --- a/linbox/vector/light_container.h +++ b/linbox/vector/light_container.h @@ -52,15 +52,15 @@ namespace LinBox LightContainer() : allocated(2), _container(new Elem[allocated]), _finish(_container) { - ENSURE( (allocated == 2) && (size() == 0) ); + ASSERT( (allocated == 2) && (size() == 0) ); } LightContainer(size_t s) : allocated(s), _container(new Elem[s]), _finish(_container+s) { - ENSURE( (allocated == s) && (size() == s) ); - ENSURE( allocated >= size() ); + ASSERT( (allocated == s) && (size() == s) ); + ASSERT( allocated >= size() ); } @@ -87,7 +87,7 @@ namespace LinBox { STATE( size_t oldsize = size() ); reallocate(s, size() ); - ENSURE( (allocated >= s) && (size() == oldsize) && ( allocated >= size() ) ); + ASSERT( (allocated >= s) && (size() == oldsize) && ( allocated >= size() ) ); } size_t size() const @@ -110,14 +110,14 @@ namespace LinBox void clear() { _finish = _container; - ENSURE( (size() == 0) ); + ASSERT( (size() == 0) ); } void resize(size_t s) { if (s>allocated) reallocate( s+(s>>1), s ); else _finish = _container + s; - ENSURE( allocated >= size() ); + ASSERT( allocated >= size() ); } iterator begin() { return _container; } iterator end() { return _finish; } @@ -134,16 +134,16 @@ namespace LinBox if (size() == allocated) reserve(allocated+(allocated>>1)); *(_finish) = c; ++_finish; - ENSURE( size() == (oldsize+1) ); - ENSURE( allocated >= size() ); + ASSERT( size() == (oldsize+1) ); + ASSERT( allocated >= size() ); } void pop_back() { STATE( size_t oldsize = size() ); REQUIRE( oldsize >= 1 ); --_finish; - ENSURE( size() == (oldsize-1) ); - ENSURE( allocated >= size() ); + ASSERT( size() == (oldsize-1) ); + ASSERT( allocated >= size() ); } ~LightContainer() { delete[] _container; } @@ -165,8 +165,8 @@ namespace LinBox else newpos = insertwithrealloc(pos,c); } - ENSURE( size() == oldsize+1 ); - ENSURE( allocated >= size() ); + ASSERT( size() == oldsize+1 ); + ASSERT( allocated >= size() ); return newpos; } @@ -182,7 +182,7 @@ namespace LinBox for(const_iterator iter=Beg; iter != End; ++iter) insert(pos, *iter); } - ENSURE( allocated >= size() ); + ASSERT( allocated >= size() ); return pos; } @@ -200,9 +200,9 @@ namespace LinBox *(pos)=*(ppos); erase(ppos); } - ENSURE( size() == oldsize-1 ); - ENSURE( allocated >= size() ); - ENSURE( _finish >= _container ); + ASSERT( size() == oldsize-1 ); + ASSERT( allocated >= size() ); + ASSERT( _finish >= _container ); return pos; } @@ -223,9 +223,9 @@ namespace LinBox *(nf) = *(nl); erase(nf,nl); } - ENSURE( size() == oldsize-lmf ); - ENSURE( allocated >= size() ); - ENSURE( _finish >= _container ); + ASSERT( size() == oldsize-lmf ); + ASSERT( allocated >= size() ); + ASSERT( _finish >= _container ); return first; } @@ -270,7 +270,7 @@ namespace LinBox allocated = s; } _finish = _container + endc; - ENSURE( allocated >= size() ); + ASSERT( allocated >= size() ); } iterator insertwithspace(iterator pos, const Elem& c) @@ -287,9 +287,9 @@ namespace LinBox insertwithspace(pos+1, *(pos)); *(pos) = c; } - ENSURE( size() == oldsize+1 ); - ENSURE( allocated >= size() ); - ENSURE( allocated == oldalloc ); + ASSERT( size() == oldsize+1 ); + ASSERT( allocated >= size() ); + ASSERT( allocated == oldalloc ); return pos; } @@ -311,7 +311,7 @@ namespace LinBox delete [] _container; _container = futur; _finish = _container + (++olds); - ENSURE( allocated >= size() ); + ASSERT( allocated >= size() ); return newpos; } From 19219764bd94ca7dda7ef0d544fd1b5e1cc1fe4a Mon Sep 17 00:00:00 2001 From: Alexis Breust Date: Thu, 9 May 2019 09:30:07 +0200 Subject: [PATCH 2/2] Reverted some error cleanup changes --- interfaces/driver/lb-utilities.h | 3 +- interfaces/maple/lb-maple-utilities.h | 2 - .../smith-form-sparseelim-poweroftwo.h | 18 ++-- linbox/matrix/densematrix/blas-matrix.h | 3 +- linbox/util/contracts.h | 84 +++++++++++++++++++ linbox/vector/light_container.h | 48 +++++------ 6 files changed, 120 insertions(+), 38 deletions(-) create mode 100644 linbox/util/contracts.h diff --git a/interfaces/driver/lb-utilities.h b/interfaces/driver/lb-utilities.h index e0127c7e0..c4d215929 100644 --- a/interfaces/driver/lb-utilities.h +++ b/interfaces/driver/lb-utilities.h @@ -36,8 +36,7 @@ /************************************** * definition of LinBox's exceptions * **************************************/ -// @fixme CONSIDER MERGING IN error.h -typedef LinBox::LinboxError lb_runtime_error; +typedef LinBox::Error lb_runtime_error; diff --git a/interfaces/maple/lb-maple-utilities.h b/interfaces/maple/lb-maple-utilities.h index 942bb451d..8ac04bc44 100644 --- a/interfaces/maple/lb-maple-utilities.h +++ b/interfaces/maple/lb-maple-utilities.h @@ -67,8 +67,6 @@ extern "C" { /********************************* * Raising LinBox error in Maple * *********************************/ - // @fixme CONSIDER merging in error.h - // We could print an arbitrary object on error static void lbRaiseError(MKernelVector kv, lb_runtime_error &t){ std::ostringstream out; out< psizes; for(p=k; p( (long)LigneA[(size_t)p].size(), (long)p) ); @@ -441,8 +441,8 @@ namespace LinBox TWOK >>= 1; TWOKMONE >>=1; - ASSERT( TWOK == (UInt_t(1U) << EXPONENT) ); - ASSERT( TWOKMONE == (TWOK - 1U) ); + ENSURE( TWOK == (UInt_t(1U) << EXPONENT) ); + ENSURE( TWOKMONE == (TWOK - 1U) ); ranks.push_back( indcol ); ++ind_pow; @@ -463,7 +463,7 @@ namespace LinBox if (c != -1) { // Pivot has been found REQUIRE( indcol > 0); - const size_t currentrank(indcol-1); + const size_t currentrank(indcol-1); if (c != (long)currentrank) { #ifdef LINBOX_pp_gauss_steps_OUT @@ -481,7 +481,7 @@ namespace LinBox for(size_t l=k + 1; (l < Ni) && (col_density[currentrank]); ++l) FaireElimination(EXPONENT, TWOK, TWOKMONE, LigneA[(size_t)l], LigneA[(size_t)k], invpiv, currentrank, c, col_density); } - + #ifdef LINBOX_pp_gauss_steps_OUT std::cerr << "step[" << k << "], pivot: " << c << std::endl; # ifdef LINBOX_pp_gauss_intermediate_OUT diff --git a/linbox/matrix/densematrix/blas-matrix.h b/linbox/matrix/densematrix/blas-matrix.h index 104923b82..0e7bc7ad8 100644 --- a/linbox/matrix/densematrix/blas-matrix.h +++ b/linbox/matrix/densematrix/blas-matrix.h @@ -449,7 +449,8 @@ namespace LinBox /*! @internal * Get read-only pointer to the matrix data. */ - pointer getPointer() const ; + pointer getPointer() ; + const_pointer getPointer() const ; const_pointer &getConstPointer() const ; diff --git a/linbox/util/contracts.h b/linbox/util/contracts.h new file mode 100644 index 000000000..e41e08535 --- /dev/null +++ b/linbox/util/contracts.h @@ -0,0 +1,84 @@ +/* Copyright (C) LinBox + * + * + * + * ========LICENCE======== + * This file is part of the library LinBox. + * + * LinBox is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * ========LICENCE======== + */ + +#ifndef __LINBOX_util_contracts_H +#define __LINBOX_util_contracts_H + +// Object class is the base class for all +// objects in the system. All classes inheriting from this class need +// to define a method IsValid. This method should perform a +// consistency check on the state of the object. Note that +// this method needs to be defined only when a debug build is made +#include +#include +#if 0 +class Object { +public: +#ifdef _DEBUG + virtual bool IsValid() const = 0; +#endif + +}; +#endif +#if _DEBUG == 2 + +// The debug mode also defines the following macros. Failure of any of these macros leads to +// program termination. The user is notified of the error condition with the right file name +// and line number. The actual failing operation is also printed using the stringizing operator # + +#define ASSERT(bool_expression) assert(bool_expression) +#define IS_VALID(obj) ASSERT((obj) != NULL && (obj)->IsValid()) +#define REQUIRE(bool_expression) ASSERT(bool_expression) +#define ENSURE(bool_expression) ASSERT(bool_expression) +#define STATE(expression) expression + +#elif _DEBUG == 1 + +#define ASSERT(bool_expression) assert(bool_expression) +#define IS_VALID(obj) ASSERT((obj) != NULL && (obj)->IsValid()) +#define REQUIRE(bool_expression) if( ! bool_expression ) throw InvalidOperationException(__FILE__,__LINE__); +#define ENSURE(bool_expression) ASSERT(bool_expression) +#define STATE(expression) expression + +#elif _DEBUG == 0 + +// When built in release mode, the _DEBUG flag would not be defined, thus there will be no overhead +// in the final release from these checks. + +#define ASSERT(ignore) ((void) 0) +#define IS_VALID(ignore) ((void) 0) +#define REQUIRE(ignore) ((void) 0) +#define ENSURE(ignore) ((void) 0) +#define STATE(ignore) ((void) 0) + +#endif + +#endif //__LINBOX_util_contracts_H + +// Local Variables: +// mode: C++ +// tab-width: 4 +// indent-tabs-mode: nil +// c-basic-offset: 4 +// End: +// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s diff --git a/linbox/vector/light_container.h b/linbox/vector/light_container.h index 09e5e73c8..89a80e5dc 100644 --- a/linbox/vector/light_container.h +++ b/linbox/vector/light_container.h @@ -52,15 +52,15 @@ namespace LinBox LightContainer() : allocated(2), _container(new Elem[allocated]), _finish(_container) { - ASSERT( (allocated == 2) && (size() == 0) ); + ENSURE( (allocated == 2) && (size() == 0) ); } LightContainer(size_t s) : allocated(s), _container(new Elem[s]), _finish(_container+s) { - ASSERT( (allocated == s) && (size() == s) ); - ASSERT( allocated >= size() ); + ENSURE( (allocated == s) && (size() == s) ); + ENSURE( allocated >= size() ); } @@ -87,7 +87,7 @@ namespace LinBox { STATE( size_t oldsize = size() ); reallocate(s, size() ); - ASSERT( (allocated >= s) && (size() == oldsize) && ( allocated >= size() ) ); + ENSURE( (allocated >= s) && (size() == oldsize) && ( allocated >= size() ) ); } size_t size() const @@ -110,14 +110,14 @@ namespace LinBox void clear() { _finish = _container; - ASSERT( (size() == 0) ); + ENSURE( (size() == 0) ); } void resize(size_t s) { if (s>allocated) reallocate( s+(s>>1), s ); else _finish = _container + s; - ASSERT( allocated >= size() ); + ENSURE( allocated >= size() ); } iterator begin() { return _container; } iterator end() { return _finish; } @@ -134,16 +134,16 @@ namespace LinBox if (size() == allocated) reserve(allocated+(allocated>>1)); *(_finish) = c; ++_finish; - ASSERT( size() == (oldsize+1) ); - ASSERT( allocated >= size() ); + ENSURE( size() == (oldsize+1) ); + ENSURE( allocated >= size() ); } void pop_back() { STATE( size_t oldsize = size() ); REQUIRE( oldsize >= 1 ); --_finish; - ASSERT( size() == (oldsize-1) ); - ASSERT( allocated >= size() ); + ENSURE( size() == (oldsize-1) ); + ENSURE( allocated >= size() ); } ~LightContainer() { delete[] _container; } @@ -165,8 +165,8 @@ namespace LinBox else newpos = insertwithrealloc(pos,c); } - ASSERT( size() == oldsize+1 ); - ASSERT( allocated >= size() ); + ENSURE( size() == oldsize+1 ); + ENSURE( allocated >= size() ); return newpos; } @@ -182,7 +182,7 @@ namespace LinBox for(const_iterator iter=Beg; iter != End; ++iter) insert(pos, *iter); } - ASSERT( allocated >= size() ); + ENSURE( allocated >= size() ); return pos; } @@ -200,9 +200,9 @@ namespace LinBox *(pos)=*(ppos); erase(ppos); } - ASSERT( size() == oldsize-1 ); - ASSERT( allocated >= size() ); - ASSERT( _finish >= _container ); + ENSURE( size() == oldsize-1 ); + ENSURE( allocated >= size() ); + ENSURE( _finish >= _container ); return pos; } @@ -223,9 +223,9 @@ namespace LinBox *(nf) = *(nl); erase(nf,nl); } - ASSERT( size() == oldsize-lmf ); - ASSERT( allocated >= size() ); - ASSERT( _finish >= _container ); + ENSURE( size() == oldsize-lmf ); + ENSURE( allocated >= size() ); + ENSURE( _finish >= _container ); return first; } @@ -270,7 +270,7 @@ namespace LinBox allocated = s; } _finish = _container + endc; - ASSERT( allocated >= size() ); + ENSURE( allocated >= size() ); } iterator insertwithspace(iterator pos, const Elem& c) @@ -287,9 +287,9 @@ namespace LinBox insertwithspace(pos+1, *(pos)); *(pos) = c; } - ASSERT( size() == oldsize+1 ); - ASSERT( allocated >= size() ); - ASSERT( allocated == oldalloc ); + ENSURE( size() == oldsize+1 ); + ENSURE( allocated >= size() ); + ENSURE( allocated == oldalloc ); return pos; } @@ -311,7 +311,7 @@ namespace LinBox delete [] _container; _container = futur; _finish = _container + (++olds); - ASSERT( allocated >= size() ); + ENSURE( allocated >= size() ); return newpos; }