track_test.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Boost.Signals library
  2. // Copyright Douglas Gregor 2001-2006
  3. // Copyright Frank Mori Hess 2007
  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 <memory>
  10. #include <boost/optional.hpp>
  11. #include <boost/ref.hpp>
  12. #include <boost/shared_ptr.hpp>
  13. #include <boost/test/minimal.hpp>
  14. #include <boost/signals2.hpp>
  15. #include <boost/bind.hpp>
  16. struct swallow {
  17. typedef int result_type;
  18. template<typename T> result_type operator()(const T*, int i) { return i; }
  19. };
  20. template<typename T>
  21. struct max_or_default {
  22. typedef T result_type;
  23. template<typename InputIterator>
  24. T operator()(InputIterator first, InputIterator last) const
  25. {
  26. boost::optional<T> max;
  27. for(; first != last; ++first)
  28. {
  29. T value = *first;
  30. if(!max)
  31. {
  32. max = value;
  33. }else if(value > *max)
  34. {
  35. max = value;
  36. }
  37. }
  38. if(max) return *max;
  39. else return T();
  40. }
  41. };
  42. static int myfunc(int i, double z)
  43. {
  44. return i;
  45. }
  46. int test_main(int, char*[])
  47. {
  48. typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type;
  49. sig_type s1;
  50. boost::signals2::connection connection;
  51. // Test auto-disconnection
  52. BOOST_CHECK(s1(5) == 0);
  53. {
  54. boost::shared_ptr<int> shorty(new int());
  55. s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track(shorty));
  56. BOOST_CHECK(s1(5) == 5);
  57. }
  58. BOOST_CHECK(s1(5) == 0);
  59. // Test auto-disconnection of slot before signal connection
  60. {
  61. boost::shared_ptr<int> shorty(new int(1));
  62. // doesn't work on gcc 3.3.5, it says: error: type specifier omitted for parameter `shorty'
  63. // does work on gcc 4.1.2
  64. // sig_type::slot_type slot(swallow(), shorty.get(), _1);
  65. swallow myswallow;
  66. sig_type::slot_type slot(myswallow, shorty.get(), _1);
  67. slot.track(shorty);
  68. shorty.reset();
  69. s1.connect(slot);
  70. BOOST_CHECK(s1(5) == 0);
  71. }
  72. // Test binding of a slot to another slot
  73. {
  74. boost::shared_ptr<int> shorty(new int(2));
  75. boost::signals2::slot<int (double)> other_slot(&myfunc, boost::cref(*shorty.get()), _1);
  76. other_slot.track(shorty);
  77. connection = s1.connect(sig_type::slot_type(other_slot, 0.5).track(other_slot));
  78. BOOST_CHECK(s1(3) == 2);
  79. }
  80. BOOST_CHECK(connection.connected() == false);
  81. BOOST_CHECK(s1(3) == 0);
  82. // Test binding of a signal as a slot
  83. {
  84. sig_type s2;
  85. s1.connect(s2);
  86. s2.connect(sig_type::slot_type(&myfunc, _1, 0.7));
  87. BOOST_CHECK(s1(4) == 4);
  88. }
  89. BOOST_CHECK(s1(4) == 0);
  90. // Test tracking of null but not empty shared_ptr
  91. BOOST_CHECK(s1(2) == 0);
  92. {
  93. boost::shared_ptr<int> shorty((int*)(0));
  94. s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track(shorty));
  95. BOOST_CHECK(s1(2) == 2);
  96. }
  97. BOOST_CHECK(s1(2) == 0);
  98. #ifndef BOOST_NO_CXX11_SMART_PTR
  99. // Test tracking through std::shared_ptr/weak_ptr
  100. BOOST_CHECK(s1(5) == 0);
  101. {
  102. std::shared_ptr<int> shorty(new int());
  103. s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(shorty));
  104. BOOST_CHECK(s1(5) == 5);
  105. }
  106. BOOST_CHECK(s1(5) == 0);
  107. {
  108. std::shared_ptr<int> shorty(new int());
  109. s1.connect
  110. (
  111. sig_type::slot_type
  112. (
  113. swallow(),
  114. shorty.get(),
  115. _1
  116. ).track_foreign
  117. (
  118. std::weak_ptr<int>(shorty)
  119. )
  120. );
  121. BOOST_CHECK(s1(5) == 5);
  122. }
  123. BOOST_CHECK(s1(5) == 0);
  124. // make sure tracking foreign shared_ptr<const void> works
  125. {
  126. std::shared_ptr<const void> shorty(new int());
  127. s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(shorty));
  128. BOOST_CHECK(s1(5) == 5);
  129. }
  130. {
  131. std::shared_ptr<int> shorty(new int());
  132. s1.connect
  133. (
  134. sig_type::slot_type
  135. (
  136. swallow(),
  137. shorty.get(),
  138. _1
  139. ).track_foreign
  140. (
  141. std::weak_ptr<const void>(shorty)
  142. )
  143. );
  144. BOOST_CHECK(s1(5) == 5);
  145. }
  146. BOOST_CHECK(s1(5) == 0);
  147. BOOST_CHECK(s1(5) == 0);
  148. #endif
  149. return 0;
  150. }