acb59b9679
[SVN r86633]
298 lines
7.3 KiB
C++
298 lines
7.3 KiB
C++
// Boost.Signals2 library
|
|
|
|
// Copyright Douglas Gregor 2001-2003.
|
|
// 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 <boost/test/minimal.hpp>
|
|
#include <boost/signals2.hpp>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
static boost::signals2::connection connections[5];
|
|
|
|
static std::string test_output;
|
|
|
|
struct remove_connection {
|
|
explicit remove_connection(int v = 0, int i = -1) : value(v), idx(i) {}
|
|
|
|
void operator()() const {
|
|
if (idx >= 0)
|
|
connections[idx].disconnect();
|
|
|
|
//return value;
|
|
std::cout << value << " ";
|
|
|
|
test_output += static_cast<char>(value + '0');
|
|
}
|
|
|
|
int value;
|
|
int idx;
|
|
};
|
|
|
|
bool operator==(const remove_connection& x, const remove_connection& y)
|
|
{ return x.value == y.value && x.idx == y.idx; }
|
|
|
|
static void
|
|
test_remove_self()
|
|
{
|
|
boost::signals2::signal<void ()> s0;
|
|
|
|
connections[0] = s0.connect(remove_connection(0));
|
|
connections[1] = s0.connect(remove_connection(1));
|
|
connections[2] = s0.connect(remove_connection(2, 2));
|
|
connections[3] = s0.connect(remove_connection(3));
|
|
|
|
std::cout << "Deleting 2" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "0123");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "013");
|
|
|
|
s0.disconnect_all_slots();
|
|
BOOST_CHECK(s0.empty());
|
|
|
|
connections[0] = s0.connect(remove_connection(0));
|
|
connections[1] = s0.connect(remove_connection(1));
|
|
connections[2] = s0.connect(remove_connection(2));
|
|
connections[3] = s0.connect(remove_connection(3, 3));
|
|
|
|
std::cout << "Deleting 3" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "0123");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "012");
|
|
|
|
s0.disconnect_all_slots();
|
|
BOOST_CHECK(s0.num_slots() == 0);
|
|
|
|
connections[0] = s0.connect(remove_connection(0, 0));
|
|
connections[1] = s0.connect(remove_connection(1));
|
|
connections[2] = s0.connect(remove_connection(2));
|
|
connections[3] = s0.connect(remove_connection(3));
|
|
|
|
std::cout << "Deleting 0" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "0123");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "123");
|
|
|
|
s0.disconnect_all_slots();
|
|
BOOST_CHECK(s0.empty());
|
|
|
|
connections[0] = s0.connect(remove_connection(0, 0));
|
|
connections[1] = s0.connect(remove_connection(1, 1));
|
|
connections[2] = s0.connect(remove_connection(2, 2));
|
|
connections[3] = s0.connect(remove_connection(3, 3));
|
|
|
|
std::cout << "Mass suicide" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "0123");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "");
|
|
}
|
|
|
|
static void
|
|
test_remove_prior()
|
|
{
|
|
boost::signals2::signal<void ()> s0;
|
|
|
|
connections[0] = s0.connect(remove_connection(0));
|
|
connections[1] = s0.connect(remove_connection(1, 0));
|
|
connections[2] = s0.connect(remove_connection(2));
|
|
connections[3] = s0.connect(remove_connection(3));
|
|
|
|
std::cout << "1 removes 0" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "0123");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "123");
|
|
|
|
s0.disconnect_all_slots();
|
|
BOOST_CHECK(s0.empty());
|
|
|
|
connections[0] = s0.connect(remove_connection(0));
|
|
connections[1] = s0.connect(remove_connection(1));
|
|
connections[2] = s0.connect(remove_connection(2));
|
|
connections[3] = s0.connect(remove_connection(3, 2));
|
|
|
|
std::cout << "3 removes 2" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "0123");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "013");
|
|
}
|
|
|
|
static void
|
|
test_remove_after()
|
|
{
|
|
boost::signals2::signal<void ()> s0;
|
|
|
|
connections[0] = s0.connect(remove_connection(0, 1));
|
|
connections[1] = s0.connect(remove_connection(1));
|
|
connections[2] = s0.connect(remove_connection(2));
|
|
connections[3] = s0.connect(remove_connection(3));
|
|
|
|
std::cout << "0 removes 1" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "023");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "023");
|
|
|
|
s0.disconnect_all_slots();
|
|
BOOST_CHECK(s0.empty());
|
|
|
|
connections[0] = s0.connect(remove_connection(0));
|
|
connections[1] = s0.connect(remove_connection(1, 3));
|
|
connections[2] = s0.connect(remove_connection(2));
|
|
connections[3] = s0.connect(remove_connection(3));
|
|
|
|
std::cout << "1 removes 3" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "012");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "012");
|
|
}
|
|
|
|
static void
|
|
test_bloodbath()
|
|
{
|
|
boost::signals2::signal<void ()> s0;
|
|
|
|
connections[0] = s0.connect(remove_connection(0, 1));
|
|
connections[1] = s0.connect(remove_connection(1, 1));
|
|
connections[2] = s0.connect(remove_connection(2, 0));
|
|
connections[3] = s0.connect(remove_connection(3, 2));
|
|
|
|
std::cout << "0 removes 1, 2 removes 0, 3 removes 2" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "023");
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "3");
|
|
}
|
|
|
|
static void
|
|
test_disconnect_equal()
|
|
{
|
|
boost::signals2::signal<void ()> s0;
|
|
|
|
connections[0] = s0.connect(remove_connection(0));
|
|
connections[1] = s0.connect(remove_connection(1));
|
|
connections[2] = s0.connect(remove_connection(2));
|
|
connections[3] = s0.connect(remove_connection(3));
|
|
|
|
std::cout << "Deleting 2" << std::endl;
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
BOOST_CHECK(test_output == "0123");
|
|
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
connections[2].disconnect();
|
|
#else
|
|
s0.disconnect(remove_connection(2));
|
|
#endif
|
|
|
|
test_output = "";
|
|
s0(); std::cout << std::endl;
|
|
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();
|
|
test_remove_prior();
|
|
test_remove_after();
|
|
test_bloodbath();
|
|
test_disconnect_equal();
|
|
test_signal_deletion();
|
|
return 0;
|
|
}
|