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