Skip to content

Instantly share code, notes, and snippets.

@zeux
Last active November 14, 2025 11:08
Show Gist options
  • Select an option

  • Save zeux/86c420e042484cda41cc6510fc19bd7d to your computer and use it in GitHub Desktop.

Select an option

Save zeux/86c420e042484cda41cc6510fc19bd7d to your computer and use it in GitHub Desktop.
C++ format library proof of concept - focus here is on minimal header so that compilation time is not affected. Implementation is very bare bones.
#include "format.h"
namespace fmt {
static void format_bool(std::string& result, bool value)
{
result += value ? "true" : "false";
}
static void format_char(std::string& result, char value)
{
result += value;
}
static void format_char(std::string& result, wchar_t value)
{
result += char(value);
}
template <typename T>
static void format_integer(std::string& result, T value)
{
char buf[128];
sprintf(buf, "%d", int(value));
result += buf;
}
template <typename T>
static void format_fp(std::string& result, T value)
{
char buf[128];
sprintf(buf, "%f", value);
result += buf;
}
static void format_pointer(std::string& result, const void* value)
{
char buf[128];
sprintf(buf, "%p", value);
result += buf;
}
static void format_string(std::string& result, const char* value)
{
result += value;
}
static void format_string(std::string& result, const std::string& value)
{
result += value;
}
static void format_dispatch(std::string& result, kind_t kind, const void* value)
{
switch (kind)
{
case kind_bool: return format_bool(result, *static_cast<const bool*>(value));
case kind_schar: return format_integer(result, *static_cast<const signed char*>(value));
case kind_uchar: return format_integer(result, *static_cast<const unsigned char*>(value));
case kind_char: return format_char(result, *static_cast<const char*>(value));
case kind_wchar_t: return format_char(result, *static_cast<const wchar_t*>(value));
case kind_short: return format_integer(result, *static_cast<const short*>(value));
case kind_ushort: return format_integer(result, *static_cast<const unsigned short*>(value));
case kind_int: return format_integer(result, *static_cast<const int*>(value));
case kind_uint: return format_integer(result, *static_cast<const unsigned int*>(value));
case kind_long: return format_integer(result, *static_cast<const long*>(value));
case kind_ulong: return format_integer(result, *static_cast<const unsigned long*>(value));
case kind_llong: return format_integer(result, *static_cast<const long long*>(value));
case kind_ullong: return format_integer(result, *static_cast<const unsigned long long*>(value));
case kind_float: return format_fp(result, *static_cast<const float*>(value));
case kind_double: return format_fp(result, *static_cast<const double*>(value));
case kind_ldouble: return format_fp(result, *static_cast<const long double*>(value));
case kind_voidptr: return format_pointer(result, *static_cast<const void* const *>(value));
case kind_charptr: return format_string(result, *static_cast<const char* const *>(value));
case kind_string: return format_string(result, *static_cast<const std::string*>(value));
case kind_nullptr: return format_pointer(result, nullptr);
}
}
std::string format_impl(const char* spec, const kind_t kinds[], const void* values[], size_t count)
{
std::string result;
size_t offset = 0;
for (const char* s = spec; *s; ++s)
{
if (s[0] == '{')
{
if (s[1] == '}')
{
if (offset >= count)
throw std::runtime_error("Not enough format arguments");
format_dispatch(result, kinds[offset], values[offset]);
offset++;
s++;
}
else
{
throw std::runtime_error("Unmatched brace");
}
}
else
{
result += s[0];
}
}
return result;
}
}
#pragma once
#include <string>
namespace fmt {
#define KIND(X) \
X(bool,bool) \
X(signed char,schar) \
X(unsigned char,uchar) \
X(char,char) \
X(wchar_t,wchar_t) \
X(short,short) \
X(unsigned short,ushort) \
X(int,int) \
X(unsigned int,uint) \
X(long,long) \
X(unsigned long,ulong) \
X(long long,llong) \
X(unsigned long long,ullong) \
X(float,float) \
X(double,double) \
X(long double,ldouble) \
X(const void*,voidptr) \
X(const char*,charptr) \
X(std::string,string) \
X(std::nullptr_t,nullptr)
#define KIND_ENUM(T,V) kind_##V,
enum kind_t { KIND(KIND_ENUM) };
#undef KIND_ENUM
template <typename T> struct type_kind;
#define KIND_SPEC(T,V) template <> struct type_kind<T> { enum { value = kind_##V }; };
KIND(KIND_SPEC)
#undef KIND_SPEC
template <typename T> struct type_kind<T&> { enum { value = type_kind<T>::value }; };
template <typename T> struct type_kind<const T> { enum { value = type_kind<T>::value }; };
#undef KIND
std::string format_impl(const char* spec, const kind_t kinds[], const void* values[], size_t count);
template <typename... Args>
std::string format(const char* spec, Args&&... args)
{
static constexpr kind_t kinds[] = { kind_t(type_kind<Args>::value)... };
const void* values[] = { &args... };
return format_impl(spec, kinds, values, sizeof(kinds) / sizeof(kinds[0]));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment