ape  0.5.0
Audio Programming Environment
trace.h
Go to the documentation of this file.
1 #ifndef CPPAPE_TRACE_H
2 #define CPPAPE_TRACE_H
3 
4 #ifndef CPPAPE_TRACING_ENABLED
5 
11 #define TRC(...) __VA_ARGS__
12 
13 #else
14  #include <map>
15  #include <vector>
16  #include <algorithm>
17  #include <complex>
18 
19  namespace ape::Tracing
20  {
21 
22  using Twine = std::pair<const char*, const char*>;
23 
24  template<typename T>
25  struct Trace
26  {
27  void reset() noexcept { index = 0; }
28  void enqueue(T thing)
29  {
30  if (index < data.size())
31  data[index++] = thing;
32  else
33  {
34  data.resize(std::max<std::size_t>(1, data.size() * 2));
35  data[index++] = thing;
36  }
37 
38  }
39  std::size_t index;
40  std::vector<T> data;
41  };
42 
43  class Tracer
44  {
45 
46  public:
47 
48  Trace<float>& getTrace(Twine id) noexcept
49  {
50  return traces[id];
51  }
52 
53  void reset() noexcept
54  {
55  for (auto& pair : traces)
56  pair.second.reset();
57  }
58 
59  const std::map<Twine, Trace<float>>& getTraces() const noexcept { return traces; }
60 
61  private:
62  std::map<Twine, Trace<float>> traces;
63  };
64 
65  template<typename Input, typename = std::true_type>
66  struct TraceTraits;
67 
68  template<typename Input>
69  struct TraceTraits<Input, typename std::is_arithmetic<Input>::type>
70  {
71  static constexpr std::size_t numElements() noexcept { return 1; }
72  static constexpr const char* nameForElement(std::size_t index) noexcept { return nullptr; }
73  static constexpr float valueForElement(const Input& r, std::size_t index) noexcept { return static_cast<float>(r); }
74  };
75 
76  template<typename InnerType>
77  struct TraceTraits<std::complex<InnerType>>
78  {
79  static constexpr std::size_t numElements() noexcept { return 2; }
80  static constexpr const char* nameForElement(std::size_t index) noexcept { return index == 0 ? "real" : "imag"; }
81  static constexpr float valueForElement(const std::complex<InnerType>& r, std::size_t index) noexcept { return index == 0 ? r.real() : r.imag(); }
82  };
83 
84  template<typename Result>
85  inline typename std::enable_if<TraceTraits<Result>::numElements() == 1>::type
86  TraceData(std::size_t index, const char* identifier, const Result& result)
87  {
88  extern Tracer GlobalTracer;
89 
90  GlobalTracer
91  .getTrace(std::make_pair(identifier, nullptr))
92  .enqueue(TraceTraits<Result>::valueForElement(result, 0));
93  }
94 
95  template<typename Result>
96  inline typename std::enable_if<TraceTraits<Result>::numElements() != 1>::type
97  TraceData(std::size_t index, const char* identifier, const Result& result)
98  {
99  extern Tracer GlobalTracer;
100 
101  for (std::size_t i = 0; i < TraceTraits<Result>::numElements(); ++i)
102  {
103  GlobalTracer
104  .getTrace(std::make_pair(identifier, TraceTraits<Result>::nameForElement(i)))
105  .enqueue(TraceTraits<Result>::valueForElement(result, i));
106  }
107  }
108 
109  }
110 
111 
112  #define TRC(...) ape::Tracing::TraceData(0, #__VA_ARGS__, (__VA_ARGS__))
113 
114 #endif
115 
116 #endif