diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
commit | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch) | |
tree | 7a7053ceb8874b28ec4b868d4c49b500008a102e /libs/signals2 | |
parent | bb4dd8289b351fae6b55e303f189127a394a1edd (diff) | |
download | boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2 boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip |
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'libs/signals2')
22 files changed, 420 insertions, 50 deletions
diff --git a/libs/signals2/doc/porting.xml b/libs/signals2/doc/porting.xml index 4b1ecab85f..d3f98877cf 100644 --- a/libs/signals2/doc/porting.xml +++ b/libs/signals2/doc/porting.xml @@ -227,8 +227,20 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </section> <section id="signals2.api_history"> <title>Signals2 API Development</title> + <section id="signals2.api_history.1-56"> + <title>Version 1.56</title> + <para> + Version 1.56 modified the behavior of the signal destructor, in that it no longer + explicitly calls disconnect_all_slots. Any signal invocations running + concurrently with the signal destructor should now complete normally, rather + than skipping all remaining slots. Once all concurrent signal invocations + complete, all connections to the deleted signal will still ultimately + be disconnected. This change brings Boost.Signals2 + behavior closer to the behavior of the original Boost.Signals library. + </para> + </section> <section id="signals2.api_history.1-45"> - <title>Version 1.4x</title> + <title>Version 1.45</title> <para> Version 1.45 added <methodname>slot::track_foreign</methodname>(). This method allows tracking of objects owned by <code>shared_ptr</code> classes other than <classname>boost::shared_ptr</classname>, @@ -263,14 +275,14 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </para> <para>Version 1.40 also introduces a variadic templates implementation of Signals2, which is used when Boost detects compiler support for variadic templates - (variadic templates are a new feature of C++0x). + (variadic templates are a new feature of C++11). This change is mostly transparent to the user, however it does introduce a few visible tweaks to the interface as described in the following. </para> <para> The following library features are deprecated, and are only available if your compiler is NOT using - variadic templates (i.e. BOOST_NO_VARIADIC_TEMPLATES is defined + variadic templates (i.e. BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined by Boost.Config). <itemizedlist> <listitem> diff --git a/libs/signals2/doc/reference/connection.xml b/libs/signals2/doc/reference/connection.xml index e12497c6d6..3cf4a37b54 100644 --- a/libs/signals2/doc/reference/connection.xml +++ b/libs/signals2/doc/reference/connection.xml @@ -53,14 +53,40 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) <throws><para>Will not throw.</para></throws> </constructor> - <copy-assignment> + <constructor> <parameter name="other"> + <paramtype><classname alt="signals2::connection">connection</classname>&&</paramtype> + </parameter> + <description><para>Move constructor.</para></description> + <effects><para><computeroutput>this</computeroutput> references + the connection formerly referenced by + <computeroutput>other</computeroutput>. The moved-from <computeroutput>other</computeroutput> + no longer references any connection.</para></effects> + + <throws><para>Will not throw.</para></throws> + </constructor> + + <copy-assignment> + <parameter name="rhs"> <paramtype>const <classname alt="signals2::connection">connection</classname>&</paramtype> </parameter> <effects><para><computeroutput>this</computeroutput> references the connection referenced by - <computeroutput>other</computeroutput>.</para></effects> + <computeroutput>rhs</computeroutput>.</para></effects> + + <throws><para>Will not throw.</para></throws> + </copy-assignment> + + <copy-assignment> + <parameter name="rhs"> + <paramtype><classname alt="signals2::connection">connection</classname>&&</paramtype> + </parameter> + <description><para>Move assignment.</para></description> + <effects><para><computeroutput>this</computeroutput> references + the connection formerly referenced by + <computeroutput>rhs</computeroutput>. The moved-from <computeroutput>rhs</computeroutput> + no longer references any connection.</para></effects> <throws><para>Will not throw.</para></throws> </copy-assignment> @@ -104,7 +130,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) <method name="swap"> <type>void</type> <parameter name="other"> - <paramtype>const <classname alt="signals2::connection">connection</classname>&</paramtype> + <paramtype><classname alt="signals2::connection">connection</classname>&</paramtype> </parameter> <effects><para>Swaps the connections referenced in <computeroutput>this</computeroutput> and @@ -210,28 +236,82 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) <throws><para>Will not throw.</para></throws> </constructor> + <constructor> + <parameter name="other"> + <paramtype><classname alt="signals2::scoped_connection">scoped_connection</classname>&&</paramtype> + </parameter> + <description><para>Move constructor.</para></description> + <effects><para><computeroutput>this</computeroutput> references + the connection formerly referenced by + <computeroutput>other</computeroutput>. The moved-from <computeroutput>other</computeroutput> + no longer references any connection.</para></effects> + + <throws><para>Will not throw.</para></throws> + </constructor> + + <constructor> + <parameter name="other"> + <paramtype><classname alt="signals2::connection">connection</classname>&&</paramtype> + </parameter> + <description><para>Move constructor.</para></description> + <effects><para><computeroutput>this</computeroutput> references + the connection formerly referenced by + <computeroutput>other</computeroutput>. The moved-from <computeroutput>other</computeroutput> + no longer references any connection.</para></effects> + + <throws><para>Will not throw.</para></throws> + </constructor> + + <copy-assignment> + <parameter name="rhs"> + <paramtype>const <classname alt="signals2::connection">connection</classname>&</paramtype> + </parameter> + <description><para>Copy assignment from unscoped connection.</para></description> + <effects><para><computeroutput>this</computeroutput> references + the connection referenced by + <computeroutput>rhs</computeroutput>. If <code>this</code> already references another + connection, the old connection will be disconnected first.</para></effects> + <postconditions> + <para><code><methodname alt="connection::connected">connected</methodname>() == other.connected()</code></para> + </postconditions> + + <throws><para>Will not throw.</para></throws> + </copy-assignment> + + <copy-assignment> + <parameter name="rhs"> + <paramtype><classname alt="signals2::scoped_connection">scoped_connection</classname>&&</paramtype> + </parameter> + <description><para>Move assignment.</para></description> + <effects><para><computeroutput>this</computeroutput> references + the connection formerly referenced by + <computeroutput>rhs</computeroutput>. The moved-from <computeroutput>rhs</computeroutput> + no longer references any connection. If <code>this</code> already references another + connection, the old connection will be disconnected first.</para></effects> + + <throws><para>Will not throw.</para></throws> + </copy-assignment> + + <copy-assignment> + <parameter name="rhs"> + <paramtype><classname alt="signals2::connection">connection</classname>&&</paramtype> + </parameter> + <description><para>Move assignment.</para></description> + <effects><para><computeroutput>this</computeroutput> references + the connection formerly referenced by + <computeroutput>rhs</computeroutput>. The moved-from <computeroutput>rhs</computeroutput> + no longer references any connection. If <code>this</code> already references another + connection, the old connection will be disconnected first.</para></effects> + + <throws><para>Will not throw.</para></throws> + </copy-assignment> + <destructor> <effects><para>If <computeroutput>this-><methodname alt="connection::connected">connected</methodname>()</computeroutput>, disconnects the signal-slot connection.</para></effects> </destructor> <method-group name="public methods"> - <method name="operator="> - <type>scoped_connection &</type> - <parameter name="rhs"> - <paramtype>const connection &</paramtype> - </parameter> - <effects> - <para><computeroutput>this</computeroutput> references - the connection referenced by - <computeroutput>rhs</computeroutput>. If <code>this</code> already references another - connection, the old connection will be disconnected first. - </para> - </effects> - <postconditions> - <para><code><methodname alt="connection::connected">connected</methodname>() == rhs.connected()</code></para> - </postconditions> - </method> <method name="release"> <type><classname alt="signals2::connection">connection</classname></type> <effects> @@ -258,7 +338,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) <paramtype>const <classname alt="signals2::scoped_connection">scoped_connection</classname>&</paramtype> </parameter> <description> - <para>The scoped_connection class is not copyable. It may only be constructed from a <classname alt="signals2::connection">connection</classname> object.</para> + <para>The scoped_connection class is not copyable. It may only be copy constructed from an unscoped + <classname alt="signals2::connection">connection</classname> object.</para> </description> </constructor> <copy-assignment> @@ -266,7 +347,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) <paramtype>const <classname alt="signals2::scoped_connection">scoped_connection</classname>&</paramtype> </parameter> <description> - <para>The scoped_connection class is not copyable. It may only be assigned from a <classname alt="signals2::connection">connection</classname> object.</para> + <para>The scoped_connection class is not copyable. It may only be copy assigned from an unscoped + <classname alt="signals2::connection">connection</classname> object.</para> </description> </copy-assignment> </access> @@ -287,4 +369,4 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </class> </namespace> </namespace> -</header>
\ No newline at end of file +</header> diff --git a/libs/signals2/doc/reference/deconstruct.xml b/libs/signals2/doc/reference/deconstruct.xml index 1996737d34..e43164ba1e 100644 --- a/libs/signals2/doc/reference/deconstruct.xml +++ b/libs/signals2/doc/reference/deconstruct.xml @@ -100,7 +100,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </para> </description> <notes> - <para>If your compiler supports the C++0x features of rvalue references + <para>If your compiler supports the C++11 features of rvalue references and variadic templates, then <code>deconstruct</code> will perform perfect forwarding of arguments to the <code>T</code> constructor, using a prototype of: diff --git a/libs/signals2/doc/reference/signal_header.xml b/libs/signals2/doc/reference/signal_header.xml index 3ab89f8317..343726cd45 100644 --- a/libs/signals2/doc/reference/signal_header.xml +++ b/libs/signals2/doc/reference/signal_header.xml @@ -140,9 +140,29 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) <postconditions><para><computeroutput>this-><methodname>empty</methodname>()</computeroutput></para></postconditions> </constructor> - <destructor> - <effects><para>Disconnects all slots connected to <computeroutput>*this</computeroutput>.</para></effects> - </destructor> + <constructor> + <parameter name="other"> + <paramtype>signal &&</paramtype> + </parameter> + <description><para>Move constructor.</para></description> + <postconditions><para>The signal <computeroutput>other</computeroutput> + is in a "moved-from" state where it may only be destroyed, swapped, or move assigned. + Any other operation on a "moved-from" signal is invalid.</para></postconditions> + + <throws><para>Will not throw.</para></throws> + </constructor> + + <copy-assignment> + <parameter name="rhs"> + <paramtype>signal &&</paramtype> + </parameter> + <description><para>Move assignment.</para></description> + <postconditions><para>The signal <computeroutput>rhs</computeroutput> + is in a "moved-from" state where it may only be destroyed, swapped, or move assigned. + Any other operation on a "moved-from" signal is invalid.</para></postconditions> + + <throws><para>Will not throw.</para></throws> + </copy-assignment> <method-group name="connection management"> <overloaded-method name="connect"> @@ -397,6 +417,44 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) <throws><para>Will not throw.</para></throws> </method> </method-group> + + <method-group name="modifiers"> + <method name="swap"> + <type>void</type> + <parameter name="other"> + <paramtype><classname alt="signals2::signal">signal</classname>&</paramtype> + </parameter> + <effects><para>Swaps the signal referenced in + <computeroutput>this</computeroutput> and + <computeroutput>other</computeroutput>.</para></effects> + + <throws><para>Will not throw.</para></throws> + </method> + </method-group> + + <free-function-group name="specialized algorithms"> + <function name="swap"> + <template> + <template-type-parameter name="Signature"/> + <template-type-parameter name="Combiner"/> + <template-type-parameter name="Group"/> + <template-type-parameter name="GroupCompare"/> + <template-type-parameter name="SlotFunction"/> + <template-type-parameter name="ExtendedSlotFunction"/> + <template-type-parameter name="Mutex"/> + </template> + <type>void</type> + <parameter name="x"> + <paramtype><classname alt="signals2::signal">signal</classname><Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>&</paramtype> + </parameter> + <parameter name="y"> + <paramtype><classname alt="signals2::signal">signal</classname><Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>&</paramtype> + </parameter> + + <effects><para><computeroutput>x.swap(y)</computeroutput></para></effects> + <throws><para>Will not throw.</para></throws> + </function> + </free-function-group> </class> </namespace> </namespace> diff --git a/libs/signals2/doc/tutorial.xml b/libs/signals2/doc/tutorial.xml index 930920e5fd..df74571e21 100644 --- a/libs/signals2/doc/tutorial.xml +++ b/libs/signals2/doc/tutorial.xml @@ -633,7 +633,7 @@ hidden in an implementation detail file.</para> use in single-threaded programs, where locking a real mutex would be useless overhead. Other mutex types you could use with <code>signal</code> include <classname>boost::mutex</classname>, or the <code>std::mutex</code> from - C++0x. + C++11. </para> <para> Changing a signal's <code>Mutex</code> template type parameter can be tedious, due to diff --git a/libs/signals2/example/Jamfile.v2 b/libs/signals2/example/Jamfile.v2 index 1cf64b0c11..079ad4432e 100644 --- a/libs/signals2/example/Jamfile.v2 +++ b/libs/signals2/example/Jamfile.v2 @@ -8,7 +8,7 @@ # For more information, see http://www.boost.org -project : requirements <source>/boost//headers ; +project : requirements <implicit-dependency>/boost//headers ; exe hello_world_slot : hello_world_slot.cpp ; diff --git a/libs/signals2/example/custom_combiners.cpp b/libs/signals2/example/custom_combiners.cpp index a209e239dd..72e43b760d 100644 --- a/libs/signals2/example/custom_combiners.cpp +++ b/libs/signals2/example/custom_combiners.cpp @@ -106,4 +106,4 @@ int main() { maximum_combiner_example(); aggregate_values_example(); -}; +} diff --git a/libs/signals2/example/disconnect_and_block.cpp b/libs/signals2/example/disconnect_and_block.cpp index 724b2e5542..4478be0059 100644 --- a/libs/signals2/example/disconnect_and_block.cpp +++ b/libs/signals2/example/disconnect_and_block.cpp @@ -111,4 +111,4 @@ int main() disconnect_by_slot_example(); return 0; -}; +} diff --git a/libs/signals2/example/extended_slot.cpp b/libs/signals2/example/extended_slot.cpp index 7a55a3680e..40699e53c7 100644 --- a/libs/signals2/example/extended_slot.cpp +++ b/libs/signals2/example/extended_slot.cpp @@ -38,4 +38,5 @@ int main() sig(); // prints nothing, world slot has disconnected itself return 0; -}; +} + diff --git a/libs/signals2/example/hello_world_multi_slot.cpp b/libs/signals2/example/hello_world_multi_slot.cpp index 43d18af6fe..f478351483 100644 --- a/libs/signals2/example/hello_world_multi_slot.cpp +++ b/libs/signals2/example/hello_world_multi_slot.cpp @@ -43,4 +43,5 @@ int main() //] return 0; -}; +} + diff --git a/libs/signals2/example/hello_world_slot.cpp b/libs/signals2/example/hello_world_slot.cpp index 979c485db7..18e3c6a383 100644 --- a/libs/signals2/example/hello_world_slot.cpp +++ b/libs/signals2/example/hello_world_slot.cpp @@ -36,4 +36,5 @@ int main() //] return 0; -}; +} + diff --git a/libs/signals2/example/ordering_slots.cpp b/libs/signals2/example/ordering_slots.cpp index 022aa77732..f69bc182c6 100644 --- a/libs/signals2/example/ordering_slots.cpp +++ b/libs/signals2/example/ordering_slots.cpp @@ -58,4 +58,5 @@ int main() //] return 0; -}; +} + diff --git a/libs/signals2/example/signal_return_value.cpp b/libs/signals2/example/signal_return_value.cpp index cc3959a444..163f29abf6 100644 --- a/libs/signals2/example/signal_return_value.cpp +++ b/libs/signals2/example/signal_return_value.cpp @@ -34,4 +34,5 @@ int main() // difference function. std::cout << *sig(5, 3) << std::endl; //] -}; +} + diff --git a/libs/signals2/example/slot_arguments.cpp b/libs/signals2/example/slot_arguments.cpp index 2171cbdd57..86c49cb6f4 100644 --- a/libs/signals2/example/slot_arguments.cpp +++ b/libs/signals2/example/slot_arguments.cpp @@ -53,4 +53,5 @@ int main() sig(5., 3.); //] return 0; -}; +} + diff --git a/libs/signals2/meta/libraries.json b/libs/signals2/meta/libraries.json new file mode 100644 index 0000000000..cb5e0654fb --- /dev/null +++ b/libs/signals2/meta/libraries.json @@ -0,0 +1,15 @@ +{ + "key": "signals2", + "name": "Signals2", + "authors": [ + "Frank Mori Hess" + ], + "description": "Managed signals & slots callback implementation (thread-safe version 2).", + "category": [ + "Function-objects", + "Patterns" + ], + "maintainers": [ + "Frank Mori Hess <fmhess -at- users.sourceforge.net>" + ] +} diff --git a/libs/signals2/test/Jamfile.v2 b/libs/signals2/test/Jamfile.v2 index a9d4f38538..344f754a88 100644 --- a/libs/signals2/test/Jamfile.v2 +++ b/libs/signals2/test/Jamfile.v2 @@ -16,14 +16,14 @@ project : source-location . : requirements <hardcode-dll-paths>true - <library>../../test/build//boost_test_exec_monitor + <library>/boost/test//boost_unit_test_framework <link>static ; rule thread-run ( sources ) { return - [ run $(sources) : : : <library>../../thread/build//boost_thread/ + [ run $(sources) : : : <library>/boost/thread//boost_thread/ <threading>multi ] ; } diff --git a/libs/signals2/test/connection_test.cpp b/libs/signals2/test/connection_test.cpp index 3ac4bde6eb..903857d603 100644 --- a/libs/signals2/test/connection_test.cpp +++ b/libs/signals2/test/connection_test.cpp @@ -82,9 +82,50 @@ void release_test() BOOST_CHECK(conn2.connected() == false); } +void move_test() +{ +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + sig_type sig; + bs2::connection conn; + // test move assignment from scoped_connection to connection + { + bs2::scoped_connection scoped(sig.connect(&myslot)); + BOOST_CHECK(scoped.connected()); + conn = std::move(scoped); + BOOST_CHECK(scoped.connected() == false); + } + BOOST_CHECK(conn.connected()); + + // test move construction from scoped to scoped + { + bs2::scoped_connection scoped2(conn); + BOOST_CHECK(scoped2.connected()); + bs2::scoped_connection scoped3(std::move(scoped2)); + BOOST_CHECK(scoped2.connected() == false); + BOOST_CHECK(scoped3.connected() == true); + BOOST_CHECK(conn.connected() == true); + } + BOOST_CHECK(conn.connected() == false); + + // test move assignment from scoped to scoped + conn = sig.connect(&myslot); + { + bs2::scoped_connection scoped3; + bs2::scoped_connection scoped2(conn); + BOOST_CHECK(scoped2.connected()); + scoped3 = std::move(scoped2); + BOOST_CHECK(scoped2.connected() == false); + BOOST_CHECK(scoped3.connected() == true); + BOOST_CHECK(conn.connected() == true); + } + BOOST_CHECK(conn.connected() == false); +#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +} + int test_main(int, char*[]) { release_test(); swap_test(); + move_test(); return 0; } diff --git a/libs/signals2/test/deletion_test.cpp b/libs/signals2/test/deletion_test.cpp index a373dc8c8f..730a86f893 100644 --- a/libs/signals2/test/deletion_test.cpp +++ b/libs/signals2/test/deletion_test.cpp @@ -238,6 +238,53 @@ test_disconnect_equal() BOOST_CHECK(test_output == "013"); } +struct signal_deletion_tester +{ +public: + signal_deletion_tester() { + b_has_run = false; + sig = new boost::signals2::signal<void(void)>(); + connection0 = sig->connect(0, boost::bind(&signal_deletion_tester::a, this)); + connection1 = sig->connect(1, boost::bind(&signal_deletion_tester::b, this)); + } + + ~signal_deletion_tester() + { + if(sig != 0) + delete sig; + } + + void a() + { + if(sig != 0) + delete sig; + sig = 0; + } + + void b() + { + b_has_run = true; + } + + boost::signals2::signal<void(void)> *sig; + bool b_has_run; + boost::signals2::connection connection0; + boost::signals2::connection connection1; +}; + +// If a signal is deleted mid-invocation, the invocation in progress +// should complete normally. Once all invocations complete, all +// slots which were connected to the deleted signal should be in the +// disconnected state. +static void test_signal_deletion() +{ + signal_deletion_tester tester; + (*tester.sig)(); + BOOST_CHECK(tester.b_has_run); + BOOST_CHECK(tester.connection0.connected() == false); + BOOST_CHECK(tester.connection1.connected() == false); +} + int test_main(int, char* []) { test_remove_self(); @@ -245,5 +292,6 @@ int test_main(int, char* []) test_remove_after(); test_bloodbath(); test_disconnect_equal(); + test_signal_deletion(); return 0; } diff --git a/libs/signals2/test/signal_n_test.cpp b/libs/signals2/test/signal_n_test.cpp index 000d77db61..994ee41bf9 100644 --- a/libs/signals2/test/signal_n_test.cpp +++ b/libs/signals2/test/signal_n_test.cpp @@ -10,12 +10,12 @@ #include <boost/config.hpp> #include <boost/test/minimal.hpp> -#ifndef BOOST_NO_VARIADIC_TEMPLATES +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES int test_main(int, char* []) { return 0; } -#else // BOOST_NO_VARIADIC_TEMPLATES +#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES #include <boost/optional.hpp> #include <boost/ref.hpp> @@ -34,7 +34,7 @@ struct max_or_default { { try { - if(max == false) max = *first; + if(!max) max = *first; else max = (*first > max.get())? *first : max; } catch(const boost::bad_weak_ptr &) @@ -286,6 +286,52 @@ template<typename ResultType> BOOST_CHECK(sig.num_slots() == 0); } } +class dummy_combiner +{ +public: + typedef int result_type; + + dummy_combiner(result_type return_value): _return_value(return_value) + {} + template<typename SlotIterator> + result_type operator()(SlotIterator, SlotIterator) + { + return _return_value; + } +private: + result_type _return_value; +}; + +static void +test_set_combiner() +{ + typedef boost::signals2::signal0<int, dummy_combiner> signal_type; + signal_type sig(dummy_combiner(0)); + BOOST_CHECK(sig() == 0); + BOOST_CHECK(sig.combiner()(0,0) == 0); + sig.set_combiner(dummy_combiner(1)); + BOOST_CHECK(sig() == 1); + BOOST_CHECK(sig.combiner()(0,0) == 1); +} + +static void +test_swap() +{ + typedef boost::signals2::signal0<int, dummy_combiner> signal_type; + signal_type sig1(dummy_combiner(1)); + BOOST_CHECK(sig1() == 1); + signal_type sig2(dummy_combiner(2)); + BOOST_CHECK(sig2() == 2); + + sig1.swap(sig2); + BOOST_CHECK(sig1() == 2); + BOOST_CHECK(sig2() == 1); + + using std::swap; + swap(sig1, sig2); + BOOST_CHECK(sig1() == 1); + BOOST_CHECK(sig2() == 2); +} int test_main(int, char* []) @@ -297,7 +343,9 @@ test_main(int, char* []) test_default_combiner(); test_extended_slot<void>(); test_extended_slot<int>(); + test_set_combiner(); + test_swap(); return 0; } -#endif // BOOST_NO_VARIADIC_TEMPLATES +#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES diff --git a/libs/signals2/test/signal_test.cpp b/libs/signals2/test/signal_test.cpp index cbf9ff8f2a..60c5e6d45e 100644 --- a/libs/signals2/test/signal_test.cpp +++ b/libs/signals2/test/signal_test.cpp @@ -29,7 +29,7 @@ struct max_or_default { { try { - if(max == false) max = *first; + if(!max) max = *first; else max = (*first > max.get())? *first : max; } catch(const boost::bad_weak_ptr &) @@ -293,6 +293,42 @@ test_set_combiner() BOOST_CHECK(sig.combiner()(0,0) == 1); } +static void +test_swap() +{ + typedef boost::signals2::signal<int (), dummy_combiner> signal_type; + signal_type sig1(dummy_combiner(1)); + BOOST_CHECK(sig1() == 1); + signal_type sig2(dummy_combiner(2)); + BOOST_CHECK(sig2() == 2); + + sig1.swap(sig2); + BOOST_CHECK(sig1() == 2); + BOOST_CHECK(sig2() == 1); + + using std::swap; + swap(sig1, sig2); + BOOST_CHECK(sig1() == 1); + BOOST_CHECK(sig2() == 2); +} + +void test_move() +{ +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + typedef boost::signals2::signal<int (), dummy_combiner> signal_type; + signal_type sig1(dummy_combiner(1)); + BOOST_CHECK(sig1() == 1); + signal_type sig2(dummy_combiner(2)); + BOOST_CHECK(sig2() == 2); + + sig1 = std::move(sig2); + BOOST_CHECK(sig1() == 2); + + signal_type sig3(std::move(sig1)); + BOOST_CHECK(sig3() == 2); +#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +} + int test_main(int, char* []) { @@ -304,5 +340,7 @@ test_main(int, char* []) test_reference_args(); test_typedefs_etc(); test_set_combiner(); + test_swap(); + test_move(); return 0; } diff --git a/libs/signals2/test/track_test.cpp b/libs/signals2/test/track_test.cpp index 0cc11422fa..be8141fb31 100644 --- a/libs/signals2/test/track_test.cpp +++ b/libs/signals2/test/track_test.cpp @@ -33,7 +33,7 @@ struct max_or_default { for(; first != last; ++first) { T value = *first; - if(max == false) + if(!max) { max = value; }else if(value > *max) @@ -110,9 +110,7 @@ int test_main(int, char*[]) } BOOST_CHECK(s1(2) == 0); -// there isn't a boost config macro that detects the existance of std::shared_ptr or std::weak_ptr, -// so we rely on BOOST_NO_VARIADIC_TEMPLATES as a hack -#ifndef BOOST_NO_VARIADIC_TEMPLATES +#ifndef BOOST_NO_CXX11_SMART_PTR // Test tracking through std::shared_ptr/weak_ptr BOOST_CHECK(s1(5) == 0); { diff --git a/libs/signals2/test/trackable_test.cpp b/libs/signals2/test/trackable_test.cpp index cc08fcb9d8..220da852c7 100644 --- a/libs/signals2/test/trackable_test.cpp +++ b/libs/signals2/test/trackable_test.cpp @@ -45,6 +45,27 @@ struct max_or_default { } }; +struct self_deleting : public boost::signals2::trackable { + void delete_myself(boost::signals2::connection connection) + { + BOOST_CHECK(connection.connected()); + delete this; + BOOST_CHECK(connection.connected() == false); + } +}; + +// test that slot assocated with signals2::trackable +// gets disconnected immediately upon deletion of the +// signals2::trackable, even when a signal invocation +// is in progress. +void test_immediate_disconnect_on_delete() +{ + boost::signals2::signal<void () > sig; + self_deleting *obj = new self_deleting(); + sig.connect_extended(boost::bind(&self_deleting::delete_myself, obj, _1)); + sig(); +} + int test_main(int, char*[]) { typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type; @@ -83,5 +104,8 @@ int test_main(int, char*[]) BOOST_CHECK(s1(5) == 0); } + + test_immediate_disconnect_on_delete(); + return 0; } |