Anklang-0.3.0.dev956+gd75ac925 anklang-0.3.0.dev956+gd75ac925
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
formatter.hh
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#pragma once
3
4#include <type_traits>
5#include <clocale>
6#include <cstdint>
7#include <sstream>
8#include <variant>
9#include <string>
10#include <list>
11
12namespace Ase {
13
15template<class ...Args> std::string string_format (const char *format, const Args &...args) __attribute__ ((__format__ (__printf__, 1, 0)));
16
18class ScopedPosixLocale final {
19 locale_t saved_locale_ = {};
20 void operator= (const ScopedPosixLocale&) = delete;
21 ScopedPosixLocale (const ScopedPosixLocale&) = delete;
22public:
23 explicit ScopedPosixLocale ();
24 virtual ~ScopedPosixLocale ();
25 static locale_t posix_locale();
26};
27
28// == Implementation Details ==
29namespace Impl {
30using StringFormatVariant = std::variant<uint64_t,double,const char*>;
32 using SL = std::list<std::string>; // use list to keep c_str() references stable
33 using StringFormatVariant::operator=;
34 void assign (const char *s, SL &h) { *this = s; }
35 void assign (const std::string &s, SL &h) { *this = s.c_str(); }
36 void assign (std::nullptr_t, SL &h) { *this = uint64_t (0); }
37 void assign (const void *p, SL &h) { *this = uint64_t (ptrdiff_t (p)); }
38 template<class T> typename std::enable_if<std::is_integral_v<T> || std::is_enum_v<T>, void>
39 ::type assign (const T &v, SL &h) { *this = uint64_t (v); }
40 template<class T> typename std::enable_if<std::is_floating_point_v<T>, void>
41 ::type assign (const T &v, SL &h) { *this = double (v); }
42 template<class T> typename std::enable_if<std::is_class<T>::value, void>
43 ::type assign (const T &o, SL &h) { std::ostringstream s; s << o; h.push_back (s.str()); *this = h.back().c_str(); }
44 static std::string string_format_args (const char *format, size_t N, const StringFormatArg *args);
45};
46} // Impl
47
62template<class ...Args> __attribute__ ((noinline)) std::string
63string_format (const char *format, const Args &...args)
64{
65 constexpr size_t N = sizeof... (Args);
66 Impl::StringFormatArg sfa[N ? N : 1];
67 size_t i = 0;
68 Impl::StringFormatArg::SL templist; // keep temporary strings across string_format_args()
69 (sfa[i++].assign (args, templist), ...); // C++17 fold expression
70 return sfa[0].string_format_args (format, N, sfa);
71}
72
73} // Ase
74
Class to push the POSIX/C locale_t (UTF-8) for the scope of its lifetime.
Definition formatter.hh:18
typedef double
The Anklang C++ API namespace.
Definition api.hh:8
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
typedef uint64_t
T str(T... args)