zpp
Zephyr C++20 Framework
fmt.hpp
Go to the documentation of this file.
1 
7 #ifndef ZPP_INCLUDE_ZPP_FMT_HPP
8 #define ZPP_INCLUDE_ZPP_FMT_HPP
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/sys/__assert.h>
12 
13 #include <cstddef>
14 #include <chrono>
15 #include <utility>
16 
17 namespace zpp {
18 
19 namespace internal {
20 
21 inline void print_arg() noexcept { }
22 inline void print_arg(bool v) noexcept { printk("%d", (int)v); }
23 inline void print_arg(float v) noexcept { printk("%f", v); }
24 inline void print_arg(double v) noexcept { printk("%g", v); }
25 inline void print_arg(char v) noexcept { printk("%c", v); }
26 inline void print_arg(const char* v) noexcept { printk("%s", v); }
27 inline void print_arg(const void* v) noexcept { printk("%p", v); }
28 inline void print_arg(uint8_t v) noexcept { printk("%d", (uint32_t)v); }
29 inline void print_arg(int8_t v) noexcept { printk("%d", (int32_t)v); }
30 inline void print_arg(uint16_t v) noexcept { printk("%d", (uint32_t)v); }
31 inline void print_arg(int16_t v) noexcept { printk("%d", (int32_t)v); }
32 inline void print_arg(uint32_t v) noexcept { printk("%d", v); }
33 inline void print_arg(int32_t v) noexcept { printk("%d", v); }
34 inline void print_arg(uint64_t v) noexcept { printk("%lld", v); }
35 inline void print_arg(int64_t v) noexcept { printk("%lld", v); }
36 
37 template<class T_Rep, class T_Period>
38 inline void print_arg(std::chrono::duration<T_Rep, T_Period> v)
39 {
40  using namespace std::chrono;
41 
42  auto s = duration_cast<seconds>(v);
43  v -= duration_cast<decltype(v)>(s);
44  auto ms = duration_cast<milliseconds>(v);
45  v -= duration_cast<decltype(v)>(ms);
46  auto us = duration_cast<microseconds>(v);
47  v -= duration_cast<decltype(v)>(us);
48  auto ns = duration_cast<nanoseconds>(v);
49 
50  printk("%d.%03d%03d%03ds",
51  (int)s.count(), (int)ms.count(),
52  (int)us.count(), (int)ns.count());
53 }
54 
55 template<class T_Clock>
56 inline void print_arg(std::chrono::time_point<T_Clock> v)
57 {
58  print_arg(v.time_since_epoch());
59 }
60 
61 inline void print_helper(const char* fmt) noexcept
62 {
63  printk("%s", fmt);
64 }
65 
66 template<class T_FirstArg, class ...T_Args>
67 inline void print_helper(const char* fmt, T_FirstArg&& first, T_Args&&... args) noexcept
68 {
69  enum class state { normal, format, open_brace, close_brace, done };
70 
71  state s = state::normal;
72  size_t n = 0;
73 
74  while (true) {
75  char c = fmt[n++];
76 
77  if (c == '\0') {
78  return;
79  }
80 
81  switch (s) {
82  case state::normal:
83  switch (c) {
84  case '{':
85  s = state::open_brace;
86  break;
87  case '}':
88  s = state::close_brace;
89  break;
90  default:
91  printk("%c", c);
92  break;
93  }
94  break;
95 
96  case state::open_brace:
97  switch(c) {
98  case '{':
99  s = state::normal;
100  printk("{");
101  break;
102 
103  case '}':
104  s = state::done;
105  break;
106 
107  default:
108  s = state::format;
109  break;
110  }
111  break;
112 
113  case state::close_brace:
114  if (c == '}') {
115  printk("}");
116  }
117  s = state::normal;
118  break;
119 
120  case state::format:
121  switch (c) {
122  case '}':
123  s = state::done;
124  break;
125  default:
126  break;
127  }
128  break;
129 
130  case state::done:
131  break;
132 
133  }
134 
135  if (s == state::done) {
136  break;
137  }
138  }
139 
140  print_arg(std::forward<T_FirstArg>(first));
141  print_helper(&(fmt[n]), std::forward<T_Args>(args)...);
142 }
143 
144 } // namespace internal
145 
156 template<class ...T_Args>
157 inline void print(const char* fmt, T_Args&&... args) noexcept
158 {
159  internal::print_helper(fmt, std::forward<T_Args>(args)...);
160 }
161 
162 } // namespace zpp
163 
164 #endif // ZPP_INCLUDE_ZPP_FMT_HPP
void print_arg() noexcept
Definition: fmt.hpp:21
void print_helper(const char *fmt) noexcept
Definition: fmt.hpp:61
void print(const char *fmt, T_Args &&... args) noexcept
simple typesafe print function
Definition: fmt.hpp:157