Skip to content

Instantly share code, notes, and snippets.

@zeux
Created July 5, 2018 20:01
Show Gist options
  • Save zeux/d0a6135d1ad39ce67570fdd6ac21914e to your computer and use it in GitHub Desktop.
Save zeux/d0a6135d1ad39ce67570fdd6ac21914e to your computer and use it in GitHub Desktop.
A sketch of type-safe string formatter using C++11 variadic templates and, unlike fmtlib, focusing on minimal header size & compilation time.
#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(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