fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <type_traits>
  4.  
  5. struct empty_result
  6. {
  7. static const std::string value;
  8. };
  9.  
  10. template<size_t Width, size_t Height>
  11. struct result_size
  12. {
  13. static const size_t width = Width;
  14. static const size_t height = Height;
  15. static const size_t square = Width * Height;
  16. };
  17.  
  18. template<char Foreground, char Background>
  19. struct render_rule
  20. {
  21. static const char background = Background;
  22. static const char foreground = Foreground;
  23. };
  24.  
  25. const std::string empty_result::value;
  26.  
  27. template<size_t Idx, unsigned char Block>
  28. struct get_element
  29. {
  30. static const size_t value = ((Block & ((Idx < 4) ? 0xF0 : 0x0F)) >> (7 - Idx)) & 1;
  31. };
  32.  
  33. template<size_t Id, size_t Idx, class Size, class Rule, size_t Element>
  34. struct process_one
  35. {
  36. static const bool in_render_zone = Idx < Size::square;
  37. static const bool new_line = Idx > 0 && (Idx % Size::width == 0);
  38. static const std::string value;
  39. };
  40.  
  41. template<size_t Id, size_t Idx, class Size, class Rule, size_t Element>
  42. const std::string process_one<Id, Idx, Size, Rule, Element>::value = (in_render_zone) ? (((new_line) ? (std::string() + '\n') : std::string()) +
  43. ((Element != 0) ? Rule::foreground : Rule::background)) : std::string();
  44.  
  45. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
  46. struct process_block
  47. {
  48. static const std::string value;
  49. };
  50.  
  51. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
  52. const std::string process_block<Id, Idx, Size, Rule, Block>::value =
  53. process_one<Id, Idx, Size, Rule, get_element<0, Block>::value>::value +
  54. process_one<Id, Idx + 1, Size, Rule, get_element<1, Block>::value>::value +
  55. process_one<Id, Idx + 2, Size, Rule, get_element<2, Block>::value>::value +
  56. process_one<Id, Idx + 3, Size, Rule, get_element<3, Block>::value>::value +
  57. process_one<Id, Idx + 4, Size, Rule, get_element<4, Block>::value>::value +
  58. process_one<Id, Idx + 5, Size, Rule, get_element<5, Block>::value>::value +
  59. process_one<Id, Idx + 6, Size, Rule, get_element<6, Block>::value>::value +
  60. process_one<Id, Idx + 7, Size, Rule, get_element<7, Block>::value>::value;
  61.  
  62. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char... Data> struct render;
  63.  
  64. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
  65. struct render<Id, Idx, Size, Rule, First, Data...>
  66. {
  67. static const std::string value;
  68. };
  69.  
  70. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
  71. const std::string render<Id, Idx, Size, Rule, First, Data...>::value = process_block<Id, Idx, Size, Rule, First>::value +
  72. render<Id, Idx + 8, Size, Rule, Data...>::value;
  73.  
  74. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
  75. struct render<Id, Idx, Size, Rule, Last>
  76. {
  77. static const std::string value;
  78. };
  79.  
  80. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
  81. const std::string render<Id, Idx, Size, Rule, Last>::value = process_block<Id, Idx, Size, Rule, Last>::value;
  82.  
  83. template<size_t Id, size_t Width, class Rule, unsigned char... Data>
  84. struct silly_img
  85. {
  86. static const size_t width = Width;
  87. static const size_t height = (Width > 0) ? (sizeof...(Data) * 8 / Width) : 0;
  88. static const bool is_valid = width > 0 && height > 0;
  89. static const std::string data;
  90.  
  91. static void show_me()
  92. {
  93. std::cout << "(" << Id << ") Size: " << width << " x " << height << "\n\n";
  94. std::cout << data;
  95. }
  96. };
  97.  
  98. template<size_t Id, size_t Width, class Rule, unsigned char... Data>
  99. const std::string silly_img<Id, Width, Rule, Data...>::data = std::string() +
  100. std::conditional< is_valid, render<Id, 0, result_size<width, height>, Rule, Data...>, empty_result>::type::value;
  101.  
  102. int main()
  103. {
  104. silly_img<0, 11, render_rule<'$', ' '>, 0x31, 0x8F, 0x7B, 0xFF, 0xFF, 0xF3, 0xF8, 0x1C, 0x01, 0x00>::show_me();
  105. std::cout << "\n\n";
  106. silly_img<1, 15, render_rule<'#', '.'>, 0x31, 0x84, 0xF7, 0x9F, 0xFF, 0x97, 0xFF, 0x03, 0xF8, 0x81, 0xC3, 0x81, 0x02, 0x00>::show_me();
  107. std::cout << "\n\n";
  108. silly_img<2, 15, render_rule<'*', ' '>, 0x3F, 0xE4, 0xFF, 0x9F, 0xC0, 0x17, 0x80, 0x0F, 0x00, 0x8F, 0xF3, 0x8F, 0xF2, 0x00>::show_me();
  109. }
  110.  
Success #stdin #stdout 0s 3092KB
stdin
Standard input is empty
stdout
(0) Size: 11 x 7

  $$   $$  
 $$$$ $$$$ 
$$$$$$$$$$$
$$$$$$$$$$$
  $$$$$$$  
    $$$    
     $     

(1) Size: 15 x 7

..##...##....#.
.####.####..###
###########..#.
###########....
..#######...#..
....###....###.
.....#......#..

(2) Size: 15 x 7

  *********  * 
 *********  ***
****         * 
****           
****        *  
 ********  *** 
  ********  *