Simulant  21.12-574
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
formatter.h
1 #pragma once
2 
3 #include <cstdint>
4 #include <string>
5 #include <sstream>
6 #include <iomanip>
7 
8 #include "../compat.h"
9 
10 namespace smlt {
11 
12 class Formatter {
13 public:
14  Formatter(const char* fmt):
15  fmt_(fmt) {}
16 
17  Formatter(const std::string& fmt):
18  fmt_(fmt) {}
19 
20  template<typename... Args>
21  std::string format(Args&& ...args) {
22  return _format(fmt_, 0, std::forward<Args>(args)...);
23  }
24 
25 private:
26  std::string _format(std::string str, int) {
27  return str;
28  }
29 
30  static bool is_int(char ch) {
31  return ch >= 48 && ch < 58;
32  }
33 
34  template<typename... Args>
35  std::string _format(const std::string& str, int c, int8_t&& v, Args&& ...args) {
36  return _format(str, c, (int16_t) v, std::forward<Args>(args)...);
37  }
38 
39  template<typename T, typename... Args>
40  std::string _format(const std::string& str, int c, T&& v, Args&& ...args) {
41  std::stringstream ss;
42  int max_token_size = 7;
43 
44  for(auto i = 0u; i < str.size(); ++i) {
45  if(str[i] == '{') {
46  std::string id, format;
47  std::string* t = &id;
48  uint32_t k = 0;
49  for(auto j = 1; j < max_token_size; ++j) {
50  k = i + j;
51 
52  if(k >= str.size() - 1) {
53  break;
54  }
55 
56  char ch = str[k];
57 
58  if(ch == '}') {
59  break;
60  } else if(ch == ':') {
61  t = &format;
62  } else {
63  if(!is_int(ch)) {
64  if(t == &id) {
65  // Id's only contain ints
66  break;
67  } else if(ch != '.') {
68  // Formatters can contain a .
69  break;
70  }
71  }
72 
73  *t += str[k];
74  }
75  }
76 
77  if(str[k] == '}') {
78  /* This was a placeholder within the size limit and
79  * with valid characters */
80  if(smlt::stoi(id) == c) {
81  /* OK we're dealing with this one */
82 
83  if(format.size() > 1 && format[0] == '.') {
84  auto prec = smlt::stoi(format.substr(1));
85  ss << std::setprecision(prec) << v;
86  } else {
87  ss << v;
88  }
89 
90  /* Skip past the placeholder */
91  i = k;
92  } else {
93  ss << str[i];
94  }
95  } else {
96  ss << str[i];
97  }
98  } else {
99  ss << str[i];
100  }
101  }
102 
103  return _format(ss.str(), c + 1, std::forward<Args>(args)...);
104  }
105 
106  std::string fmt_;
107 };
108 
109 }
110 
111 typedef smlt::Formatter _F;
112 
smlt
Definition: animation.cpp:25
smlt::Formatter
Definition: formatter.h:12