// Document/View sample for Boost.Signals2. // Expands on doc_view_acm.cpp example by using boost::signals2::deconstruct // as a post-constructing factory function. // // Copyright Keith MacDonald 2005. // Copyright Frank Mori Hess 2009. // // Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include #include #include #include #include #include #include class Document { public: typedef boost::signals2::signal signal_t; public: Document() {} /* Connect a slot to the signal which will be emitted whenever text is appended to the document. */ boost::signals2::connection connect(const signal_t::slot_type &subscriber) { return m_sig.connect(subscriber); } void append(const char* s) { m_text += s; m_sig(); } const std::string& getText() const { return m_text; } private: signal_t m_sig; std::string m_text; }; class TextView { public: /* This adl_postconstruct function will be found via argument-dependent lookup when using boost::signals2::deconstruct. */ template friend void adl_postconstruct(const boost::shared_ptr &view_sp, TextView *view, Document& doc) { view->m_document = &doc; { typedef Document::signal_t::slot_type slot_type; slot_type myslot(&TextView::refresh, view); doc.connect(myslot.track(view_sp)); } } void refresh() const { std::cout << "TextView: " << m_document->getText() << std::endl; } private: // give boost::signals2::deconstruct access to private constructor friend class boost::signals2::deconstruct_access; // private constructor to force use of deconstruct TextView() {} Document* m_document; }; class HexView { public: /* This adl_postconstruct function will be found via argument-dependent lookup when using boost::signals2::deconstruct. */ template friend void adl_postconstruct(const boost::shared_ptr &view_sp, HexView *view, Document& doc) { view->m_document = &doc; { typedef Document::signal_t::slot_type slot_type; slot_type myslot(&HexView::refresh, view); doc.connect(myslot.track(view_sp)); } } void refresh() const { const std::string& s = m_document->getText(); std::cout << "HexView:"; for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) std::cout << ' ' << std::hex << static_cast(*it); std::cout << std::endl; } private: // give boost::signals2::deconstruct access to private constructor friend class boost::signals2::deconstruct_access; // private constructor to force use of deconstruct HexView() {} Document* m_document; }; namespace bs2 = boost::signals2; int main(int argc, char* argv[]) { Document doc; boost::shared_ptr v1 = bs2::deconstruct().postconstruct(boost::ref(doc)); boost::shared_ptr v2 = bs2::deconstruct().postconstruct(boost::ref(doc)); doc.append(argc >= 2 ? argv[1] : "Hello world!"); v2.reset(); // destroy the HexView, automatically disconnecting doc.append(" HexView should no longer be connected."); return 0; }