• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Signals library
2 
3 // Copyright Douglas Gregor 2001-2006
4 // Copyright Frank Mori Hess 2007
5 // Use, modification and
6 // distribution is subject to the Boost Software License, Version
7 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 // For more information, see http://www.boost.org
11 
12 #include <memory>
13 #include <boost/optional.hpp>
14 #include <boost/ref.hpp>
15 #include <boost/shared_ptr.hpp>
16 #include <boost/signals2.hpp>
17 #define BOOST_TEST_MODULE track_test
18 #include <boost/test/included/unit_test.hpp>
19 #include <boost/bind/bind.hpp>
20 
21 using namespace boost::placeholders;
22 
23 struct swallow {
24   typedef int result_type;
operator ()swallow25   template<typename T> result_type operator()(const T*, int i) { return i; }
26 };
27 
28 template<typename T>
29 struct max_or_default {
30   typedef T result_type;
31 
32   template<typename InputIterator>
operator ()max_or_default33   T operator()(InputIterator first, InputIterator last) const
34   {
35     boost::optional<T> max;
36     for(; first != last; ++first)
37     {
38       T value = *first;
39       if(!max)
40       {
41         max = value;
42       }else if(value > *max)
43       {
44         max = value;
45       }
46     }
47     if(max) return *max;
48     else return T();
49   }
50 };
51 
myfunc(int i,double z)52 static int myfunc(int i, double z)
53 {
54   return i;
55 }
56 
BOOST_AUTO_TEST_CASE(test_main)57 BOOST_AUTO_TEST_CASE(test_main)
58 {
59   typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type;
60   sig_type s1;
61   boost::signals2::connection connection;
62 
63   // Test auto-disconnection
64   BOOST_CHECK(s1(5) == 0);
65   {
66     boost::shared_ptr<int> shorty(new int());
67     s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track(shorty));
68     BOOST_CHECK(s1(5) == 5);
69   }
70   BOOST_CHECK(s1(5) == 0);
71 
72   // Test auto-disconnection of slot before signal connection
73   {
74     boost::shared_ptr<int> shorty(new int(1));
75 // doesn't work on gcc 3.3.5, it says: error: type specifier omitted for parameter `shorty'
76 // does work on gcc 4.1.2
77 //    sig_type::slot_type slot(swallow(), shorty.get(), _1);
78     swallow myswallow;
79     sig_type::slot_type slot(myswallow, shorty.get(), _1);
80 
81     slot.track(shorty);
82     shorty.reset();
83     s1.connect(slot);
84     BOOST_CHECK(s1(5) == 0);
85   }
86 
87   // Test binding of a slot to another slot
88   {
89     boost::shared_ptr<int> shorty(new int(2));
90     boost::signals2::slot<int (double)> other_slot(&myfunc, boost::cref(*shorty.get()), _1);
91     other_slot.track(shorty);
92     connection = s1.connect(sig_type::slot_type(other_slot, 0.5).track(other_slot));
93     BOOST_CHECK(s1(3) == 2);
94   }
95   BOOST_CHECK(connection.connected() == false);
96   BOOST_CHECK(s1(3) == 0);
97 
98   // Test binding of a signal as a slot
99   {
100     sig_type s2;
101     s1.connect(s2);
102     s2.connect(sig_type::slot_type(&myfunc, _1, 0.7));
103     BOOST_CHECK(s1(4) == 4);
104   }
105   BOOST_CHECK(s1(4) == 0);
106 
107   // Test tracking of null but not empty shared_ptr
108   BOOST_CHECK(s1(2) == 0);
109   {
110     boost::shared_ptr<int> shorty((int*)(0));
111     s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track(shorty));
112     BOOST_CHECK(s1(2) == 2);
113   }
114   BOOST_CHECK(s1(2) == 0);
115 
116 #ifndef BOOST_NO_CXX11_SMART_PTR
117   // Test tracking through std::shared_ptr/weak_ptr
118   BOOST_CHECK(s1(5) == 0);
119   {
120     std::shared_ptr<int> shorty(new int());
121     s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(shorty));
122     BOOST_CHECK(s1(5) == 5);
123   }
124   BOOST_CHECK(s1(5) == 0);
125   {
126     std::shared_ptr<int> shorty(new int());
127     s1.connect
128     (
129       sig_type::slot_type
130       (
131         swallow(),
132         shorty.get(),
133         _1
134       ).track_foreign
135       (
136         std::weak_ptr<int>(shorty)
137       )
138     );
139     BOOST_CHECK(s1(5) == 5);
140   }
141   BOOST_CHECK(s1(5) == 0);
142   // make sure tracking foreign shared_ptr<const void> works
143   {
144     std::shared_ptr<const void> shorty(new int());
145     s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(shorty));
146     BOOST_CHECK(s1(5) == 5);
147   }
148   {
149     std::shared_ptr<int> shorty(new int());
150     s1.connect
151     (
152       sig_type::slot_type
153       (
154         swallow(),
155         shorty.get(),
156         _1
157       ).track_foreign
158       (
159         std::weak_ptr<const void>(shorty)
160       )
161     );
162     BOOST_CHECK(s1(5) == 5);
163   }
164   BOOST_CHECK(s1(5) == 0);
165   BOOST_CHECK(s1(5) == 0);
166 #endif
167 }
168