doc_view_acm_deconstruct.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Document/View sample for Boost.Signals2.
  2. // Expands on doc_view_acm.cpp example by using boost::signals2::deconstruct
  3. // as a post-constructing factory function.
  4. //
  5. // Copyright Keith MacDonald 2005.
  6. // Copyright Frank Mori Hess 2009.
  7. //
  8. // Use, modification and
  9. // distribution is subject to the Boost Software License, Version
  10. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. // For more information, see http://www.boost.org
  13. #include <iostream>
  14. #include <string>
  15. #include <boost/bind.hpp>
  16. #include <boost/ref.hpp>
  17. #include <boost/signals2/deconstruct.hpp>
  18. #include <boost/signals2/signal.hpp>
  19. #include <boost/shared_ptr.hpp>
  20. class Document
  21. {
  22. public:
  23. typedef boost::signals2::signal<void ()> signal_t;
  24. public:
  25. Document()
  26. {}
  27. /* Connect a slot to the signal which will be emitted whenever
  28. text is appended to the document. */
  29. boost::signals2::connection connect(const signal_t::slot_type &subscriber)
  30. {
  31. return m_sig.connect(subscriber);
  32. }
  33. void append(const char* s)
  34. {
  35. m_text += s;
  36. m_sig();
  37. }
  38. const std::string& getText() const
  39. {
  40. return m_text;
  41. }
  42. private:
  43. signal_t m_sig;
  44. std::string m_text;
  45. };
  46. class TextView
  47. {
  48. public:
  49. /* This adl_postconstruct function will be found
  50. via argument-dependent lookup when using boost::signals2::deconstruct. */
  51. template<typename T>
  52. friend void adl_postconstruct(const boost::shared_ptr<T> &view_sp, TextView *view, Document& doc)
  53. {
  54. view->m_document = &doc;
  55. {
  56. typedef Document::signal_t::slot_type slot_type;
  57. slot_type myslot(&TextView::refresh, view);
  58. doc.connect(myslot.track(view_sp));
  59. }
  60. }
  61. void refresh() const
  62. {
  63. std::cout << "TextView: " << m_document->getText() << std::endl;
  64. }
  65. private:
  66. // give boost::signals2::deconstruct access to private constructor
  67. friend class boost::signals2::deconstruct_access;
  68. // private constructor to force use of deconstruct
  69. TextView() : m_document(0)
  70. {}
  71. Document* m_document;
  72. };
  73. class HexView
  74. {
  75. public:
  76. /* This adl_postconstruct function will be found
  77. via argument-dependent lookup when using boost::signals2::deconstruct. */
  78. template<typename T>
  79. friend void adl_postconstruct(const boost::shared_ptr<T> &view_sp, HexView *view, Document& doc)
  80. {
  81. view->m_document = &doc;
  82. {
  83. typedef Document::signal_t::slot_type slot_type;
  84. slot_type myslot(&HexView::refresh, view);
  85. doc.connect(myslot.track(view_sp));
  86. }
  87. }
  88. void refresh() const
  89. {
  90. const std::string& s = m_document->getText();
  91. std::cout << "HexView:";
  92. for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
  93. std::cout << ' ' << std::hex << static_cast<int>(*it);
  94. std::cout << std::endl;
  95. }
  96. private:
  97. // give boost::signals2::deconstruct access to private constructor
  98. friend class boost::signals2::deconstruct_access;
  99. // private constructor to force use of deconstruct
  100. HexView(): m_document(0)
  101. {}
  102. Document* m_document;
  103. };
  104. namespace bs2 = boost::signals2;
  105. int main(int argc, char* argv[])
  106. {
  107. Document doc;
  108. boost::shared_ptr<TextView> v1 = bs2::deconstruct<TextView>().postconstruct(boost::ref(doc));
  109. boost::shared_ptr<HexView> v2 = bs2::deconstruct<HexView>().postconstruct(boost::ref(doc));
  110. doc.append(argc >= 2 ? argv[1] : "Hello world!");
  111. v2.reset(); // destroy the HexView, automatically disconnecting
  112. doc.append(" HexView should no longer be connected.");
  113. return 0;
  114. }