#include <iostream>
#include <string>
#include <type_traits>
struct empty_result
{
static const std::string value;
};
template<size_t Width, size_t Height>
struct result_size
{
static const size_t width = Width;
static const size_t height = Height;
static const size_t square = Width * Height;
};
template<char Foreground, char Background>
struct render_rule
{
static const char background = Background;
static const char foreground = Foreground;
};
const std::string empty_result::value;
template<size_t Idx, unsigned char Block>
struct get_element
{
static const size_t value = ((Block & ((Idx < 4) ? 0xF0 : 0x0F)) >> (7 - Idx)) & 1;
};
template<size_t Id, size_t Idx, class Size, class Rule, size_t Element>
struct process_one
{
static const bool in_render_zone = Idx < Size::square;
static const bool new_line = Idx > 0 && (Idx % Size::width == 0);
static const std::string value;
};
template<size_t Id, size_t Idx, class Size, class Rule, size_t Element>
const std::string process_one<Id, Idx, Size, Rule, Element>::value = (in_render_zone) ? (((new_line) ? (std::string() + '\n') : std::string()) +
((Element != 0) ? Rule::foreground : Rule::background)) : std::string();
template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
struct process_block
{
static const std::string value;
};
template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
const std::string process_block<Id, Idx, Size, Rule, Block>::value =
process_one<Id, Idx, Size, Rule, get_element<0, Block>::value>::value +
process_one<Id, Idx + 1, Size, Rule, get_element<1, Block>::value>::value +
process_one<Id, Idx + 2, Size, Rule, get_element<2, Block>::value>::value +
process_one<Id, Idx + 3, Size, Rule, get_element<3, Block>::value>::value +
process_one<Id, Idx + 4, Size, Rule, get_element<4, Block>::value>::value +
process_one<Id, Idx + 5, Size, Rule, get_element<5, Block>::value>::value +
process_one<Id, Idx + 6, Size, Rule, get_element<6, Block>::value>::value +
process_one<Id, Idx + 7, Size, Rule, get_element<7, Block>::value>::value;
template<size_t Id, size_t Idx, class Size, class Rule, unsigned char... Data> struct render;
template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
struct render<Id, Idx, Size, Rule, First, Data...>
{
static const std::string value;
};
template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
const std::string render<Id, Idx, Size, Rule, First, Data...>::value = process_block<Id, Idx, Size, Rule, First>::value +
render<Id, Idx + 8, Size, Rule, Data...>::value;
template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
struct render<Id, Idx, Size, Rule, Last>
{
static const std::string value;
};
template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
const std::string render<Id, Idx, Size, Rule, Last>::value = process_block<Id, Idx, Size, Rule, Last>::value;
template<size_t Id, size_t Width, class Rule, unsigned char... Data>
struct silly_img
{
static const size_t width = Width;
static const size_t height = (Width > 0) ? (sizeof...(Data) * 8 / Width) : 0;
static const bool is_valid = width > 0 && height > 0;
static const std::string data;
static void show_me()
{
std::cout << "(" << Id << ") Size: " << width << " x " << height << "\n\n";
std::cout << data;
}
};
template<size_t Id, size_t Width, class Rule, unsigned char... Data>
const std::string silly_img<Id, Width, Rule, Data...>::data = std::string() +
std::conditional< is_valid, render<Id, 0, result_size<width, height>, Rule, Data...>, empty_result>::type::value;
int main()
{
silly_img<0, 11, render_rule<'$', ' '>, 0x31, 0x8F, 0x7B, 0xFF, 0xFF, 0xF3, 0xF8, 0x1C, 0x01, 0x00>::show_me();
std::cout << "\n\n";
silly_img<1, 15, render_rule<'#', '.'>, 0x31, 0x84, 0xF7, 0x9F, 0xFF, 0x97, 0xFF, 0x03, 0xF8, 0x81, 0xC3, 0x81, 0x02, 0x00>::show_me();
std::cout << "\n\n";
silly_img<2, 15, render_rule<'*', ' '>, 0x3F, 0xE4, 0xFF, 0x9F, 0xC0, 0x17, 0x80, 0x0F, 0x00, 0x8F, 0xF3, 0x8F, 0xF2, 0x00>::show_me();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzdHJ1Y3QgZW1wdHlfcmVzdWx0CnsKICAgIHN0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyB2YWx1ZTsKfTsKCnRlbXBsYXRlPHNpemVfdCBXaWR0aCwgc2l6ZV90IEhlaWdodD4Kc3RydWN0IHJlc3VsdF9zaXplCnsKICAgIHN0YXRpYyBjb25zdCBzaXplX3Qgd2lkdGggPSBXaWR0aDsKICAgIHN0YXRpYyBjb25zdCBzaXplX3QgaGVpZ2h0ID0gSGVpZ2h0OwogICAgc3RhdGljIGNvbnN0IHNpemVfdCBzcXVhcmUgPSBXaWR0aCAqIEhlaWdodDsKfTsKCnRlbXBsYXRlPGNoYXIgRm9yZWdyb3VuZCwgY2hhciBCYWNrZ3JvdW5kPgpzdHJ1Y3QgcmVuZGVyX3J1bGUKewogICAgc3RhdGljIGNvbnN0IGNoYXIgYmFja2dyb3VuZCA9IEJhY2tncm91bmQ7CiAgICBzdGF0aWMgY29uc3QgY2hhciBmb3JlZ3JvdW5kID0gRm9yZWdyb3VuZDsKfTsKCmNvbnN0IHN0ZDo6c3RyaW5nIGVtcHR5X3Jlc3VsdDo6dmFsdWU7Cgp0ZW1wbGF0ZTxzaXplX3QgSWR4LCB1bnNpZ25lZCBjaGFyIEJsb2NrPgpzdHJ1Y3QgZ2V0X2VsZW1lbnQKewogICAgc3RhdGljIGNvbnN0IHNpemVfdCB2YWx1ZSA9ICgoQmxvY2sgJiAoKElkeCA8IDQpID8gMHhGMCA6IDB4MEYpKSA+PiAoNyAtIElkeCkpICYgMTsKfTsKCnRlbXBsYXRlPHNpemVfdCBJZCwgc2l6ZV90IElkeCwgY2xhc3MgU2l6ZSwgY2xhc3MgUnVsZSwgc2l6ZV90IEVsZW1lbnQ+CnN0cnVjdCBwcm9jZXNzX29uZQp7CiAgICBzdGF0aWMgY29uc3QgYm9vbCBpbl9yZW5kZXJfem9uZSA9IElkeCA8IFNpemU6OnNxdWFyZTsKICAgIHN0YXRpYyBjb25zdCBib29sIG5ld19saW5lID0gSWR4ID4gMCAmJiAoSWR4ICUgU2l6ZTo6d2lkdGggPT0gMCk7CiAgICBzdGF0aWMgY29uc3Qgc3RkOjpzdHJpbmcgdmFsdWU7Cn07Cgp0ZW1wbGF0ZTxzaXplX3QgSWQsIHNpemVfdCBJZHgsIGNsYXNzIFNpemUsIGNsYXNzIFJ1bGUsIHNpemVfdCBFbGVtZW50Pgpjb25zdCBzdGQ6OnN0cmluZyBwcm9jZXNzX29uZTxJZCwgSWR4LCBTaXplLCBSdWxlLCBFbGVtZW50Pjo6dmFsdWUgPSAoaW5fcmVuZGVyX3pvbmUpID8gKCgobmV3X2xpbmUpID8gKHN0ZDo6c3RyaW5nKCkgKyAnXG4nKSA6IHN0ZDo6c3RyaW5nKCkpICsgCiAgICAoKEVsZW1lbnQgIT0gMCkgPyBSdWxlOjpmb3JlZ3JvdW5kIDogUnVsZTo6YmFja2dyb3VuZCkpIDogc3RkOjpzdHJpbmcoKTsKCnRlbXBsYXRlPHNpemVfdCBJZCwgc2l6ZV90IElkeCwgY2xhc3MgU2l6ZSwgY2xhc3MgUnVsZSwgdW5zaWduZWQgY2hhciBCbG9jaz4Kc3RydWN0IHByb2Nlc3NfYmxvY2sKewogICAgc3RhdGljIGNvbnN0IHN0ZDo6c3RyaW5nIHZhbHVlOwp9OwoKdGVtcGxhdGU8c2l6ZV90IElkLCBzaXplX3QgSWR4LCBjbGFzcyBTaXplLCBjbGFzcyBSdWxlLCB1bnNpZ25lZCBjaGFyIEJsb2NrPgpjb25zdCBzdGQ6OnN0cmluZyBwcm9jZXNzX2Jsb2NrPElkLCBJZHgsIFNpemUsIFJ1bGUsIEJsb2NrPjo6dmFsdWUgPSAKICAgIHByb2Nlc3Nfb25lPElkLCBJZHgsIFNpemUsIFJ1bGUsIGdldF9lbGVtZW50PDAsIEJsb2NrPjo6dmFsdWU+Ojp2YWx1ZSArCiAgICBwcm9jZXNzX29uZTxJZCwgSWR4ICsgMSwgU2l6ZSwgUnVsZSwgZ2V0X2VsZW1lbnQ8MSwgQmxvY2s+Ojp2YWx1ZT46OnZhbHVlICsKICAgIHByb2Nlc3Nfb25lPElkLCBJZHggKyAyLCBTaXplLCBSdWxlLCBnZXRfZWxlbWVudDwyLCBCbG9jaz46OnZhbHVlPjo6dmFsdWUgKwogICAgcHJvY2Vzc19vbmU8SWQsIElkeCArIDMsIFNpemUsIFJ1bGUsIGdldF9lbGVtZW50PDMsIEJsb2NrPjo6dmFsdWU+Ojp2YWx1ZSArCiAgICBwcm9jZXNzX29uZTxJZCwgSWR4ICsgNCwgU2l6ZSwgUnVsZSwgZ2V0X2VsZW1lbnQ8NCwgQmxvY2s+Ojp2YWx1ZT46OnZhbHVlICsKICAgIHByb2Nlc3Nfb25lPElkLCBJZHggKyA1LCBTaXplLCBSdWxlLCBnZXRfZWxlbWVudDw1LCBCbG9jaz46OnZhbHVlPjo6dmFsdWUgKwogICAgcHJvY2Vzc19vbmU8SWQsIElkeCArIDYsIFNpemUsIFJ1bGUsIGdldF9lbGVtZW50PDYsIEJsb2NrPjo6dmFsdWU+Ojp2YWx1ZSArCiAgICBwcm9jZXNzX29uZTxJZCwgSWR4ICsgNywgU2l6ZSwgUnVsZSwgZ2V0X2VsZW1lbnQ8NywgQmxvY2s+Ojp2YWx1ZT46OnZhbHVlOwoKdGVtcGxhdGU8c2l6ZV90IElkLCBzaXplX3QgSWR4LCBjbGFzcyBTaXplLCBjbGFzcyBSdWxlLCB1bnNpZ25lZCBjaGFyLi4uIERhdGE+IHN0cnVjdCByZW5kZXI7Cgp0ZW1wbGF0ZTxzaXplX3QgSWQsIHNpemVfdCBJZHgsIGNsYXNzIFNpemUsIGNsYXNzIFJ1bGUsIHVuc2lnbmVkIGNoYXIgRmlyc3QsIHVuc2lnbmVkIGNoYXIuLi4gRGF0YT4Kc3RydWN0IHJlbmRlcjxJZCwgSWR4LCBTaXplLCBSdWxlLCBGaXJzdCwgRGF0YS4uLj4KewogICAgc3RhdGljIGNvbnN0IHN0ZDo6c3RyaW5nIHZhbHVlOwp9OwoKdGVtcGxhdGU8c2l6ZV90IElkLCBzaXplX3QgSWR4LCBjbGFzcyBTaXplLCBjbGFzcyBSdWxlLCB1bnNpZ25lZCBjaGFyIEZpcnN0LCB1bnNpZ25lZCBjaGFyLi4uIERhdGE+CmNvbnN0IHN0ZDo6c3RyaW5nIHJlbmRlcjxJZCwgSWR4LCBTaXplLCBSdWxlLCBGaXJzdCwgRGF0YS4uLj46OnZhbHVlID0gcHJvY2Vzc19ibG9jazxJZCwgSWR4LCBTaXplLCBSdWxlLCBGaXJzdD46OnZhbHVlICsKICAgIHJlbmRlcjxJZCwgSWR4ICsgOCwgU2l6ZSwgUnVsZSwgRGF0YS4uLj46OnZhbHVlOwoKdGVtcGxhdGU8c2l6ZV90IElkLCAgc2l6ZV90IElkeCwgY2xhc3MgU2l6ZSwgY2xhc3MgUnVsZSwgdW5zaWduZWQgY2hhciBMYXN0PgpzdHJ1Y3QgcmVuZGVyPElkLCBJZHgsIFNpemUsIFJ1bGUsIExhc3Q+CnsKICAgIHN0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyB2YWx1ZTsKfTsKCnRlbXBsYXRlPHNpemVfdCBJZCwgc2l6ZV90IElkeCwgY2xhc3MgU2l6ZSwgY2xhc3MgUnVsZSwgdW5zaWduZWQgY2hhciBMYXN0Pgpjb25zdCBzdGQ6OnN0cmluZyByZW5kZXI8SWQsIElkeCwgU2l6ZSwgUnVsZSwgTGFzdD46OnZhbHVlID0gcHJvY2Vzc19ibG9jazxJZCwgSWR4LCBTaXplLCBSdWxlLCBMYXN0Pjo6dmFsdWU7Cgp0ZW1wbGF0ZTxzaXplX3QgSWQsIHNpemVfdCBXaWR0aCwgY2xhc3MgUnVsZSwgdW5zaWduZWQgY2hhci4uLiBEYXRhPgpzdHJ1Y3Qgc2lsbHlfaW1nCnsKICAgIHN0YXRpYyBjb25zdCBzaXplX3Qgd2lkdGggPSBXaWR0aDsKICAgIHN0YXRpYyBjb25zdCBzaXplX3QgaGVpZ2h0ID0gKFdpZHRoID4gMCkgPyAoc2l6ZW9mLi4uKERhdGEpICogOCAvIFdpZHRoKSA6IDA7CiAgICBzdGF0aWMgY29uc3QgYm9vbCBpc192YWxpZCA9IHdpZHRoID4gMCAmJiBoZWlnaHQgPiAwOwogICAgc3RhdGljIGNvbnN0IHN0ZDo6c3RyaW5nIGRhdGE7CgogICAgc3RhdGljIHZvaWQgc2hvd19tZSgpCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8ICIoIiA8PCBJZCA8PCAiKSBTaXplOiAiIDw8IHdpZHRoIDw8ICIgeCAiIDw8IGhlaWdodCA8PCAiXG5cbiI7CiAgICAgICAgc3RkOjpjb3V0IDw8IGRhdGE7CiAgICB9Cn07Cgp0ZW1wbGF0ZTxzaXplX3QgSWQsIHNpemVfdCBXaWR0aCwgY2xhc3MgUnVsZSwgdW5zaWduZWQgY2hhci4uLiBEYXRhPgpjb25zdCBzdGQ6OnN0cmluZyBzaWxseV9pbWc8SWQsIFdpZHRoLCBSdWxlLCBEYXRhLi4uPjo6ZGF0YSA9IHN0ZDo6c3RyaW5nKCkgKyAKICAgIHN0ZDo6Y29uZGl0aW9uYWw8IGlzX3ZhbGlkLCByZW5kZXI8SWQsIDAsIHJlc3VsdF9zaXplPHdpZHRoLCBoZWlnaHQ+LCBSdWxlLCBEYXRhLi4uPiwgZW1wdHlfcmVzdWx0Pjo6dHlwZTo6dmFsdWU7CgppbnQgbWFpbigpCnsKICAgIHNpbGx5X2ltZzwwLCAxMSwgcmVuZGVyX3J1bGU8JyQnLCAnICc+LCAweDMxLCAweDhGLCAweDdCLCAweEZGLCAweEZGLCAweEYzLCAweEY4LCAweDFDLCAweDAxLCAweDAwPjo6c2hvd19tZSgpOwogICAgc3RkOjpjb3V0IDw8ICJcblxuIjsKICAgIHNpbGx5X2ltZzwxLCAxNSwgcmVuZGVyX3J1bGU8JyMnLCAnLic+LCAweDMxLCAweDg0LCAweEY3LCAweDlGLCAweEZGLCAweDk3LCAweEZGLCAweDAzLCAweEY4LCAweDgxLCAweEMzLCAweDgxLCAweDAyLCAweDAwPjo6c2hvd19tZSgpOwogICAgc3RkOjpjb3V0IDw8ICJcblxuIjsKICAgIHNpbGx5X2ltZzwyLCAxNSwgcmVuZGVyX3J1bGU8JyonLCAnICc+LCAweDNGLCAweEU0LCAweEZGLCAweDlGLCAweEMwLCAweDE3LCAweDgwLCAweDBGLCAweDAwLCAweDhGLCAweEYzLCAweDhGLCAweEYyLCAweDAwPjo6c2hvd19tZSgpOwp9Cg==