jubilant-funicular
format.h
1 #ifndef NTA_FORMATTER_H_INCLUDED
2 #define NTA_FORMATTER_H_INCLUDED
3 
4 #include <string>
5 #include <sstream>
6 #include <iostream>
7 
8 #include "nta/MyEngine.h"
9 #include "nta/type_traits.h"
10 
11 namespace nta {
12  namespace utils {
18  template<typename... Args>
19  std::string format(const std::string& fmt, Args&&... args);
20 
22  template<typename T, typename Enable = void>
23  struct Formatter {};
25  template<typename T>
26  struct Formatter<T, typename std::enable_if_t<can_cout<T>>> {
27  std::string operator()(const T& arg) {
28  std::ostringstream os;
29  os<<arg;
30  return os.str();
31  }
32  };
33  // Should I not have these here in jubliant-funicular?
34  template<>
35  struct Formatter<bool> {
36  std::string operator()(const bool& arg) {
37  return arg ? "true" : "false";
38  }
39  };
40  template<>
41  struct Formatter<glm::vec2> {
42  std::string operator()(const glm::vec2& arg) {
43  return format("({}, {})", arg.x, arg.y);
44  }
45  };
46  template<>
47  struct Formatter<glm::vec3> {
48  std::string operator()(const glm::vec3& arg) {
49  return format("({}, {}, {})", arg.x, arg.y, arg.z);
50  }
51  };
52  template<>
53  struct Formatter<glm::vec4> {
54  std::string operator()(const glm::vec4& arg) {
55  return format("({}, {}, {}, {})", arg.x, arg.y, arg.z, arg.w);
56  }
57  };
58  template<>
59  struct Formatter<glm::ivec2> {
60  std::string operator()(const glm::ivec2& arg) {
61  return format("({}, {})", arg.x, arg.y);
62  }
63  };
64  template<>
65  struct Formatter<glm::ivec3> {
66  std::string operator()(const glm::ivec3& arg) {
67  return format("({}, {}, {})", arg.x, arg.y, arg.z);
68  }
69  };
70  template<>
71  struct Formatter<glm::ivec4> {
72  std::string operator()(const glm::ivec4& arg) {
73  return format("({}, {}, {}, {})", arg.x, arg.y, arg.z, arg.w);
74  }
75  };
76 
77  extern std::string format_helper(std::string& sofar, const std::string& fmt);
78  template<typename T, typename... Args>
79  std::string format_helper(std::string& sofar, const std::string& fmt,
80  const T& arg0, Args&&... args) {
81  auto end = fmt.find("{}", 0);
82  auto arg = end == std::string::npos ? "" : Formatter<T>()(arg0);
83  auto rest = end == std::string::npos ? "" : fmt.substr(end+2);
84  sofar += fmt.substr(0, end) + arg;
85  return format_helper(sofar, rest, std::forward<Args>(args)...);
86  }
87  template<typename... Args>
88  std::string format(const std::string& fmt, Args&&... args) {
89  std::string ret;
90  return format_helper(ret, fmt, std::forward<Args>(args)...);
91  }
92  template<typename... Args>
93  std::ostream& print(const std::string& fmt, Args&&... args) {
94  return std::cout<<format(fmt, std::forward<Args>(args)...);
95  }
96  template<typename... Args>
97  std::ostream& println(const std::string& fmt, Args&&... args) {
98  return std::cout<<format(fmt, std::forward<Args>(args)...)<<std::endl;
99  }
100  }
101 }
102 
103 #endif // NTA_FORMATTER_H_INCLUDED
nta::utils::Formatter
Specialize this struct to use custom types with format.
Definition: format.h:23
nta::utils::format
std::string format(const std::string &fmt, Args &&... args)
Definition: format.h:88
nta
Definition: Animation2D.h:6