// Copyright © 2017 Martin Ueding <dev@martin-ueding.de>
// Licensed under the MIT/Expat license.
#include <iostream>
template <int i, bool divisable_3, bool divisable_5>
struct FizzBuzz_1 {
static int const value = i;
};
template <int i>
struct FizzBuzz_1<i, true, false> {
static int const value = -1;
};
template <int i>
struct FizzBuzz_1<i, false, true> {
static int const value = -2;
};
template <int i>
struct FizzBuzz_1<i, true, true> {
static int const value = -3;
};
template <int i>
struct FizzBuzz : public FizzBuzz_1<i, i % 3 == 0, i % 5 == 0> {};
template <int i>
constexpr char const *word();
template <>
constexpr char const *word<-1>() {
return "Fizz";
}
template <>
constexpr char const *word<-2>() {
return "Buzz";
}
template <>
constexpr char const *word<-3>() {
return "FizzBuzz";
}
template <int i>
struct Print {
static void print() {
Print<i - 1>::print();
auto const value = FizzBuzz<i>::value;
if (value < 0) {
std::cout << word<value>() << std::endl;
} else {
std::cout << value << std::endl;
}
}
};
template <>
struct Print<0> {
static void print() {}
};
int main() {
Print<100>::print();
}
Ly8gQ29weXJpZ2h0IMKpIDIwMTcgTWFydGluIFVlZGluZyA8ZGV2QG1hcnRpbi11ZWRpbmcuZGU+Ci8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQvRXhwYXQgbGljZW5zZS4KCiNpbmNsdWRlIDxpb3N0cmVhbT4KCnRlbXBsYXRlIDxpbnQgaSwgYm9vbCBkaXZpc2FibGVfMywgYm9vbCBkaXZpc2FibGVfNT4Kc3RydWN0IEZpenpCdXp6XzEgewogICAgc3RhdGljIGludCBjb25zdCB2YWx1ZSA9IGk7Cn07Cgp0ZW1wbGF0ZSA8aW50IGk+CnN0cnVjdCBGaXp6QnV6el8xPGksIHRydWUsIGZhbHNlPiB7CiAgICBzdGF0aWMgaW50IGNvbnN0IHZhbHVlID0gLTE7Cn07Cgp0ZW1wbGF0ZSA8aW50IGk+CnN0cnVjdCBGaXp6QnV6el8xPGksIGZhbHNlLCB0cnVlPiB7CiAgICBzdGF0aWMgaW50IGNvbnN0IHZhbHVlID0gLTI7Cn07Cgp0ZW1wbGF0ZSA8aW50IGk+CnN0cnVjdCBGaXp6QnV6el8xPGksIHRydWUsIHRydWU+IHsKICAgIHN0YXRpYyBpbnQgY29uc3QgdmFsdWUgPSAtMzsKfTsKCnRlbXBsYXRlIDxpbnQgaT4Kc3RydWN0IEZpenpCdXp6IDogcHVibGljIEZpenpCdXp6XzE8aSwgaSAlIDMgPT0gMCwgaSAlIDUgPT0gMD4ge307Cgp0ZW1wbGF0ZSA8aW50IGk+CmNvbnN0ZXhwciBjaGFyIGNvbnN0ICp3b3JkKCk7Cgp0ZW1wbGF0ZSA8Pgpjb25zdGV4cHIgY2hhciBjb25zdCAqd29yZDwtMT4oKSB7CiAgICByZXR1cm4gIkZpenoiOwp9Cgp0ZW1wbGF0ZSA8Pgpjb25zdGV4cHIgY2hhciBjb25zdCAqd29yZDwtMj4oKSB7CiAgICByZXR1cm4gIkJ1enoiOwp9Cgp0ZW1wbGF0ZSA8Pgpjb25zdGV4cHIgY2hhciBjb25zdCAqd29yZDwtMz4oKSB7CiAgICByZXR1cm4gIkZpenpCdXp6IjsKfQoKdGVtcGxhdGUgPGludCBpPgpzdHJ1Y3QgUHJpbnQgewogICAgc3RhdGljIHZvaWQgcHJpbnQoKSB7CiAgICAgICAgUHJpbnQ8aSAtIDE+OjpwcmludCgpOwogICAgICAgIGF1dG8gY29uc3QgdmFsdWUgPSBGaXp6QnV6ejxpPjo6dmFsdWU7CiAgICAgICAgaWYgKHZhbHVlIDwgMCkgewogICAgICAgICAgICBzdGQ6OmNvdXQgPDwgd29yZDx2YWx1ZT4oKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RkOjpjb3V0IDw8IHZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgICAgICB9CiAgICB9Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgUHJpbnQ8MD4gewogICAgc3RhdGljIHZvaWQgcHJpbnQoKSB7fQp9OwoKaW50IG1haW4oKSB7CiAgICBQcmludDwxMDA+OjpwcmludCgpOwp9Cg==