trackable_test.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Boost.Signals2 library
  2. // Copyright Douglas Gregor 2001-2006.
  3. // Copyright Frank Mori Hess 2009.
  4. // Use, modification and
  5. // distribution is subject to the Boost Software License, Version
  6. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. // For more information, see http://www.boost.org
  9. #include <boost/test/minimal.hpp>
  10. #include <boost/signals2/signal.hpp>
  11. #include <boost/signals2/trackable.hpp>
  12. #include <boost/bind.hpp>
  13. #include <boost/ref.hpp>
  14. #include <boost/weak_ptr.hpp>
  15. struct short_lived : public boost::signals2::trackable {
  16. ~short_lived() {}
  17. };
  18. struct swallow {
  19. typedef int result_type;
  20. template<typename T> int operator()(const T*, int i) { return i; }
  21. template<typename T> int operator()(T &, int i) { return i; }
  22. template<typename T> int operator()(boost::weak_ptr<T>, int i) { return i; }
  23. };
  24. template<typename T>
  25. struct max_or_default {
  26. typedef T result_type;
  27. template<typename InputIterator>
  28. T operator()(InputIterator first, InputIterator last) const
  29. {
  30. if (first == last)
  31. return T();
  32. T max = *first++;
  33. for (; first != last; ++first)
  34. max = (*first > max)? *first : max;
  35. return max;
  36. }
  37. };
  38. struct self_deleting : public boost::signals2::trackable {
  39. void delete_myself(boost::signals2::connection connection)
  40. {
  41. BOOST_CHECK(connection.connected());
  42. delete this;
  43. BOOST_CHECK(connection.connected() == false);
  44. }
  45. };
  46. // test that slot assocated with signals2::trackable
  47. // gets disconnected immediately upon deletion of the
  48. // signals2::trackable, even when a signal invocation
  49. // is in progress.
  50. void test_immediate_disconnect_on_delete()
  51. {
  52. boost::signals2::signal<void () > sig;
  53. self_deleting *obj = new self_deleting();
  54. sig.connect_extended(boost::bind(&self_deleting::delete_myself, obj, _1));
  55. sig();
  56. }
  57. int test_main(int, char*[])
  58. {
  59. typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type;
  60. sig_type s1;
  61. // Test auto-disconnection
  62. BOOST_CHECK(s1(5) == 0);
  63. {
  64. short_lived shorty;
  65. s1.connect(boost::bind<int>(swallow(), &shorty, _1));
  66. BOOST_CHECK(s1(5) == 5);
  67. }
  68. BOOST_CHECK(s1(5) == 0);
  69. // Test auto-disconnection of trackable inside reference_wrapper
  70. {
  71. short_lived shorty;
  72. s1.connect(boost::bind<int>(swallow(), boost::ref(shorty), _1));
  73. BOOST_CHECK(s1(5) == 5);
  74. }
  75. BOOST_CHECK(s1(5) == 0);
  76. // Test multiple arg slot constructor
  77. {
  78. short_lived shorty;
  79. s1.connect(sig_type::slot_type(swallow(), &shorty, _1));
  80. BOOST_CHECK(s1(5) == 5);
  81. }
  82. BOOST_CHECK(s1(5) == 0);
  83. // Test auto-disconnection of slot before signal connection
  84. {
  85. short_lived* shorty = new short_lived();
  86. sig_type::slot_type slot(boost::bind<int>(swallow(), shorty, _1));
  87. delete shorty;
  88. BOOST_CHECK(s1(5) == 0);
  89. }
  90. test_immediate_disconnect_on_delete();
  91. return 0;
  92. }