Guest User

Untitled

a guest
Oct 2nd, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.08 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <functional>
  6. #include <cassert>
  7.  
  8.  
  9. void displayMessage();
  10. enum ESentenceType {
  11.     eStatement,
  12.     eExclamation,
  13.     sQuestion,
  14.     eCommand
  15. };
  16.  
  17. class nonCopyable {
  18. protected:
  19.     nonCopyable() {
  20.     }
  21.  
  22.     ~nonCopyable() {
  23.     }
  24.  
  25. private:
  26.     nonCopyable(const nonCopyable&);
  27.     const nonCopyable& operator=(const nonCopyable&);
  28. };
  29.  
  30. inline char getPunctionMark(ESentenceType sentenceType) {
  31.     char puncMark = '.';
  32.     switch(sentenceType) {
  33.         case eStatement  : puncMark = '.'; break;
  34.         case eExclamation: puncMark = '!'; break;
  35.         case sQuestion   : puncMark = '?'; break;
  36.         case eCommand    : puncMark = '.'; break;
  37.         default: {
  38.             // should never get here
  39.             assert(false);
  40.         }
  41.     }
  42.     return puncMark;
  43. }
  44.  
  45. template<typename TElem>
  46. class Creatable {
  47. protected:
  48.     Creatable() {
  49.     }
  50.  
  51.     virtual ~Creatable() {
  52.         clear();
  53.     }
  54.  
  55. public:
  56.     static TElem* create() {
  57.         TElem* e = new TElem;
  58.         return e;
  59.     }
  60.  
  61.     void free() {
  62.         delete this;
  63.     }
  64.  
  65.     virtual void clear() {
  66.     }
  67. };
  68.  
  69. template<typename TElem, typename TParam>
  70. class CreatableParam {
  71. protected:
  72.     CreatableParam() {
  73.     }
  74.  
  75.     virtual ~CreatableParam() {
  76.     }
  77.  
  78. public:
  79.     static TElem* create(TParam p) {
  80.         TElem* e = new TElem;
  81.         e->initialize(p);
  82.         return e;
  83.     }
  84.  
  85.     void free() {
  86.         finalize();
  87.         delete this;
  88.     }
  89.  
  90.     virtual void initialize(TParam /*p*/) {
  91.     }
  92.  
  93.     virtual void finalize() {
  94.         clear();
  95.     }
  96.  
  97.     virtual void clear() {
  98.     }
  99. };
  100.  
  101. class DisplayElem
  102. : public nonCopyable {
  103. protected:
  104.     DisplayElem() {
  105.     }
  106.  
  107.     virtual ~DisplayElem() {
  108.     }
  109.  
  110. public:
  111.     virtual void display(std::ostream& os) const = 0;
  112. };
  113.  
  114. class Displayer
  115. : public std::unary_function<void, const DisplayElem*> {
  116. private:
  117.     std::ostream& m_os;
  118.     char   m_sep;
  119.     size_t m_count;
  120.  
  121. public:
  122.     Displayer(std::ostream& os, char sep = '\0')
  123.     : m_os(os)
  124.     , m_sep(sep)
  125.     , m_count(0) {
  126.     }
  127.  
  128.     ~Displayer() {
  129.     }
  130.  
  131.     void operator()(const DisplayElem* e) {
  132.         if(('\0' != m_sep) && (0 < m_count)) {
  133.             m_os << m_sep;
  134.         }
  135.         e->display(m_os);
  136.         ++m_count;
  137.     }
  138. };
  139.  
  140. template <typename TElem>
  141. class Freer
  142. : public std::unary_function<void, TElem*> {
  143. public:
  144.     void operator()(TElem* e) {
  145.         e->free();
  146.     }
  147. };
  148.  
  149.  
  150. class Letter
  151. : public DisplayElem
  152. , public CreatableParam<Letter, char> {
  153. private:
  154.     char m_ch;
  155.  
  156. protected:
  157.     /*virtual*/ ~Letter() {
  158.     }
  159.  
  160. public:
  161.     Letter() : m_ch('\0') {
  162.     }
  163.  
  164.     void initialize(char ch) {
  165.         m_ch = ch;
  166.     }
  167.  
  168.     void finalize() {
  169.         m_ch = '\0';
  170.     }
  171.  
  172.     void display(std::ostream& os) const {
  173.         os << m_ch;
  174.         // no endLetter()
  175.     }
  176. };
  177.  
  178. class Word
  179. : public DisplayElem
  180. , public Creatable<Word> {
  181. private:
  182.     std::vector<Letter*> m_letters;
  183.  
  184. protected:
  185.     /*virtual*/ ~Word() {
  186.         clear();
  187.     }
  188.  
  189. public:
  190.     Word() {
  191.     }
  192.  
  193.     void clear() {
  194.         std::for_each(m_letters.begin(), m_letters.end(), Freer<Letter>());
  195.         m_letters.clear();
  196.     }
  197.  
  198.     void addLetter(Letter* s) {
  199.         m_letters.push_back(s);
  200.     }
  201.  
  202.     /*virtual*/ void display(std::ostream& os) const {
  203.         std::for_each(m_letters.begin(), m_letters.end(), Displayer(os));
  204.         // no endLetter()
  205.     }
  206. };
  207. class Sentence
  208. : public DisplayElem
  209. , public CreatableParam<Sentence, ESentenceType> {
  210. private:
  211.     std::vector<Word*> m_words;
  212.  
  213.     ESentenceType m_sentenceType;
  214.  
  215. protected:
  216.     /*virtual*/ ~Sentence() {
  217.         clear();
  218.     }
  219.  
  220.     void endSentence(std::ostream& os) const {
  221.         const char puncMark = getPunctionMark(m_sentenceType);
  222.         os << puncMark;
  223.     }
  224.  
  225. public:
  226.     Sentence()
  227.     : m_sentenceType(eStatement) {
  228.     }
  229.  
  230.     void initialize(ESentenceType sentenceType) {
  231.         m_sentenceType = sentenceType;
  232.     }
  233.  
  234.     void finalize() {
  235.         m_sentenceType = eStatement;
  236.     }
  237.  
  238.     void clear() {
  239.         std::for_each(m_words.begin(), m_words.end(), Freer<Word>());
  240.         m_words.clear();
  241.     }
  242.  
  243.     void addWord(Word* w) {
  244.         m_words.push_back(w);
  245.     }
  246.  
  247.     void display(std::ostream& os) const {
  248.         std::for_each(m_words.begin(), m_words.end(), Displayer(os, ' '));
  249.         endSentence(os);
  250.     }
  251. };
  252. class Message
  253. : public DisplayElem
  254. , public Creatable<Message> {
  255. private:
  256.     std::vector<Sentence*> m_sentences;
  257.  
  258. protected:
  259.     /*virtual*/ ~Message() {
  260.         clear();
  261.     }
  262.  
  263.     void endMessage(std::ostream& os) const {
  264.         os << std::endl;
  265.     }
  266.  
  267. public:
  268.     Message() {
  269.     }
  270.  
  271.     void clear() {
  272.         std::for_each(m_sentences.begin(), m_sentences.end(), Freer<Sentence>());
  273.         m_sentences.clear();
  274.     }
  275.  
  276.     void addSentence(Sentence* s) {
  277.         m_sentences.push_back(s);
  278.     }
  279.  
  280.     void display(std::ostream& os) const {
  281.         std::for_each(m_sentences.begin(), m_sentences.end(), Displayer(os, ' '));
  282.         endMessage(os);
  283.     }
  284. };
  285. int main() {
  286.     displayMessage();
  287.     return 0;
  288. }
  289. void displayMessage() {
  290.     Word* first_word = Word::create();
  291.     first_word->addLetter(Letter::create('H'));
  292.     first_word->addLetter(Letter::create('e'));
  293.     first_word->addLetter(Letter::create('l'));
  294.     first_word->addLetter(Letter::create('l'));
  295.     first_word->addLetter(Letter::create('o'));
  296.  
  297.     Word* second_word = Word::create();
  298.     second_word->addLetter(Letter::create('w'));
  299.     second_word->addLetter(Letter::create('o'));
  300.     second_word->addLetter(Letter::create('r'));
  301.     second_word->addLetter(Letter::create('l'));
  302.     second_word->addLetter(Letter::create('d'));
  303.  
  304.     Sentence* sentence = Sentence::create(eExclamation);
  305.     sentence->addWord(first_word);
  306.     sentence->addWord(second_word);
  307.  
  308.     Message* message = Message::create();
  309.     message->addSentence(sentence);
  310.  
  311.     message->display(std::cout);
  312.  
  313.     message->free();
  314.     // sentences, etc freed by parent
  315. }
Advertisement
Add Comment
Please, Sign In to add comment