1#ifndef LIBFILEZILLA_FORMAT_HEADER
2#define LIBFILEZILLA_FORMAT_HEADER
10#ifdef LFZ_FORMAT_DEBUG
12#define format_assert(pred) assert((pred))
14#define format_assert(pred)
40 explicit operator bool()
const {
return type != 0; }
46 if constexpr (std::is_signed_v<std::decay_t<Arg>>) {
56template<
typename String,
bool Un
signed,
typename Arg>
59 std::decay_t<Arg>
v =
arg;
63 format_assert(!
Unsigned || !std::is_signed_v<std::decay_t<Arg>> ||
arg >= 0);
76 typename String::value_type
buf[
sizeof(
v) * 4 + 1];
77 auto *
const end =
buf +
sizeof(
v) * 4 + 1;
81 int const mod = std::abs(
static_cast<int>(
v % 10));
98 if (
static_cast<size_t>(end -
p) <
width) {
127template<
typename String,
bool Un
signed,
typename Arg>
134template<
typename String,
bool Un
signed,
typename Arg>
141template<
typename String,
class Arg,
typename =
void>
144template<
typename String,
class Arg>
153 template <
typename String>
154 static constexpr bool is_formattable_as = std::disjunction<
155 std::is_enum<std::decay_t<Arg>>,
156 std::is_arithmetic<std::decay_t<Arg>>,
157 std::is_pointer<std::decay_t<Arg>>,
158 std::is_same<String, std::decay_t<Arg>>,
159 has_toString<String, Arg>
165template<
typename String,
bool Lowercase,
typename Arg>
168 if constexpr (std::is_enum_v<std::decay_t<Arg>>) {
172 else if constexpr (std::is_signed_v<std::decay_t<Arg>>) {
175 else if constexpr (std::is_integral_v<std::decay_t<Arg>>) {
176 std::decay_t<Arg>
v =
arg;
177 typename String::value_type
buf[
sizeof(
v) * 2];
178 auto*
const end =
buf +
sizeof(
v) * 2;
195template<
typename String,
typename Arg>
198 if constexpr (std::is_pointer_v<std::decay_t<Arg>>) {
207template<
typename String,
typename Arg>
210 if constexpr (std::is_integral_v<std::decay_t<Arg>>) {
211 return String({
static_cast<typename String::value_type
>(
static_cast<unsigned char>(
arg))});
220template<
typename String>
233template<
typename String,
typename Arg>
238 if constexpr (std::is_same_v<String, std::decay_t<Arg>>) {
241 else if constexpr (has_toString<String, Arg>::value) {
252 else if (
f.type ==
'd' ||
f.type ==
'i') {
255 else if (
f.type ==
'u') {
258 else if (
f.type ==
'x') {
262 else if (
f.type ==
'X') {
266 else if (
f.type ==
'p') {
270 else if (
f.type ==
'c') {
301template<
typename InString,
typename OutString>
305 if (++
pos >=
fmt.size()) {
322 else if (
fmt[
pos] ==
' ') {
325 else if (
fmt[
pos] ==
'-') {
329 else if (
fmt[
pos] ==
'+') {
336 if (++
pos >=
fmt.size()) {
347 if (++
pos >=
fmt.size()) {
352 if (
f.width > 10000) {
360 if (++
pos >=
fmt.size()) {
370 if (
c ==
'h' ||
c ==
'l' ||
c ==
'L' ||
c ==
'j' ||
c ==
'z' ||
c ==
't') {
371 if (++
pos >=
fmt.size()) {
381 f.type =
static_cast<char>(
fmt[
pos++]);
385template<
typename String,
typename Arg,
int N>
390 "Argument cannot be formatted by fz::sprintf()"
396template<
typename String,
typename...
Args, std::size_t...
Is>
402template<
typename InString,
typename CharType =
typename InString::value_type,
typename OutString = std::basic_
string<CharType>,
typename... Args>
408 typename InString::size_type
start = 0,
pos;
411 while ((
pos =
fmt.find(
'%',
start)) != InString::npos) {
419 ret += detail::extract_arg<OutString>(
f,
arg_n++, std::forward<Args>(
args)...);
455template<
typename...
Args>
458 detail::check_arguments<std::string,
Args...>(std::index_sequence_for<
Args...>());
460 return detail::do_sprintf(
fmt, std::forward<Args>(
args)...);
463template<
typename...
Args>
466 detail::check_arguments<std::wstring,
Args...>(std::index_sequence_for<
Args...>());
468 return detail::do_sprintf(
fmt, std::forward<Args>(
args)...);
Functions to encode/decode strings.
type
Definition logger.hpp:16
The namespace used by libfilezilla.
Definition apply.hpp:17
bool dispatch(event_base const &ev, F &&f)
Dispatch for simple_event<> based events to simple functors.
Definition event_handler.hpp:199
std::string sprintf(std::string_view const &fmt, Args &&... args)
A simple type-safe sprintf replacement.
Definition format.hpp:456
String types and assorted functions.