NGL  6.5
The NCCA Graphics Library
format.cc
Go to the documentation of this file.
1 /*
2  Formatting library for C++
3 
4  Copyright (c) 2012 - 2016, Victor Zverovich
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9 
10  1. Redistributions of source code must retain the above copyright notice, this
11  list of conditions and the following disclaimer.
12  2. Redistributions in binary form must reproduce the above copyright notice,
13  this list of conditions and the following disclaimer in the documentation
14  and/or other materials provided with the distribution.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "fmt/format.h"
29 #include "fmt/printf.h"
30 
31 #include <string.h>
32 
33 #include <cctype>
34 #include <cerrno>
35 #include <climits>
36 #include <cmath>
37 #include <cstdarg>
38 #include <cstddef> // for std::ptrdiff_t
39 
40 #if defined(_WIN32) && defined(__MINGW32__)
41 # include <cstring>
42 #endif
43 
44 #if FMT_USE_WINDOWS_H
45 # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
46 # include <windows.h>
47 # else
48 # define NOMINMAX
49 # include <windows.h>
50 # undef NOMINMAX
51 # endif
52 #endif
53 
54 using fmt::internal::Arg;
55 
56 #if FMT_EXCEPTIONS
57 # define FMT_TRY try
58 # define FMT_CATCH(x) catch (x)
59 #else
60 # define FMT_TRY if (true)
61 # define FMT_CATCH(x) if (false)
62 #endif
63 
64 #ifdef _MSC_VER
65 # pragma warning(push)
66 # pragma warning(disable: 4127) // conditional expression is constant
67 # pragma warning(disable: 4702) // unreachable code
68 // Disable deprecation warning for strerror. The latter is not called but
69 // MSVC fails to detect it.
70 # pragma warning(disable: 4996)
71 #endif
72 
73 // Dummy implementations of strerror_r and strerror_s called if corresponding
74 // system functions are not available.
75 static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
76  return fmt::internal::Null<>();
77 }
78 static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
79  return fmt::internal::Null<>();
80 }
81 
82 namespace fmt {
83 
87 
88 namespace {
89 
90 #ifndef _MSC_VER
91 # define FMT_SNPRINTF snprintf
92 #else // _MSC_VER
93 inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
94  va_list args;
95  va_start(args, format);
96  int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
97  va_end(args);
98  return result;
99 }
100 # define FMT_SNPRINTF fmt_snprintf
101 #endif // _MSC_VER
102 
103 #if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
104 # define FMT_SWPRINTF snwprintf
105 #else
106 # define FMT_SWPRINTF swprintf
107 #endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
108 
109 const char RESET_COLOR[] = "\x1b[0m";
110 
111 typedef void (*FormatFunc)(Writer &, int, StringRef);
112 
113 // Portable thread-safe version of strerror.
114 // Sets buffer to point to a string describing the error code.
115 // This can be either a pointer to a string stored in buffer,
116 // or a pointer to some static immutable string.
117 // Returns one of the following values:
118 // 0 - success
119 // ERANGE - buffer is not large enough to store the error message
120 // other - failure
121 // Buffer should be at least of size 1.
122 int safe_strerror(
123  int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
124  FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
125 
126  class StrError {
127  private:
128  int error_code_;
129  char *&buffer_;
130  std::size_t buffer_size_;
131 
132  // A noop assignment operator to avoid bogus warnings.
133  void operator=(const StrError &) {}
134 
135  // Handle the result of XSI-compliant version of strerror_r.
136  int handle(int result) {
137  // glibc versions before 2.13 return result in errno.
138  return result == -1 ? errno : result;
139  }
140 
141  // Handle the result of GNU-specific version of strerror_r.
142  int handle(char *message) {
143  // If the buffer is full then the message is probably truncated.
144  if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
145  return ERANGE;
146  buffer_ = message;
147  return 0;
148  }
149 
150  // Handle the case when strerror_r is not available.
151  int handle(internal::Null<>) {
152  return fallback(strerror_s(buffer_, buffer_size_, error_code_));
153  }
154 
155  // Fallback to strerror_s when strerror_r is not available.
156  int fallback(int result) {
157  // If the buffer is full then the message is probably truncated.
158  return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
159  ERANGE : result;
160  }
161 
162  // Fallback to strerror if strerror_r and strerror_s are not available.
163  int fallback(internal::Null<>) {
164  errno = 0;
165  buffer_ = strerror(error_code_);
166  return errno;
167  }
168 
169  public:
170  StrError(int err_code, char *&buf, std::size_t buf_size)
171  : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
172 
173  int run() {
174  strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
175  return handle(strerror_r(error_code_, buffer_, buffer_size_));
176  }
177  };
178  return StrError(error_code, buffer, buffer_size).run();
179 }
180 
181 void format_error_code(Writer &out, int error_code,
183  // Report error code making sure that the output fits into
184  // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
185  // bad_alloc.
186  out.clear();
187  static const char SEP[] = ": ";
188  static const char ERROR_STR[] = "error ";
189  // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
190  std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
191  typedef internal::IntTraits<int>::MainType MainType;
192  MainType abs_value = static_cast<MainType>(error_code);
193  if (internal::is_negative(error_code)) {
194  abs_value = 0 - abs_value;
195  ++error_code_size;
196  }
197  error_code_size += internal::count_digits(abs_value);
198  if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
199  out << message << SEP;
200  out << ERROR_STR << error_code;
201  assert(out.size() <= internal::INLINE_BUFFER_SIZE);
202 }
203 
204 void report_error(FormatFunc func, int error_code,
205  StringRef message) FMT_NOEXCEPT {
206  MemoryWriter full_message;
207  func(full_message, error_code, message);
208  // Use Writer::data instead of Writer::c_str to avoid potential memory
209  // allocation.
210  std::fwrite(full_message.data(), full_message.size(), 1, stderr);
211  std::fputc('\n', stderr);
212 }
213 } // namespace
214 
215 namespace internal {
216 
217 // This method is used to preserve binary compatibility with fmt 3.0.
218 // It can be removed in 4.0.
220  Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
221  fmt::format_system_error(out, error_code, message);
222 }
223 } // namespace internal
224 
226  int err_code, CStringRef format_str, ArgList args) {
227  error_code_ = err_code;
228  MemoryWriter w;
229  format_system_error(w, err_code, format(format_str, args));
230  std::runtime_error &base = *this;
231  base = std::runtime_error(w.str());
232 }
233 
234 template <typename T>
236  char *buffer, std::size_t size, const char *format,
237  unsigned width, int precision, T value) {
238  if (width == 0) {
239  return precision < 0 ?
240  FMT_SNPRINTF(buffer, size, format, value) :
241  FMT_SNPRINTF(buffer, size, format, precision, value);
242  }
243  return precision < 0 ?
244  FMT_SNPRINTF(buffer, size, format, width, value) :
245  FMT_SNPRINTF(buffer, size, format, width, precision, value);
246 }
247 
248 template <typename T>
250  wchar_t *buffer, std::size_t size, const wchar_t *format,
251  unsigned width, int precision, T value) {
252  if (width == 0) {
253  return precision < 0 ?
254  FMT_SWPRINTF(buffer, size, format, value) :
255  FMT_SWPRINTF(buffer, size, format, precision, value);
256  }
257  return precision < 0 ?
258  FMT_SWPRINTF(buffer, size, format, width, value) :
259  FMT_SWPRINTF(buffer, size, format, width, precision, value);
260 }
261 
262 template <typename T>
263 const char internal::BasicData<T>::DIGITS[] =
264  "0001020304050607080910111213141516171819"
265  "2021222324252627282930313233343536373839"
266  "4041424344454647484950515253545556575859"
267  "6061626364656667686970717273747576777879"
268  "8081828384858687888990919293949596979899";
269 
270 #define FMT_POWERS_OF_10(factor) \
271  factor * 10, \
272  factor * 100, \
273  factor * 1000, \
274  factor * 10000, \
275  factor * 100000, \
276  factor * 1000000, \
277  factor * 10000000, \
278  factor * 100000000, \
279  factor * 1000000000
280 
281 template <typename T>
283  0, FMT_POWERS_OF_10(1)
284 };
285 
286 template <typename T>
288  0,
289  FMT_POWERS_OF_10(1),
290  FMT_POWERS_OF_10(ULongLong(1000000000)),
291  // Multiply several constants instead of using a single long long constant
292  // to avoid warnings about C++98 not supporting long long.
293  ULongLong(1000000000) * ULongLong(1000000000) * 10
294 };
295 
296 FMT_FUNC void internal::report_unknown_type(char code, const char *type) {
297  (void)type;
298  if (std::isprint(static_cast<unsigned char>(code))) {
300  format("unknown format code '{}' for {}", code, type)));
301  }
303  format("unknown format code '\\x{:02x}' for {}",
304  static_cast<unsigned>(code), type)));
305 }
306 
307 #if FMT_USE_WINDOWS_H
308 
309 FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) {
310  static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
311  if (s.size() > INT_MAX)
312  FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
313  int s_size = static_cast<int>(s.size());
314  int length = MultiByteToWideChar(
315  CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
316  if (length == 0)
317  FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
318  buffer_.resize(length + 1);
319  length = MultiByteToWideChar(
320  CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
321  if (length == 0)
322  FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
323  buffer_[length] = 0;
324 }
325 
326 FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) {
327  if (int error_code = convert(s)) {
328  FMT_THROW(WindowsError(error_code,
329  "cannot convert string from UTF-16 to UTF-8"));
330  }
331 }
332 
334  if (s.size() > INT_MAX)
335  return ERROR_INVALID_PARAMETER;
336  int s_size = static_cast<int>(s.size());
337  int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
338  if (length == 0)
339  return GetLastError();
340  buffer_.resize(length + 1);
341  length = WideCharToMultiByte(
342  CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
343  if (length == 0)
344  return GetLastError();
345  buffer_[length] = 0;
346  return 0;
347 }
348 
349 FMT_FUNC void WindowsError::init(
350  int err_code, CStringRef format_str, ArgList args) {
351  error_code_ = err_code;
352  MemoryWriter w;
353  internal::format_windows_error(w, err_code, format(format_str, args));
354  std::runtime_error &base = *this;
355  base = std::runtime_error(w.str());
356 }
357 
358 FMT_FUNC void internal::format_windows_error(
359  Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
360  FMT_TRY {
362  buffer.resize(INLINE_BUFFER_SIZE);
363  for (;;) {
364  wchar_t *system_message = &buffer[0];
365  int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
366  0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
367  system_message, static_cast<uint32_t>(buffer.size()), 0);
368  if (result != 0) {
369  UTF16ToUTF8 utf8_message;
370  if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
371  out << message << ": " << utf8_message;
372  return;
373  }
374  break;
375  }
376  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
377  break; // Can't get error message, report error code instead.
378  buffer.resize(buffer.size() * 2);
379  }
380  } FMT_CATCH(...) {}
381  fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
382 }
383 
384 #endif // FMT_USE_WINDOWS_H
385 
387  Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
388  FMT_TRY {
391  for (;;) {
392  char *system_message = &buffer[0];
393  int result = safe_strerror(error_code, system_message, buffer.size());
394  if (result == 0) {
395  out << message << ": " << system_message;
396  return;
397  }
398  if (result != ERANGE)
399  break; // Can't get error message, report error code instead.
400  buffer.resize(buffer.size() * 2);
401  }
402  } FMT_CATCH(...) {}
403  fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
404 }
405 
406 template <typename Char>
408  if (!map_.empty())
409  return;
411  const NamedArg *named_arg = 0;
412  bool use_values =
414  if (use_values) {
415  for (unsigned i = 0;/*nothing*/; ++i) {
416  internal::Arg::Type arg_type = args.type(i);
417  switch (arg_type) {
418  case internal::Arg::NONE:
419  return;
421  named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
422  map_.push_back(Pair(named_arg->name, *named_arg));
423  break;
424  default:
425  /*nothing*/;
426  }
427  }
428  return;
429  }
430  for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
431  internal::Arg::Type arg_type = args.type(i);
432  if (arg_type == internal::Arg::NAMED_ARG) {
433  named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
434  map_.push_back(Pair(named_arg->name, *named_arg));
435  }
436  }
437  for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
438  switch (args.args_[i].type) {
439  case internal::Arg::NONE:
440  return;
442  named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
443  map_.push_back(Pair(named_arg->name, *named_arg));
444  break;
445  default:
446  /*nothing*/;
447  }
448  }
449 }
450 
451 template <typename Char>
453  FMT_THROW(std::runtime_error("buffer overflow"));
454 }
455 
457  unsigned arg_index, const char *&error) {
458  Arg arg = args_[arg_index];
459  switch (arg.type) {
460  case Arg::NONE:
461  error = "argument index out of range";
462  break;
463  case Arg::NAMED_ARG:
464  arg = *static_cast<const internal::Arg*>(arg.pointer);
465  break;
466  default:
467  /*nothing*/;
468  }
469  return arg;
470 }
471 
473  int error_code, fmt::StringRef message) FMT_NOEXCEPT {
474  // 'fmt::' is for bcc32.
475  report_error(format_system_error, error_code, message);
476 }
477 
478 #if FMT_USE_WINDOWS_H
479 FMT_FUNC void report_windows_error(
480  int error_code, fmt::StringRef message) FMT_NOEXCEPT {
481  // 'fmt::' is for bcc32.
482  report_error(internal::format_windows_error, error_code, message);
483 }
484 #endif
485 
486 FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) {
487  MemoryWriter w;
488  w.write(format_str, args);
489  std::fwrite(w.data(), 1, w.size(), f);
490 }
491 
492 FMT_FUNC void print(CStringRef format_str, ArgList args) {
493  print(stdout, format_str, args);
494 }
495 
497  char escape[] = "\x1b[30m";
498  escape[3] = static_cast<char>('0' + c);
499  std::fputs(escape, stdout);
500  print(format, args);
501  std::fputs(RESET_COLOR, stdout);
502 }
503 
504 template <typename Char>
506 
507 FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) {
508  MemoryWriter w;
509  printf(w, format, args);
510  std::size_t size = w.size();
511  return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
512 }
513 
514 #ifndef FMT_HEADER_ONLY
515 
516 template struct internal::BasicData<void>;
517 
518 // Explicit instantiations for char.
519 
520 template void internal::FixedBuffer<char>::grow(std::size_t);
521 
522 template void internal::ArgMap<char>::init(const ArgList &args);
523 
524 template void PrintfFormatter<char>::format(CStringRef format);
525 
527  char *buffer, std::size_t size, const char *format,
528  unsigned width, int precision, double value);
529 
530 template int internal::CharTraits<char>::format_float(
531  char *buffer, std::size_t size, const char *format,
532  unsigned width, int precision, long double value);
533 
534 // Explicit instantiations for wchar_t.
535 
536 template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
537 
538 template void internal::ArgMap<wchar_t>::init(const ArgList &args);
539 
540 template void PrintfFormatter<wchar_t>::format(WCStringRef format);
541 
543  wchar_t *buffer, std::size_t size, const wchar_t *format,
544  unsigned width, int precision, double value);
545 
546 template int internal::CharTraits<wchar_t>::format_float(
547  wchar_t *buffer, std::size_t size, const wchar_t *format,
548  unsigned width, int precision, long double value);
549 
550 #endif // FMT_HEADER_ONLY
551 
552 } // namespace fmt
553 
554 #ifdef _MSC_VER
555 # pragma warning(pop)
556 #endif
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
Definition: glew.h:2584
std::size_t size() const
Definition: format.h:455
FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args)
Definition: format.cc:496
const internal::Arg * args_
Definition: format.h:1376
#define FMT_NOEXCEPT
Definition: format.h:190
const void * pointer
Definition: format.h:1018
bool is_negative(T value)
Definition: format.h:811
#define FMT_ASSERT(condition, message)
Definition: format.h:229
FMT_API void format(BasicCStringRef< Char > format_str)
Definition: printf.h:387
static const uint32_t POWERS_OF_10_32[]
Definition: format.h:836
BasicStringRef< Char > name
Definition: format.h:1346
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1256
FMT_API void report_unknown_type(char code, const char *type)
Definition: format.cc:296
static fmt::internal::Null strerror_s(char *, std::size_t,...)
Definition: format.cc:78
const GLfloat * c
Definition: glew.h:16629
std::string format(CStringRef format_str, ArgList args)
Definition: format.h:3175
const Char * data() const FMT_NOEXCEPT
Definition: format.h:2468
static fmt::internal::Null strerror_r(int, char *,...)
Definition: format.cc:75
FMT_GCC_EXTENSION typedef unsigned long long ULongLong
Definition: format.h:369
FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args)
Definition: format.cc:507
GLsizei const GLfloat * value
Definition: glew.h:1852
JSON writer.
Definition: writer.h:54
typedef void(GLAPIENTRY *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target
FMT_FUNC void format_system_error(Writer &out, int error_code, StringRef message) FMT_NOEXCEPT
Definition: format.cc:219
internal::Arg::Type type(unsigned index) const
Definition: format.h:1379
GLuint GLsizei GLsizei * length
Definition: glew.h:1828
#define FMT_THROW(x)
Definition: format.h:172
Yes & convert(fmt::ULongLong)
FMT_FUNC void report_system_error(int error_code, fmt::StringRef message) FMT_NOEXCEPT
Definition: format.cc:472
FMT_FUNC void format_system_error(Writer &out, int error_code, StringRef message) FMT_NOEXCEPT
Definition: format.cc:386
#define FMT_SNPRINTF
Definition: format.cc:91
const Char * data() const
Definition: format.h:452
GLuint64EXT * result
Definition: glew.h:14309
BasicStringRef< char > StringRef
Definition: format.h:486
BasicMemoryWriter< char > MemoryWriter
Definition: format.h:3050
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1893
void write(BasicCStringRef< Char > format, ArgList args)
Definition: format.h:2515
GLenum GLint GLint * precision
Definition: glew.h:3512
#define FMT_FUNC
Definition: format.h:3832
unsigned int uint32_t
Definition: stdint.h:126
#define FMT_SWPRINTF
Definition: format.cc:106
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2583
MapType::value_type Pair
Definition: format.h:1816
unsigned __int64 uint64_t
Definition: stdint.h:136
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
GLuint buffer
Definition: glew.h:1683
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glew.h:1257
FMT_API Arg do_get_arg(unsigned arg_index, const char *&error)
Definition: format.cc:456
const internal::Value * values_
Definition: format.h:1375
Color
Definition: format.h:3156
static const uint64_t POWERS_OF_10_64[]
Definition: format.h:837
internal::NamedArg< char > arg(StringRef name, const T &arg)
Definition: format.h:3325
FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args)
Definition: format.cc:486
unsigned count_digits(uint64_t n)
Definition: format.h:864
void resize(std::size_t new_size)
Definition: format.h:623
FMT_API void init(const ArgList &args)
Definition: format.cc:407
GLsizeiptr size
Definition: glew.h:1684
#define FMT_POWERS_OF_10(factor)
Definition: format.cc:270
Definition: format.cc:82
#define FMT_CATCH(x)
Definition: format.cc:61
std::size_t size() const
Definition: format.h:615
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1255
GLdouble s
Definition: glew.h:1393
std::basic_string< Char > str() const
Definition: format.h:2486
#define FMT_TRY
Definition: format.cc:60
FMT_API void grow(std::size_t size)
Definition: format.cc:452
void init(int err_code, CStringRef format_str, ArgList args)
Definition: format.cc:225
std::size_t size() const
Definition: format.h:2462
GLclampf f
Definition: glew.h:3511
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: printf.h:487