Otclient 1.0  14/8/2020
format.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #ifndef STDEXT_FORMAT_H
24 #define STDEXT_FORMAT_H
25 
26 #include "traits.h"
27 
28 #include <string>
29 #include <cstdio>
30 #include <cassert>
31 #include <tuple>
32 #include <iostream>
33 #include <sstream>
34 #include <iomanip>
35 
36 namespace stdext {
37 
38  template<class T> void print_ostream(std::ostringstream& stream, const T& last) { stream << last; }
39  template<class T, class... Args>
40  void print_ostream(std::ostringstream& stream, const T& first, const Args&... rest) { stream << "\t" << first; print_ostream(stream, rest...); }
41  template<class... T>
42 
43  // Utility for printing variables just like lua
44  void print(const T&... args) { std::ostringstream buf; print_ostream(buf, args...); std::cout << buf.str() << std::endl; }
45 
46  template<typename T>
47  typename std::enable_if<std::is_integral<T>::value ||
48  std::is_pointer<T>::value ||
49  std::is_floating_point<T>::value ||
50  std::is_enum<T>::value, T>::type sprintf_cast(const T& t) { return t; }
51  inline const char* sprintf_cast(const char* s) { return s; }
52  inline const char* sprintf_cast(const std::string& s) { return s.c_str(); }
53 
54  template<int N> struct expand_snprintf {
55  template<typename Tuple, typename... Args> static int call(char* s, size_t maxlen, const char* format, const Tuple& tuple, const Args&... args) {
56  return expand_snprintf<N - 1>::call(s, maxlen, format, tuple, sprintf_cast(std::get<N - 1>(tuple)), args...);
57  }
58  };
59  template<> struct expand_snprintf<0> {
60  template<typename Tuple, typename... Args> static int call(char* s, size_t maxlen, const char* format, const Tuple& /*tuple*/, const Args&... args) {
61 #ifdef _MSC_VER
62  return _snprintf(s, maxlen, format, args...);
63 #else
64  return snprintf(s, maxlen, format, args...);
65 #endif
66  }
67  };
68 
69  // Improved snprintf that accepts std::string and other types
70  template<typename... Args>
71  int snprintf(char* s, size_t maxlen, const char* format, const Args&... args) {
72  std::tuple<typename replace_extent<Args>::type...> tuple(args...);
73  return expand_snprintf<std::tuple_size<decltype(tuple)>::value>::call(s, maxlen, format, tuple);
74  }
75 
76  template<typename... Args>
77  inline int snprintf(char* s, size_t maxlen, const char* format) {
78  std::strncpy(s, format, maxlen);
79  s[maxlen - 1] = 0;
80  return strlen(s);
81  }
82 
83  template<typename... Args>
84  inline std::string format() { return std::string(); }
85 
86  template<typename... Args>
87  inline std::string format(const std::string& format) { return format; }
88 
89  // Format strings with the sprintf style, accepting std::string and string convertible types for %s
90  template<typename... Args>
91  std::string format(const std::string& format, const Args&... args) {
92  int n, size = 1024;
93  std::string str;
94  while (true) {
95  str.resize(size);
96  n = snprintf(&str[0], size, format.c_str(), args...);
97  assert(n != -1);
98  if (n < size) {
99  str.resize(n);
100  return str;
101  }
102  size *= 2;
103  }
104  }
105 
106 }
107 
108 #endif
stdext::sprintf_cast
std::enable_if< std::is_integral< T >::value||std::is_pointer< T >::value||std::is_floating_point< T >::value||std::is_enum< T >::value, T >::type sprintf_cast(const T &t)
Definition: format.h:50
stdext::expand_snprintf::call
static int call(char *s, size_t maxlen, const char *format, const Tuple &tuple, const Args &... args)
Definition: format.h:55
stdext::print_ostream
void print_ostream(std::ostringstream &stream, const T &last)
Definition: format.h:38
stdext::expand_snprintf
Definition: format.h:54
stdext::format
std::string format()
Definition: format.h:84
stdext::expand_snprintf< 0 >::call
static int call(char *s, size_t maxlen, const char *format, const Tuple &, const Args &... args)
Definition: format.h:60
stdext::snprintf
int snprintf(char *s, size_t maxlen, const char *format, const Args &... args)
Definition: format.h:71
stdext::print
void print(const T &... args)
Definition: format.h:44
traits.h
stdext
Definition: any.h:30