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