Advertisement
Guest User

Сопрограммы на C++

a guest
Apr 27th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.52 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3.  
  4. class CharIter {
  5. public:
  6.   virtual ~CharIter() {}
  7.  
  8.   virtual char next() = 0;
  9. };
  10.  
  11. class SimpleChain: public CharIter {
  12. public:
  13.   SimpleChain(const char *str)
  14.     : m_str(str)
  15.   {
  16.     /* пусто */
  17.   }
  18.  
  19.   virtual char next() {
  20.     char result = *m_str;
  21.     if (result) {
  22.       ++ m_str;
  23.     }
  24.     return result;
  25.   }
  26.  
  27. private:
  28.   const char *m_str;
  29. };
  30.  
  31. #define YIELD_RETURN(point, value) \
  32.   m_state = point; \
  33.   return (value); \
  34.   case point:
  35.  
  36. class RLEDecode: public CharIter {
  37. public:
  38.   RLEDecode(CharIter *src)
  39.     : m_src(src)
  40.     , m_state(Start)
  41.   {
  42.     /* пусто */
  43.   }
  44.  
  45.   virtual char next();
  46.  
  47. private:
  48.   CharIter *m_src;
  49.  
  50.   enum State {
  51.     Start, Normal, Repeat, End
  52.   };
  53.   State m_state;
  54.  
  55.   char m_current;
  56.   int m_repeat;
  57. };
  58.  
  59. char RLEDecode::next() {
  60.   switch (m_state) {
  61.     case Start:
  62.     while (m_current = m_src->next(), m_current != '\0') {
  63.       if (m_current == '!') {
  64.         m_repeat = (unsigned char) m_src->next();
  65.         m_current = m_src->next();
  66.         while (m_repeat > 0) {
  67.           YIELD_RETURN(Repeat, m_current);
  68.           --m_repeat;
  69.         }
  70.       } else {
  71.         YIELD_RETURN(Normal, m_current);
  72.       }
  73.     }
  74.  
  75.     while (true) {
  76.       YIELD_RETURN(End, '\0');
  77.     }
  78.   }
  79.  
  80.   // компилятор ругается
  81.   return '\0';
  82. }
  83.  
  84. class Wrapper: public CharIter {
  85. public:
  86.   Wrapper(CharIter *src, int width)
  87.     : m_src(src)
  88.     , m_width(width)
  89.     , m_state(Start)
  90.   {
  91.     /* пусто */;
  92.   }
  93.  
  94.   virtual char next();
  95.  
  96. private:
  97.   CharIter *m_src;
  98.   int m_width;
  99.  
  100.   enum State {
  101.     Start, InLine, NewLine, End
  102.   };
  103.   State m_state;
  104.  
  105.   char m_current;
  106.   int m_col;
  107. };
  108.  
  109. char Wrapper::next() {
  110.   switch (m_state) {
  111.     case Start:
  112.     m_current = m_src->next();
  113.     while (m_current != '\0') {
  114.       for (
  115.         m_col = 0;
  116.         m_col < m_width && m_current != '\0';
  117.         ++m_col, m_current = m_src->next()
  118.       ) {
  119.         YIELD_RETURN(InLine, m_current);
  120.       }
  121.       YIELD_RETURN(NewLine, '\n');
  122.     }
  123.  
  124.     while (true) {
  125.       YIELD_RETURN(End, '\0');
  126.     }
  127.   }
  128.  
  129.   // компилятор ругается
  130.   return '\0';
  131. }
  132.  
  133. int main() {
  134.   const char *string =
  135.     "12345678901234567890"
  136.     "Hello, ten of A: !\12A, one bang: !\1!, 64 of x: !\100x.";
  137.  
  138.   SimpleChain source(string);
  139.   RLEDecode rle(&source);
  140.   Wrapper wrapper(&rle, 20);
  141.  
  142.   char current;
  143.   while (current = wrapper.next(), current != '\0') {
  144.     printf("%c", current);
  145.   }
  146.  
  147.   return 0;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement