Ariles
trace.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2017-2020 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @brief
9 */
10 
11 #pragma once
12 
13 
14 #ifndef H_CPPUT_TRACE
15 # define H_CPPUT_TRACE
16 
17 
18 # ifdef CPPUT_TRACE_ENABLE
19 # include <iostream>
20 # include <libgen.h>
21 # include <typeinfo>
22 # include <cxxabi.h>
23 
24 # ifndef CPPUT_TRACE_FUNCTION_NAME
25 // __PRETTY_FUNCTION__
26 # define CPPUT_TRACE_FUNCTION_NAME __func__
27 # endif
28 
29 namespace cpput
30 {
31  namespace trace
32  {
33  class Tracer
34  {
35  public:
36  std::string tabulation_;
37  const std::string function_name_;
38  const std::string file_;
39  const int line_number_;
40 
41  protected:
42  std::size_t getDepth(const bool increment = true)
43  {
44  static std::size_t depth = 0;
45  if (true == increment)
46  {
47  return (depth++);
48  }
49  else
50  {
51  return (--depth);
52  }
53  }
54 
55  template <class t_First, class... t_Args>
56  void outputFirst(t_First &&first, t_Args &&...args)
57  {
58  std::cout << first;
59  outputFirst(std::forward<t_Args>(args)...);
60  }
61 
62  template <class t_Last>
63  void outputFirst(t_Last &&last)
64  {
65  std::cout << last << std::endl;
66  }
67 
68 
69  public:
70  Tracer(const std::string &function_name, const std::string &file, const int line_number)
71  : function_name_(function_name), file_(file), line_number_(line_number)
72  {
73  tabulation_.assign(getDepth(true), ' ');
74 
75  std::cout << tabulation_ //
76  << ">>> Entering function: " << function_name_ //
77  << " | File: " << file_ //
78  << " | Line: " << line_number_ << std::endl;
79  }
80 
81  ~Tracer()
82  {
83  std::cout << tabulation_ //
84  << "<<< Leaving function: " << function_name_ //
85  << " | File: " << file_ //
86  << " | Line: " << line_number_ << std::endl;
87  getDepth(false);
88  }
89 
90 
91  template <class... t_Args>
92  void output(t_Args &&...args)
93  {
94  std::cout << tabulation_;
95  outputFirst(std::forward<t_Args>(args)...);
96  }
97 
98  std::string demangle(const char *name) const
99  {
100  std::size_t len = 0;
101  int status = 0;
102 
103  char *demangled_name = abi::__cxa_demangle(name, NULL, &len, &status);
104 
105  if (demangled_name != NULL)
106  {
107  const std::string result(demangled_name);
108  free(demangled_name);
109  return (result);
110  }
111  else
112  {
113  return ("");
114  }
115  }
116  };
117  } // namespace trace
118 } // namespace cpput
119 
120 # define CPPUT_TRACE_FUNCTION \
121  char trace_path[] = __FILE__; \
122  cpput::trace::Tracer tracer(CPPUT_TRACE_FUNCTION_NAME, basename(trace_path), __LINE__);
123 # define CPPUT_TRACE_VALUE(variable) tracer.output("Value: ", #variable, " = ", variable);
124 # define CPPUT_TRACE_TYPE(variable) tracer.output("Type: ", tracer.demangle(typeid(variable).name()));
125 # else
126 # define CPPUT_TRACE_FUNCTION
127 # define CPPUT_TRACE_VALUE(value)
128 # define CPPUT_TRACE_TYPE(type)
129 # endif
130 
131 #endif
Definition: concat.h:17