1 /* utils/debug.h 2 * 3 * Copyright (C) 2011 Fflas-ffpack 4 * Modified by BB, from LinBox 5 * ========LICENCE======== 6 * This file is part of the library FFLAS-FFPACK. 7 * 8 * FFLAS-FFPACK is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * ========LICENCE======== 22 * 23 */ 24 25 /*! @file utils/debug.h 26 * @ingroup util 27 * Various utilities for debugging. 28 * @todo we should put vector printing elsewhere. 29 */ 30 31 #ifndef __FFLASFFPACK_util_debug_H 32 #define __FFLASFFPACK_util_debug_H 33 #include <fflas-ffpack/fflas-ffpack-config.h> 34 35 #include <iostream> 36 #include <sstream> 37 #include <cmath> 38 39 #include "fflas-ffpack/fflas-ffpack-config.h" 40 41 42 #ifdef __FFLASFFPACK_HAVE_STDINT_H 43 #ifndef __STDC_LIMIT_MACROS 44 #define __STDC_LIMIT_MACROS 45 #endif 46 #include <stdint.h> 47 #include <limits> 48 49 // If somebody nasty previously included <stdint.h> without __STDC_LIMIT_MACROS :) 50 #ifndef INT64_MAX 51 #define INT64_MAX std::numeric_limits<int64_t>::max() 52 #endif 53 54 #ifndef UINT64_MAX 55 #define UINT64_MAX std::numeric_limits<uint64_t>::max() 56 #endif 57 58 #ifndef INT32_MAX 59 #define INT32_MAX std::numeric_limits<int32_t>::max() 60 #endif 61 62 #ifndef UINT32_MAX 63 #define UINT32_MAX std::numeric_limits<uint32_t>::max() 64 #endif 65 66 #ifndef INT16_MAX 67 #define INT16_MAX std::numeric_limits<int16_t>::max() 68 #endif 69 70 #ifndef UINT16_MAX 71 #define UINT16_MAX std::numeric_limits<uint16_t>::max() 72 #endif 73 74 #ifndef INT8_MAX 75 #define INT8_MAX std::numeric_limits<int8_t>::max() 76 #endif 77 78 #ifndef UINT8_MAX 79 #define UINT8_MAX std::numeric_limits<uint8_t>::max() 80 #endif 81 82 #else 83 #error "you need intXX_t types" 84 #endif 85 86 #ifndef NDEBUG 87 #include <stdexcept> 88 #define FFLASFFPACK_check(check) \ 89 if (!(check)) {\ 90 FFPACK::failure()(__func__, __FILE__, __LINE__, #check); \ 91 throw std::runtime_error(#check); \ 92 } 93 #define FFLASFFPACK_abort(msg) \ 94 {\ 95 FFPACK::failure()(__func__, __FILE__, __LINE__, msg); \ 96 throw std::runtime_error(msg); \ 97 } 98 #else 99 #define FFLASFFPACK_check(check) ((void) 0) 100 #define FFLASFFPACK_abort(mst) ((void) 0) 101 #endif 102 103 104 105 namespace FFPACK { 106 107 /*! A precondtion failed. 108 * @ingroup util 109 * The \c throw mechanism is usually used here as in 110 \code 111 if (!check) 112 failure()(__func__,__LINE__,"this check just failed"); 113 \endcode 114 * The parameters of the constructor help debugging. 115 */ 116 class Failure { 117 protected: 118 std::ostream *_errorStream; 119 120 public: 121 Failure()122 Failure() {} 123 124 /*! @internal 125 * A precondtion failed. 126 * @param function usually \c __func__, the function that threw the error 127 * @param line usually \c __LINE__, the line where it happened 128 * @param check a string telling what failed. 129 */ operator()130 void operator() (const char *function, int line, const char *check) 131 { 132 if (_errorStream == (std::ostream *) 0) 133 _errorStream = &std::cerr; 134 135 (*_errorStream) << std::endl << std::endl; 136 (*_errorStream) << "ERROR (" << function << ":" << line << "): "; 137 (*_errorStream) << "Precondition not met:" << check << std::endl; 138 } 139 140 /*! @internal 141 * A precondtion failed. 142 * The parameter help debugging. This is not much different from the previous 143 * except we can digg faster in the file where the exception was triggered. 144 * @param function usually \c __func__, the function that threw the error 145 * @param file usually \c __FILE__, the file where this function is 146 * @param line usually \c __LINE__, the line where it happened 147 * @param check a string telling what failed. 148 */ operator()149 void operator() (const char* function, const char *file, int line, const char *check) 150 { 151 if (_errorStream == (std::ostream *) 0) 152 _errorStream = &std::cerr; 153 154 (*_errorStream) << std::endl << std::endl; 155 (*_errorStream) << "ERROR (at " << function << " in " << file << ':' << line << "): " << std::endl; 156 (*_errorStream) << "Precondition not met:" << check << std::endl; 157 } 158 159 void setErrorStream (std::ostream &stream); 160 161 /*! @internal overload the virtual print of LinboxError. 162 * @param o output stream 163 */ print(std::ostream & o)164 std::ostream &print (std::ostream &o) const 165 { 166 if (std::ostringstream * str = dynamic_cast<std::ostringstream*>(_errorStream)) 167 return o << str->str() ; 168 else 169 throw "FFLAS-FFPACK ERROR: Failure exception is not initialized correctly"; 170 } 171 }; 172 173 failure()174 inline Failure& failure() { 175 static Failure failure_internal; 176 return failure_internal; 177 } 178 179 template<class T> isOdd(const T & a)180 inline bool isOdd (const T & a) { 181 return (a%2); 182 } 183 isOdd(const float & a)184 inline bool isOdd(const float &a) { 185 return (bool)(int)fmodf(a,2.f); 186 } 187 isOdd(const double & a)188 inline bool isOdd(const double &a) { 189 return (bool)(int)fmod(a,2.); 190 } 191 192 } // FFPACK 193 194 #endif // __FFLASFFPACK_util_debug_H 195 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 196 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s 197