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> struct IndexList
  10. {
  11. template<size_t N> using append = IndexList<Indices..., N>;
  12.  
  13. static constexpr size_t size() {
  14. return sizeof...(Indices);
  15. }
  16. };
  17.  
  18. template<size_t Size> struct IndexListMaker {
  19. typedef typename IndexListMaker<Size-1>::type::template append<Size-1> type;
  20. };
  21.  
  22. template<> struct IndexListMaker<0u> {
  23. typedef IndexList<> type;
  24. };
  25.  
  26. template<typename... Ts> using toIndexList = typename IndexListMaker<sizeof...(Ts)>::type;
  27. }
  28.  
  29. namespace il = index_list;
  30. }
  31.  
  32. struct EmptyResult {
  33. static const std::string value;
  34. };
  35.  
  36. const std::string EmptyResult::value;
  37.  
  38. template<size_t Width, size_t Height> struct ResultSize {
  39. static constexpr size_t width = Width;
  40. static constexpr size_t height = Height;
  41. static constexpr size_t square = Width * Height;
  42. };
  43.  
  44. template<char Foreground, char Background> struct RenderRule {
  45. static constexpr char background = Background;
  46. static constexpr char foreground = Foreground;
  47. };
  48.  
  49. template<size_t Idx, unsigned char Block> struct GetElement {
  50. static constexpr size_t value = ((Block & ((Idx < 4u) ? 0xF0u : 0x0Fu)) >> (7u - Idx)) & 1u;
  51. };
  52.  
  53. template<size_t Id, size_t Idx, class Size, class Rule, size_t Element> struct OneElementProcessor {
  54. static constexpr bool inRenderZone = Idx < Size::square;
  55. static constexpr bool needNewLine = Idx > 0 && (Idx % Size::width == 0u);
  56. static const std::string value;
  57. };
  58.  
  59. template<size_t Id, size_t Idx, class Size, class Rule, size_t Element>
  60. const std::string OneElementProcessor<Id, Idx, Size, Rule, Element>::value = (inRenderZone) ? (((needNewLine) ? (std::string() + '\n') : std::string()) +
  61. ((Element != 0u) ? Rule::foreground : Rule::background)) : std::string();
  62.  
  63. template<template <size_t> class T, size_t... Indices> struct Summa;
  64.  
  65. template<template <size_t> class T, size_t Index, size_t... Indices> struct Summa<T, Index, Indices...> {
  66. static const decltype(T<Index>::value) value;
  67. };
  68.  
  69. template<template <size_t> class T, size_t Index, size_t... Indices>
  70. const decltype(T<Index>::value) Summa<T, Index, Indices...>::value = T<Index>::value + Summa<T, Indices...>::value;
  71.  
  72. template<template <size_t> class T, size_t Index> struct Summa<T, Index> {
  73. static const decltype(T<Index>::value) value;
  74. };
  75.  
  76. template<template <size_t> class T, size_t Index>
  77. const decltype(T<Index>::value) Summa<T, Index>::value = T<Index>::value;
  78.  
  79. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Block> struct BlockProcessor {
  80. template<size_t N> using processOne = OneElementProcessor<Id, Idx + N, Size, Rule, GetElement<N, Block>::value>;
  81.  
  82. template<size_t... Indices> static constexpr auto run(const mu::il::IndexList<Indices...>&) {
  83. return Summa<processOne, Indices...>::value;
  84. }
  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 BlockProcessor<Id, Idx, Size, Rule, Block>::value = BlockProcessor<Id, Idx, Size, Rule, Block>::template run(mu::il::IndexListMaker<8>::type());
  91.  
  92. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char... Data> struct Render;
  93.  
  94. 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...> {
  95. static const std::string value;
  96. };
  97.  
  98. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char First, unsigned char... Data>
  99. const std::string Render<Id, Idx, Size, Rule, First, Data...>::value = BlockProcessor<Id, Idx, Size, Rule, First>::value +
  100. Render<Id, Idx + 8, Size, Rule, Data...>::value;
  101.  
  102. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last> struct Render<Id, Idx, Size, Rule, Last> {
  103. static const std::string value;
  104. };
  105.  
  106. template<size_t Id, size_t Idx, class Size, class Rule, unsigned char Last>
  107. const std::string Render<Id, Idx, Size, Rule, Last>::value = BlockProcessor<Id, Idx, Size, Rule, Last>::value;
  108.  
  109. template<size_t Id, size_t Width, class Rule, unsigned char... Data> struct SillyImage {
  110. static constexpr size_t width = Width;
  111. static constexpr size_t height = (Width > 0) ? (sizeof...(Data) * 8 / Width) : 0;
  112. static constexpr bool is_valid = width > 0 && height > 0;
  113. static const std::string data;
  114.  
  115. static void showMe() {
  116. std::cout << "(" << Id << ") Size: " << width << " x " << height << "\n\n";
  117. std::cout << data;
  118. }
  119. };
  120.  
  121. template<size_t Id, size_t Width, class Rule, unsigned char... Data>
  122. const std::string SillyImage<Id, Width, Rule, Data...>::data = std::string() +
  123. std::conditional< is_valid, Render<Id, 0, ResultSize<width, height>, Rule, Data...>, EmptyResult>::type::value;
  124.  
  125. int main() {
  126. SillyImage<0, 11, RenderRule<'$', ' '>, 0x31, 0x8F, 0x7B, 0xFF, 0xFF, 0xF3, 0xF8, 0x1C, 0x01, 0x00>::showMe();
  127. std::cout << "\n\n";
  128. SillyImage<1, 15, RenderRule<'#', '.'>, 0x31, 0x84, 0xF7, 0x9F, 0xFF, 0x97, 0xFF, 0x03, 0xF8, 0x81, 0xC3, 0x81, 0x02, 0x00>::showMe();
  129. std::cout << "\n\n";
  130. SillyImage<2, 15, RenderRule<'*', ' '>, 0x3F, 0xE4, 0xFF, 0x9F, 0xC0, 0x17, 0x80, 0x0F, 0x00, 0x8F, 0xF3, 0x8F, 0xF2, 0x00>::showMe();
  131. }
  132.  
Success #stdin #stdout 0s 3356KB
stdin
Standard input is empty
stdout
(0) Size: 11 x 7

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

(1) Size: 15 x 7

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

(2) Size: 15 x 7

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