fork download
  1. #include <iostream>
  2.  
  3. namespace auto_list_exploit {
  4. static auto li = {1,2};
  5. using initializer_list = decltype(li);
  6. }
  7.  
  8. template <typename CT=char>
  9. class TextSurface {
  10. using initializer_list = auto_list_exploit::initializer_list;
  11. public:
  12. struct point {
  13. int x,y;
  14. point(int x=0, int y=0) : x(x), y(y) {}
  15. point(initializer_list list) : x((list.begin())[0]), y((list.begin())[1]) {}
  16. };
  17. private:
  18. int m_width, m_height, m_data_count;
  19. CT* m_data;
  20.  
  21. int OffsetOf(int x, int y) const { return y * m_width + x; }
  22. bool IsInside(int x, int y) { return x >= 0 && y>= 0 && x < m_width && y < m_height; }
  23. CT& at(int x, int y) { return m_data[OffsetOf(x,y)]; }
  24. CT at(int x, int y) const { return m_data[OffsetOf(x,y)]; }
  25.  
  26. int Abs(int x) { return x < 0 ? -x : x; }
  27.  
  28. void Poly(const point& pfirst, CT value, const point& plast) {
  29. Line(plast, pfirst, value);
  30. }
  31. template <typename ...Ts>
  32. void Poly(const point& pfirst, CT value, const point& p0, const point& p1, Ts...args) {
  33. Line(p0, p1, value);
  34. Poly(pfirst, value, p1, args...);
  35. }
  36. public:
  37. TextSurface(int width=0, int height=0) :
  38. m_width(height ? width : 0),
  39. m_height(width ? height : 0),
  40. m_data_count(width * height)
  41. {
  42. m_data = m_data_count ? new CT[m_data_count] : nullptr;
  43. Clear();
  44. }
  45. // Cannot copy
  46. TextSurface(const TextSurface&) =delete;
  47. TextSurface& operator = (const TextSurface&) =delete;
  48. // Can return from functions
  49. TextSurface& operator = (TextSurface&& src) {
  50. delete [] m_data;
  51. m_width = src.m_width; m_height = src.m_height; m_data_count = src.m_data_count;
  52. m_data = src.m_data;
  53. src.m_data = nullptr;
  54. return *this;
  55. }
  56. TextSurface(TextSurface&& src) : m_data(nullptr) { operator = ((TextSurface&&)src); }
  57. ~TextSurface() { delete [] m_data; }
  58.  
  59. int Width() const { return m_width; }
  60. int Height() const { return m_height; }
  61. void Clear(CT value=' ') {
  62. CT* p = m_data;
  63. CT* pe = p + m_data_count;
  64. while(p != pe) *(p++) = value;
  65. }
  66. void Line(int x0, int y0, int x1, int y1, CT value) {
  67. const int dx = x1-x0;
  68. const int dy = y1-y0;
  69. if(!dx && !dy) {
  70. if(IsInside(x0, y0)) { at(x0, y0) = value; }
  71. return;
  72. }
  73. const bool ymajor = Abs(dy) > Abs(dx);
  74. int x=x0, y=y0;
  75. int &mj = ymajor ? y : x;
  76. int &mn = ymajor ? x : y;
  77. const int mje = ymajor ? y1 : x1;
  78. const int mjst = mj < mje ? 1 : -1;
  79. double mnd = mn;
  80. double mnst = ymajor ? double(dx)/Abs(dy) : double(dy)/Abs(dx);
  81. do {
  82. mn = int(mnd + 0.5);
  83. if(IsInside(x,y)) { at(x,y) = value; }
  84. mj += mjst;
  85. mnd += mnst;
  86. } while(mj != mje+mjst);
  87. }
  88. void Line(const point& p0, const point& p1, CT value) { Line(p0.x, p0.y, p1.x, p1.y, value); }
  89.  
  90. template <typename ...Ts>
  91. void Poly(CT value, const point& p0, const point& p1, Ts...args) {
  92. Line(p0, p1, value);
  93. Poly(p0, value, p1, args...);
  94. }
  95. // init-list overloads for triangle and quad (initializer_list can't be packed)
  96. void Poly(CT value, initializer_list l0, initializer_list l1, initializer_list l2) { Poly(value, point(l0), point(l1), point(l2)); }
  97. void Poly(CT value, initializer_list l0, initializer_list l1, initializer_list l2, initializer_list l3) { Poly(value, point(l0), point(l1), point(l2), point(l3)); }
  98.  
  99. void Rect(int x, int y, int width, int height, CT value) {
  100. Poly(value, point(x,y), point(x+width-1, y), point(x+width-1, y+height-1), point(x, y+height-1));
  101. }
  102. // Label places text. xloc selects the meaning of the x coordinate.
  103. // Its value is between -1 and 1: -1 for x at the left of the text,
  104. // 0 for x in the middle, and 1 for x at the end of the text.
  105. void Label(const CT* text, int x, int y, double xloc=-1) {
  106. int len = 0;
  107. while(text[len]) { ++len; }
  108. x -= int((xloc + 1)/2 * (len - 1));
  109. for(int i=0; i<len; ++i) {
  110. if(IsInside(x,y)) { at(x,y) = text[i]; }
  111. ++x;
  112. } }
  113. void Present() const {
  114. const CT* p = m_data;
  115. for(int j=0; j<m_height; ++j) {
  116. std::cout.write(p, m_width);
  117. std::cout << '\n';
  118. p += m_width;
  119. } }
  120. };
  121.  
  122. typedef TextSurface<char> CharSurface;
  123.  
  124. int main() {
  125. CharSurface surf(60,20);
  126. surf.Poly('*', {20,2}, {34,16}, {20,16});
  127. surf.Label("14 ft", 18, 10, 1);
  128. surf.Label("9 ft", 26, 17, 0);
  129. surf.Present();
  130. }
Success #stdin #stdout 0s 3456KB
stdin
Standard input is empty
stdout
                                                            
                                                            
                    *                                       
                    **                                      
                    * *                                     
                    *  *                                    
                    *   *                                   
                    *    *                                  
                    *     *                                 
                    *      *                                
              14 ft *       *                               
                    *        *                              
                    *         *                             
                    *          *                            
                    *           *                           
                    *            *                          
                    ***************                         
                         9 ft