fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <type_traits>
  4.  
  5. namespace mu
  6. {
  7. namespace index_list
  8. {
  9. template<size_t... Indices>
  10. struct index_list
  11. {
  12. template<size_t N>
  13. using append = index_list<Indices..., N>;
  14.  
  15. static constexpr size_t size()
  16. {
  17. return sizeof...(Indices);
  18. }
  19. };
  20.  
  21. template<size_t Size>
  22. struct make_index_list
  23. {
  24. typedef typename make_index_list<Size-1>::type::template append<Size-1> type;
  25. };
  26.  
  27. template<>
  28. struct make_index_list<0u>
  29. {
  30. typedef index_list<> type;
  31. };
  32.  
  33. template<typename... Ts>
  34. using to_index_list = typename make_index_list<sizeof...(Ts)>::type;
  35. }
  36.  
  37. namespace il = index_list;
  38. }
  39.  
  40. struct empty_result
  41. {
  42. static const std::string value;
  43. };
  44.  
  45. const std::string empty_result::value;
  46.  
  47.  
  48. template<size_t Width, size_t Height>
  49. struct result_size
  50. {
  51. static constexpr size_t width = Width;
  52. static constexpr size_t height = Height;
  53. static constexpr size_t square = Width * Height;
  54. };
  55.  
  56. template<char Foreground, char Background>
  57. struct render_rule
  58. {
  59. static constexpr char background = Background;
  60. static constexpr char foreground = Foreground;
  61. };
  62.  
  63. template<size_t Idx, unsigned char Block>
  64. struct get_element
  65. {
  66. static constexpr size_t value = ((Block & ((Idx < 4) ? 0xF0 : 0x0F)) >> (7 - Idx)) & 1;
  67. };
  68.  
  69. template<size_t Id, size_t Idx, class Size, class Rule, size_t Element>
  70. struct process_one
  71. {
  72. static constexpr bool in_render_zone = Idx < Size::square;
  73. static constexpr bool new_line = Idx > 0 && (Idx % Size::width == 0);
  74. static const std::string value;
  75. };
  76.  
  77. template<size_t Id, size_t Idx, class Size, class Rule, size_t Element>
  78. const std::string process_one<Id, Idx, Size, Rule, Element>::value = (in_render_zone) ? (((new_line) ? (std::string() + '\n') : std::string()) +
  79. ((Element != 0) ? Rule::foreground : Rule::background)) : std::string();
  80.  
  81.  
  82. /*
  83. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
  84. struct process_block
  85. {
  86.   static const std::string value;
  87. };
  88.  
  89. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
  90. const std::string process_block<Id, Idx, Size, Rule, Block>::value =
  91.   process_one<Id, Idx, Size, Rule, get_element<0, Block>::value>::value +
  92.   process_one<Id, Idx + 1, Size, Rule, get_element<1, Block>::value>::value +
  93.   process_one<Id, Idx + 2, Size, Rule, get_element<2, Block>::value>::value +
  94.   process_one<Id, Idx + 3, Size, Rule, get_element<3, Block>::value>::value +
  95.   process_one<Id, Idx + 4, Size, Rule, get_element<4, Block>::value>::value +
  96.   process_one<Id, Idx + 5, Size, Rule, get_element<5, Block>::value>::value +
  97.   process_one<Id, Idx + 6, Size, Rule, get_element<6, Block>::value>::value +
  98.   process_one<Id, Idx + 7, Size, Rule, get_element<7, Block>::value>::value;
  99. */
  100.  
  101. template<template <size_t> class T, size_t... Indices> struct summa;
  102.  
  103. template<template <size_t> class T, size_t Index, size_t... Indices>
  104. struct summa<T, Index, Indices...>
  105. {
  106. static const decltype(T<Index>::value) value;
  107. };
  108.  
  109. template<template <size_t> class T, size_t Index, size_t... Indices>
  110. const decltype(T<Index>::value) summa<T, Index, Indices...>::value = T<Index>::value + summa<T, Indices...>::value;
  111.  
  112. template<template <size_t> class T, size_t Index>
  113. struct summa<T, Index>
  114. {
  115. static const decltype(T<Index>::value) value;
  116. };
  117.  
  118. template<template <size_t> class T, size_t Index>
  119. const decltype(T<Index>::value) summa<T, Index>::value = T<Index>::value;
  120.  
  121. /*
  122.  
  123. template<Signature>
  124. struct summa
  125. {
  126.   static switch (template Signature)
  127.   {
  128.   case template <size_t> class T, size_t Index, size_t... Indices:
  129.   static constexpr auto value = T<Index>::value + summa<T, Indices...>::value;
  130.   break;
  131.   case template <size_t> class T, size_t Index:
  132.   static constexpr auto value = T<Index>::value;
  133.   break;
  134.   default:;
  135.   }
  136. };
  137.  
  138. template<template <size_t> class T, size_t Index, size_t... Indices>
  139. struct summa<T, Index, Indices...>
  140. {
  141.   static if (sizeof...(Indices) > 0)
  142.   static constexpr auto value = T<Index>::value + summa<T, Indices...>::value;
  143.   else
  144.   static constexpr auto value = T<Index>::value;
  145. };
  146.  
  147. */
  148. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
  149. struct process_block_
  150. {
  151. template<size_t N>
  152. using process_one_ = process_one<Id, Idx + N, Size, Rule, get_element<N, Block>::value>;
  153.  
  154. template<size_t... Indices>
  155. static constexpr auto run(const mu::il::index_list<Indices...>&) -> decltype(summa<process_one_, Indices...>::value)
  156. {
  157. return summa<process_one_, Indices...>::value;
  158. }
  159.  
  160. static const std::string value;
  161. };
  162.  
  163. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block>
  164. const std::string process_block_<Id, Idx, Size, Rule, Block>::value = process_block_<Id, Idx, Size, Rule, Block>::template run(mu::il::make_index_list<8>::type());
  165.  
  166. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char... Data> struct render;
  167.  
  168. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
  169. struct render<Id, Idx, Size, Rule, First, Data...>
  170. {
  171. static const std::string value;
  172. };
  173.  
  174. /*
  175. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
  176. const std::string render<Id, Idx, Size, Rule, First, Data...>::value = process_block<Id, Idx, Size, Rule, First>::value +
  177.   render<Id, Idx + 8, Size, Rule, Data...>::value;
  178. */
  179.  
  180. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
  181. const std::string render<Id, Idx, Size, Rule, First, Data...>::value = process_block_<Id, Idx, Size, Rule, First>::value +
  182. render<Id, Idx + 8, Size, Rule, Data...>::value;
  183.  
  184. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
  185. struct render<Id, Idx, Size, Rule, Last>
  186. {
  187. static const std::string value;
  188. };
  189.  
  190. /*
  191. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
  192. const std::string render<Id, Idx, Size, Rule, Last>::value = process_block<Id, Idx, Size, Rule, Last>::value;
  193. */
  194.  
  195. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
  196. const std::string render<Id, Idx, Size, Rule, Last>::value = process_block_<Id, Idx, Size, Rule, Last>::value;
  197.  
  198.  
  199. template<size_t Id, size_t Width, class Rule, unsigned char... Data>
  200. struct silly_img
  201. {
  202. static constexpr size_t width = Width;
  203. static constexpr size_t height = (Width > 0) ? (sizeof...(Data) * 8 / Width) : 0;
  204. static constexpr bool is_valid = width > 0 && height > 0;
  205. static const std::string data;
  206.  
  207. static void show_me()
  208. {
  209. std::cout << "(" << Id << ") Size: " << width << " x " << height << "\n\n";
  210. std::cout << data;
  211. }
  212. };
  213.  
  214. template<size_t Id, size_t Width, class Rule, unsigned char... Data>
  215. const std::string silly_img<Id, Width, Rule, Data...>::data = std::string() +
  216. std::conditional< is_valid, render<Id, 0, result_size<width, height>, Rule, Data...>, empty_result>::type::value;
  217.  
  218. int main()
  219. {
  220. silly_img<0, 11, render_rule<'$', ' '>, 0x31, 0x8F, 0x7B, 0xFF, 0xFF, 0xF3, 0xF8, 0x1C, 0x01, 0x00>::show_me();
  221. std::cout << "\n\n";
  222. silly_img<1, 15, render_rule<'#', '.'>, 0x31, 0x84, 0xF7, 0x9F, 0xFF, 0x97, 0xFF, 0x03, 0xF8, 0x81, 0xC3, 0x81, 0x02, 0x00>::show_me();
  223. std::cout << "\n\n";
  224. silly_img<2, 15, render_rule<'*', ' '>, 0x3F, 0xE4, 0xFF, 0x9F, 0xC0, 0x17, 0x80, 0x0F, 0x00, 0x8F, 0xF3, 0x8F, 0xF2, 0x00>::show_me();
  225. }
  226.  
Success #stdin #stdout 0s 3068KB
stdin
Standard input is empty
stdout
(0) Size: 11 x 7

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

(1) Size: 15 x 7

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

(2) Size: 15 x 7

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