Skip to content

Instantly share code, notes, and snippets.

@regexident
Last active January 11, 2024 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save regexident/7953e94db6a630a0bf41 to your computer and use it in GitHub Desktop.
Save regexident/7953e94db6a630a0bf41 to your computer and use it in GitHub Desktop.
FizzBuzz in C++ Template Meta-Programming
// Created by Vincent Esche on 2/10/15.
// Copyright (c) 2015 Vincent Esche. All rights reserved.
#include <iostream>
#include <cxxabi.h>
struct fizz;
struct buzz;
struct fizz_buzz;
template <int Number>
struct num : public std::integral_constant<int, Number> { };
template <typename...Types>
struct list { };
template <template <typename> class Function, typename TypeList>
struct map;
template <template <typename> class Function, typename...Types>
struct map<Function, list<Types...>> {
using type = list<typename Function<Types>::type...>;
};
template <typename Number, bool Fizz = (Number::value%3)==0, bool Buzz = (Number::value%5)==0>
struct fb_impl {
using type = Number;
};
template <int Number>
struct fb_impl<num<Number>, true, true> {
using type = fizz_buzz;
};
template <int Number>
struct fb_impl<num<Number>, true, false> {
using type = fizz;
};
template <int Number>
struct fb_impl<num<Number>, false, true> {
using type = buzz;
};
template <typename Number>
using fb = fb_impl<Number>;
template <typename Type, typename TypeList>
struct cons;
template <typename Type, typename...Types>
struct cons<Type, list<Types...>> {
using type = list<Type, Types...>;
};
template <int First, int Last, template <int> class Type>
struct generate {
using type = typename cons<Type<First>, typename generate<First + 1, Last, Type>::type>::type;
};
template <int Number, template <int> class Type>
struct generate<Number, Number, Type> {
using type = list<>;
};
template <typename Type>
const char *demangled_type_name() {
int status;
return abi::__cxa_demangle(typeid(Type).name(), 0, 0, &status);
}
template <typename TypeList>
void print_type_list() {
using list_type = TypeList;
std::cout << demangled_type_name<list_type>() << std::endl;
}
int main(int argc, const char * argv[]) {
using numbers_list = typename generate<1, 256, num>::type;
using fizz_buzz_list = typename map<fb, numbers_list>::type;
print_type_list<fizz_buzz_list>();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment