]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/blob - src/debug.h
73ff1e95e292f81ccf1e2e6caaa03565c9e82044
[hercules2020/kcf.git] / src / debug.h
1 #ifndef DEBUG_H
2 #define DEBUG_H
3
4 #include <ios>
5 #include <iomanip>
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <opencv2/opencv.hpp>
9 #include "dynmem.hpp"
10 #include "complexmat.hpp"
11
12 #ifdef CUFFT
13 #include <cufft.h>
14 #endif
15
16
17 class IOSave
18 {
19     std::ios&           stream;
20     std::ios::fmtflags  flags;
21     std::streamsize     precision;
22     char                fill;
23 public:
24     IOSave( std::ios& userStream )
25         : stream( userStream )
26         , flags( userStream.flags() )
27         , precision( userStream.precision() )
28         , fill( userStream.fill() )
29     {
30     }
31     ~IOSave()
32     {
33         stream.flags( flags );
34         stream.precision( precision );
35         stream.fill( fill );
36     }
37 };
38
39 class DbgTracer {
40     int indentLvl = 0;
41
42   public:
43     bool debug = false;
44
45     std::string indent() { return std::string(indentLvl * 4, ' '); }
46
47     class FTrace {
48         DbgTracer &t;
49         const char *funcName;
50
51       public:
52         FTrace(DbgTracer &dt, const char *fn, const char *format, ...) : t(dt), funcName(fn)
53         {
54             if (!t.debug) return;
55             char *arg;
56             va_list vl;
57             va_start(vl, format);
58             if (-1 == vasprintf(&arg, format, vl))
59                 throw std::runtime_error("vasprintf error");
60             va_end(vl);
61
62             std::cerr << t.indent() << funcName << "(" << arg << ") {" << std::endl;
63             dt.indentLvl++;
64         }
65         ~FTrace()
66         {
67             if (!t.debug) return;
68             t.indentLvl--;
69             std::cerr << t.indent() << "}" << std::endl;
70         }
71     };
72
73     template <typename T>
74     void traceVal(const char *name, const T& obj, int line, bool always = false)
75     {
76         (void)line;
77         if (debug || always) {
78 #ifdef CUFFT
79             CudaSafeCall(cudaStreamSynchronize(cudaStreamPerThread));
80 #endif
81             std::cerr << indent() << name /*<< " @" << line */ << " " << print(obj) << std::endl;
82         }
83     }
84
85     template <typename T> struct Printer {
86         const T &obj;
87         Printer(const T &_obj) : obj(_obj) {}
88     };
89
90     template <typename T> Printer<T> print(const T& obj) { return Printer<T>(obj); }
91     Printer<cv::Mat> print(const MatScales& obj) { return Printer<cv::Mat>(obj); }
92     Printer<cv::Mat> print(const MatFeats& obj) { return Printer<cv::Mat>(obj); }
93     Printer<cv::Mat> print(const MatScaleFeats& obj) { return Printer<cv::Mat>(obj); }
94 };
95
96 template <typename T>
97 std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer<T> &p)
98 {
99     os << p.obj;
100     return os;
101 }
102
103 #if CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION < 3
104 static inline std::ostream &operator<<(std::ostream &out, const cv::MatSize &msize)
105 {
106     int i, dims = msize.p[-1];
107     for (i = 0; i < dims; i++) {
108         out << msize.p[i];
109         if (i < dims - 1)
110             out << " x ";
111     }
112     return out;
113 }
114 #endif
115
116 std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer<cv::Mat> &p);
117
118 #if defined(CUFFT)
119 static inline std::ostream &operator<<(std::ostream &os, const cufftComplex &p)
120 {
121     (void)p; // TODO
122     return os;
123 }
124 #endif
125
126 std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer<ComplexMat> &p);
127
128 extern DbgTracer __dbgTracer;
129
130 #define TRACE(...) const DbgTracer::FTrace __tracer(__dbgTracer, __PRETTY_FUNCTION__, ##__VA_ARGS__)
131
132 #define DEBUG_PRINT(obj) __dbgTracer.traceVal(#obj, (obj), __LINE__)
133 #define DEBUG_PRINTM(obj) DEBUG_PRINT(obj)
134 #define PRINT(obj) __dbgTracer.traceVal(#obj, (obj), __LINE__, true)
135
136 #endif // DEBUG_H