summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/signals2
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/signals2')
-rw-r--r--src/boost/libs/signals2/CMakeLists.txt41
-rw-r--r--src/boost/libs/signals2/Jamfile11
-rw-r--r--src/boost/libs/signals2/LICENSE23
-rw-r--r--src/boost/libs/signals2/README.md35
-rw-r--r--src/boost/libs/signals2/example/CMakeLists.txt24
-rw-r--r--src/boost/libs/signals2/example/Jamfile.v242
-rw-r--r--src/boost/libs/signals2/example/custom_combiners.cpp109
-rw-r--r--src/boost/libs/signals2/example/disconnect_and_block.cpp114
-rw-r--r--src/boost/libs/signals2/example/doc_view.cpp115
-rw-r--r--src/boost/libs/signals2/example/doc_view_acm.cpp127
-rw-r--r--src/boost/libs/signals2/example/doc_view_acm_deconstruct.cpp135
-rw-r--r--src/boost/libs/signals2/example/extended_slot.cpp42
-rw-r--r--src/boost/libs/signals2/example/hello_world_multi_slot.cpp47
-rw-r--r--src/boost/libs/signals2/example/hello_world_slot.cpp40
-rw-r--r--src/boost/libs/signals2/example/ordering_slots.cpp62
-rw-r--r--src/boost/libs/signals2/example/passing_slots.cpp55
-rw-r--r--src/boost/libs/signals2/example/postconstructor_ex1.cpp45
-rw-r--r--src/boost/libs/signals2/example/postconstructor_ex2.cpp55
-rw-r--r--src/boost/libs/signals2/example/predestructor_example.cpp52
-rw-r--r--src/boost/libs/signals2/example/signal_return_value.cpp38
-rw-r--r--src/boost/libs/signals2/example/slot_arguments.cpp57
-rw-r--r--src/boost/libs/signals2/index.html13
-rw-r--r--src/boost/libs/signals2/meta/libraries.json15
-rw-r--r--src/boost/libs/signals2/test/Jamfile.v251
-rw-r--r--src/boost/libs/signals2/test/connection_test.cpp130
-rw-r--r--src/boost/libs/signals2/test/dead_slot_test.cpp47
-rw-r--r--src/boost/libs/signals2/test/deadlock_regression_test.cpp109
-rw-r--r--src/boost/libs/signals2/test/deconstruct_test.cpp174
-rw-r--r--src/boost/libs/signals2/test/deletion_test.cpp297
-rw-r--r--src/boost/libs/signals2/test/invocation_benchmark.cpp60
-rw-r--r--src/boost/libs/signals2/test/mutex_test.cpp292
-rw-r--r--src/boost/libs/signals2/test/ordering_test.cpp128
-rw-r--r--src/boost/libs/signals2/test/regression_test.cpp109
-rw-r--r--src/boost/libs/signals2/test/shared_connection_block_test.cpp112
-rw-r--r--src/boost/libs/signals2/test/signal_n_test.cpp352
-rw-r--r--src/boost/libs/signals2/test/signal_test.cpp348
-rw-r--r--src/boost/libs/signals2/test/signal_type_test.cpp43
-rw-r--r--src/boost/libs/signals2/test/slot_compile_test.cpp27
-rw-r--r--src/boost/libs/signals2/test/threading_models_test.cpp86
-rw-r--r--src/boost/libs/signals2/test/track_test.cpp167
-rw-r--r--src/boost/libs/signals2/test/trackable_test.cpp112
41 files changed, 3941 insertions, 0 deletions
diff --git a/src/boost/libs/signals2/CMakeLists.txt b/src/boost/libs/signals2/CMakeLists.txt
new file mode 100644
index 000000000..3755a5628
--- /dev/null
+++ b/src/boost/libs/signals2/CMakeLists.txt
@@ -0,0 +1,41 @@
+# Copyright 2019 Mike Dev
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
+#
+# NOTE: CMake support for Boost.Signals2 is currently experimental at best
+# and the interface is likely to change in the future
+
+cmake_minimum_required( VERSION 3.5...3.16 )
+project( BoostSignals2 LANGUAGES CXX)
+
+option( BOOST_SIGNALS2_INCLUDE_EXAMPLES "Add boost signals2 examples" OFF )
+
+add_library( boost_signals2 INTERFACE )
+add_library( Boost::signals2 ALIAS boost_signals2 )
+
+target_include_directories( boost_signals2 INTERFACE include )
+
+target_link_libraries( boost_signals2
+ INTERFACE
+ Boost::assert
+ Boost::bind
+ Boost::config
+ Boost::core
+ Boost::function
+ Boost::iterator
+ Boost::mpl
+ Boost::optional
+ Boost::parameter
+ Boost::predef
+ Boost::preprocessor
+ Boost::smart_ptr
+ Boost::throw_exception
+ Boost::tuple
+ Boost::type_traits
+ Boost::variant
+)
+
+if( BOOST_SIGNALS2_INCLUDE_EXAMPLES )
+ add_subdirectory( example )
+endif()
+
diff --git a/src/boost/libs/signals2/Jamfile b/src/boost/libs/signals2/Jamfile
new file mode 100644
index 000000000..d88704f2e
--- /dev/null
+++ b/src/boost/libs/signals2/Jamfile
@@ -0,0 +1,11 @@
+# Boost.Signals2 Library Jamfile
+#
+# Copyright (c) 2018 James E. King III
+#
+# Use, modification, and distribution are 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)
+
+# please order by name to ease maintenance
+build-project example ;
+build-project test ;
diff --git a/src/boost/libs/signals2/LICENSE b/src/boost/libs/signals2/LICENSE
new file mode 100644
index 000000000..36b7cd93c
--- /dev/null
+++ b/src/boost/libs/signals2/LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/src/boost/libs/signals2/README.md b/src/boost/libs/signals2/README.md
new file mode 100644
index 000000000..9c5621ba0
--- /dev/null
+++ b/src/boost/libs/signals2/README.md
@@ -0,0 +1,35 @@
+Signals2, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), is an implementation of a managed signals and slots system.
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+
+### Properties
+
+* C++03
+* Header-Only
+
+### Build Status
+
+Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests |
+:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- |
+[`master`](https://github.com/boostorg/signals2/tree/master) | [![Build Status](https://travis-ci.org/boostorg/signals2.svg?branch=master)](https://travis-ci.org/boostorg/signals2) | [![Build status](https://ci.appveyor.com/api/projects/status/vjbstowu1s13x4l5/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/signals2-db91c/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15884/badge.svg)](https://scan.coverity.com/projects/boostorg-signals2) | [![codecov](https://codecov.io/gh/boostorg/signals2/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/signals2/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/signals2.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/signals2.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/signals2.html)
+[`develop`](https://github.com/boostorg/signals2/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/signals2.svg?branch=develop)](https://travis-ci.org/boostorg/signals2) | [![Build status](https://ci.appveyor.com/api/projects/status/vjbstowu1s13x4l5/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/signals2-db91c/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15884/badge.svg)](https://scan.coverity.com/projects/boostorg-signals2) | [![codecov](https://codecov.io/gh/boostorg/signals2/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/signals2/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/signals2.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/signals2.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/signals2.html)
+
+### Directories
+
+| Name | Purpose |
+| ----------- | ------------------------------ |
+| `ci` | continuous integration scripts |
+| `doc` | documentation |
+| `example` | examples |
+| `include` | headers |
+| `test` | unit tests |
+
+### More information
+
+* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-signals2)
+* [Report bugs](https://github.com/boostorg/signals2/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
+* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[signals2]` tag at the beginning of the subject line.
+
diff --git a/src/boost/libs/signals2/example/CMakeLists.txt b/src/boost/libs/signals2/example/CMakeLists.txt
new file mode 100644
index 000000000..3b42e58d8
--- /dev/null
+++ b/src/boost/libs/signals2/example/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright 2019 Mike Dev
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
+#
+# NOTE: CMake support for Boost.Signals2 is currently experimental at best
+# and the interface is likely to change in the future
+
+file( GLOB example_src_files *.cpp )
+
+find_package(Threads REQUIRED)
+
+foreach( file IN LISTS example_src_files )
+
+ get_filename_component( example_name ${file} NAME_WE )
+
+ add_executable( boost_signals2_example_${example_name} ${file} )
+ target_link_libraries( boost_signals2_example_${example_name}
+ PUBLIC
+ Boost::signals2
+ Boost::io
+ Threads::Threads
+ )
+
+endforeach()
diff --git a/src/boost/libs/signals2/example/Jamfile.v2 b/src/boost/libs/signals2/example/Jamfile.v2
new file mode 100644
index 000000000..079ad4432
--- /dev/null
+++ b/src/boost/libs/signals2/example/Jamfile.v2
@@ -0,0 +1,42 @@
+# Boost.Signals2 example programs
+
+# Copyright Michael Caisse 2010
+# 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
+
+project : requirements <implicit-dependency>/boost//headers ;
+
+exe hello_world_slot : hello_world_slot.cpp ;
+
+exe hello_world_multi_slot : hello_world_multi_slot.cpp ;
+
+exe ordering_slots : ordering_slots.cpp ;
+
+exe passing_slots : passing_slots.cpp ;
+
+exe extended_slot : extended_slot.cpp ;
+
+exe custom_combiners : custom_combiners.cpp ;
+
+exe disconnect_and_block : disconnect_and_block.cpp ;
+
+exe doc_view : doc_view.cpp ;
+
+exe doc_view_acm : doc_view_acm.cpp ;
+
+exe doc_view_acm_deconstruct : doc_view_acm_deconstruct.cpp ;
+
+exe postconstructor_ex1 : postconstructor_ex1.cpp ;
+
+exe postconstructor_ex2 : postconstructor_ex2.cpp ;
+
+exe predestructor_example : predestructor_example.cpp ;
+
+exe signal_return_value : signal_return_value.cpp ;
+
+exe slot_arguments : slot_arguments.cpp ;
+
diff --git a/src/boost/libs/signals2/example/custom_combiners.cpp b/src/boost/libs/signals2/example/custom_combiners.cpp
new file mode 100644
index 000000000..72e43b760
--- /dev/null
+++ b/src/boost/libs/signals2/example/custom_combiners.cpp
@@ -0,0 +1,109 @@
+// Example program showing signals with custom combiners.
+//
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+#include <vector>
+
+float product(float x, float y) { return x * y; }
+float quotient(float x, float y) { return x / y; }
+float sum(float x, float y) { return x + y; }
+float difference(float x, float y) { return x - y; }
+
+//[ custom_combiners_maximum_def_code_snippet
+// combiner which returns the maximum value returned by all slots
+template<typename T>
+struct maximum
+{
+ typedef T result_type;
+
+ template<typename InputIterator>
+ T operator()(InputIterator first, InputIterator last) const
+ {
+ // If there are no slots to call, just return the
+ // default-constructed value
+ if(first == last ) return T();
+ T max_value = *first++;
+ while (first != last) {
+ if (max_value < *first)
+ max_value = *first;
+ ++first;
+ }
+
+ return max_value;
+ }
+};
+//]
+
+void maximum_combiner_example()
+{
+ // signal which uses our custom "maximum" combiner
+ boost::signals2::signal<float (float x, float y), maximum<float> > sig;
+
+//[ custom_combiners_maximum_usage_code_snippet
+ sig.connect(&product);
+ sig.connect(&quotient);
+ sig.connect(&sum);
+ sig.connect(&difference);
+
+ // Outputs the maximum value returned by the connected slots, in this case
+ // 15 from the product function.
+ std::cout << "maximum: " << sig(5, 3) << std::endl;
+//]
+}
+
+//[ custom_combiners_aggregate_values_def_code_snippet
+// aggregate_values is a combiner which places all the values returned
+// from slots into a container
+template<typename Container>
+struct aggregate_values
+{
+ typedef Container result_type;
+
+ template<typename InputIterator>
+ Container operator()(InputIterator first, InputIterator last) const
+ {
+ Container values;
+
+ while(first != last) {
+ values.push_back(*first);
+ ++first;
+ }
+ return values;
+ }
+};
+//]
+
+void aggregate_values_example()
+{
+ // signal which uses aggregate_values as its combiner
+ boost::signals2::signal<float (float, float),
+ aggregate_values<std::vector<float> > > sig;
+
+//[ custom_combiners_aggregate_values_usage_code_snippet
+ sig.connect(&quotient);
+ sig.connect(&product);
+ sig.connect(&sum);
+ sig.connect(&difference);
+
+ std::vector<float> results = sig(5, 3);
+ std::cout << "aggregate values: ";
+ std::copy(results.begin(), results.end(),
+ std::ostream_iterator<float>(std::cout, " "));
+ std::cout << "\n";
+//]
+}
+
+int main()
+{
+ maximum_combiner_example();
+ aggregate_values_example();
+}
diff --git a/src/boost/libs/signals2/example/disconnect_and_block.cpp b/src/boost/libs/signals2/example/disconnect_and_block.cpp
new file mode 100644
index 000000000..4478be005
--- /dev/null
+++ b/src/boost/libs/signals2/example/disconnect_and_block.cpp
@@ -0,0 +1,114 @@
+// Various simple examples involving disconnecting and blocking slots.
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+#include <boost/signals2/shared_connection_block.hpp>
+
+struct HelloWorld
+{
+ void operator()() const
+ {
+ std::cout << "Hello, World!" << std::endl;
+ }
+};
+
+void disconnect_example()
+{
+ boost::signals2::signal<void ()> sig;
+
+//[ disconnect_code_snippet
+ boost::signals2::connection c = sig.connect(HelloWorld());
+ std::cout << "c is connected\n";
+ sig(); // Prints "Hello, World!"
+
+ c.disconnect(); // Disconnect the HelloWorld object
+ std::cout << "c is disconnected\n";
+ sig(); // Does nothing: there are no connected slots
+//]
+}
+
+void block_example()
+{
+ boost::signals2::signal<void ()> sig;
+
+//[ block_code_snippet
+ boost::signals2::connection c = sig.connect(HelloWorld());
+ std::cout << "c is not blocked.\n";
+ sig(); // Prints "Hello, World!"
+
+ {
+ boost::signals2::shared_connection_block block(c); // block the slot
+ std::cout << "c is blocked.\n";
+ sig(); // No output: the slot is blocked
+ } // shared_connection_block going out of scope unblocks the slot
+ std::cout << "c is not blocked.\n";
+ sig(); // Prints "Hello, World!"}
+//]
+}
+
+struct ShortLived
+{
+ void operator()() const
+ {
+ std::cout << "Life is short!" << std::endl;
+ }
+};
+
+void scoped_connection_example()
+{
+ boost::signals2::signal<void ()> sig;
+
+//[ scoped_connection_code_snippet
+ {
+ boost::signals2::scoped_connection c(sig.connect(ShortLived()));
+ sig(); // will call ShortLived function object
+ } // scoped_connection goes out of scope and disconnects
+
+ sig(); // ShortLived function object no longer connected to sig
+//]
+}
+
+//[ disconnect_by_slot_def_code_snippet
+void foo() { std::cout << "foo"; }
+void bar() { std::cout << "bar\n"; }
+//]
+
+void disconnect_by_slot_example()
+{
+ boost::signals2::signal<void()> sig;
+
+//[ disconnect_by_slot_usage_code_snippet
+ sig.connect(&foo);
+ sig.connect(&bar);
+ sig();
+
+ // disconnects foo, but not bar
+ sig.disconnect(&foo);
+ sig();
+//]
+}
+
+int main()
+{
+ std::cout << "Disconnect example:\n";
+ disconnect_example();
+
+ std::cout << "\nBlock example:\n";
+ block_example();
+
+ std::cout << "\nScoped connection example:\n";
+ scoped_connection_example();
+
+ std::cout << "\nDisconnect by slot example:\n";
+ disconnect_by_slot_example();
+
+ return 0;
+}
diff --git a/src/boost/libs/signals2/example/doc_view.cpp b/src/boost/libs/signals2/example/doc_view.cpp
new file mode 100644
index 000000000..7ff1990e9
--- /dev/null
+++ b/src/boost/libs/signals2/example/doc_view.cpp
@@ -0,0 +1,115 @@
+// Document/View sample for Boost.Signals
+// Copyright Keith MacDonald 2005.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <string>
+#include <boost/signals2/signal.hpp>
+#include <boost/bind.hpp>
+
+//[ document_def_code_snippet
+class Document
+{
+public:
+ typedef boost::signals2::signal<void ()> signal_t;
+
+public:
+ Document()
+ {}
+
+ /* Connect a slot to the signal which will be emitted whenever
+ text is appended to the document. */
+ boost::signals2::connection connect(const signal_t::slot_type &subscriber)
+ {
+ return m_sig.connect(subscriber);
+ }
+
+ void append(const char* s)
+ {
+ m_text += s;
+ m_sig();
+ }
+
+ const std::string& getText() const
+ {
+ return m_text;
+ }
+
+private:
+ signal_t m_sig;
+ std::string m_text;
+};
+//]
+
+//[ text_view_def_code_snippet
+class TextView
+{
+public:
+ TextView(Document& doc): m_document(doc)
+ {
+ m_connection = m_document.connect(boost::bind(&TextView::refresh, this));
+ }
+
+ ~TextView()
+ {
+ m_connection.disconnect();
+ }
+
+ void refresh() const
+ {
+ std::cout << "TextView: " << m_document.getText() << std::endl;
+ }
+private:
+ Document& m_document;
+ boost::signals2::connection m_connection;
+};
+//]
+
+//[ hex_view_def_code_snippet
+class HexView
+{
+public:
+ HexView(Document& doc): m_document(doc)
+ {
+ m_connection = m_document.connect(boost::bind(&HexView::refresh, this));
+ }
+
+ ~HexView()
+ {
+ m_connection.disconnect();
+ }
+
+ void refresh() const
+ {
+ const std::string& s = m_document.getText();
+
+ std::cout << "HexView:";
+
+ for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
+ std::cout << ' ' << std::hex << static_cast<int>(*it);
+
+ std::cout << std::endl;
+ }
+private:
+ Document& m_document;
+ boost::signals2::connection m_connection;
+};
+//]
+
+//[ document_view_main_code_snippet
+int main(int argc, char* argv[])
+{
+ Document doc;
+ TextView v1(doc);
+ HexView v2(doc);
+
+ doc.append(argc == 2 ? argv[1] : "Hello world!");
+ return 0;
+}
+//]
diff --git a/src/boost/libs/signals2/example/doc_view_acm.cpp b/src/boost/libs/signals2/example/doc_view_acm.cpp
new file mode 100644
index 000000000..ffc790826
--- /dev/null
+++ b/src/boost/libs/signals2/example/doc_view_acm.cpp
@@ -0,0 +1,127 @@
+// Document/View sample for Boost.Signals2.
+// Expands on doc_view.cpp example by using automatic
+// connection management.
+//
+// Copyright Keith MacDonald 2005.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <string>
+#include <boost/bind.hpp>
+#include <boost/io/ios_state.hpp>
+#include <boost/signals2/signal.hpp>
+#include <boost/shared_ptr.hpp>
+
+class Document
+{
+public:
+ typedef boost::signals2::signal<void ()> signal_t;
+
+public:
+ Document()
+ {}
+
+ /* connect a slot to the signal which will be emitted whenever
+ text is appended to the document. */
+ boost::signals2::connection connect(const signal_t::slot_type &subscriber)
+ {
+ return m_sig.connect(subscriber);
+ }
+
+ void append(const char* s)
+ {
+ m_text += s;
+ m_sig();
+ }
+
+ const std::string& getText() const
+ {
+ return m_text;
+ }
+
+private:
+ signal_t m_sig;
+ std::string m_text;
+};
+
+class TextView
+{
+public:
+ // static factory function that sets up automatic connection tracking
+ static boost::shared_ptr<TextView> create(Document& doc)
+ {
+ boost::shared_ptr<TextView> new_view(new TextView(doc));
+ {
+ typedef Document::signal_t::slot_type slot_type;
+ slot_type myslot(&TextView::refresh, new_view.get());
+ doc.connect(myslot.track(new_view));
+ }
+ return new_view;
+ }
+
+ void refresh() const
+ {
+ std::cout << "TextView: " << m_document.getText() << std::endl;
+ }
+private:
+ // private constructor to force use of static factory function
+ TextView(Document &doc): m_document(doc)
+ {}
+
+ Document& m_document;
+};
+
+class HexView
+{
+public:
+ // static factory function that sets up automatic connection tracking
+ static boost::shared_ptr<HexView> create(Document& doc)
+ {
+ boost::shared_ptr<HexView> new_view(new HexView(doc));
+ {
+ typedef Document::signal_t::slot_type slot_type;
+ slot_type myslot(&HexView::refresh, new_view.get());
+ doc.connect(myslot.track(new_view));
+ }
+ return new_view;
+ }
+
+ void refresh() const
+ {
+ boost::io::ios_flags_saver ifs(std::cout);
+ const std::string& s = m_document.getText();
+
+ std::cout << "HexView:";
+
+ for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
+ std::cout << ' ' << std::hex << static_cast<int>(*it);
+
+ std::cout << std::endl;
+ }
+private:
+ // private constructor to force use of static factory function
+ HexView(Document& doc): m_document(doc)
+ {}
+
+ Document& m_document;
+};
+
+int main(int argc, char* argv[])
+{
+ Document doc;
+ boost::shared_ptr<TextView> v1 = TextView::create(doc);
+ boost::shared_ptr<HexView> v2 = HexView::create(doc);
+
+ doc.append(argc >= 2 ? argv[1] : "Hello world!");
+
+ v2.reset(); // destroy the HexView, automatically disconnecting
+ doc.append(" HexView should no longer be connected.");
+
+ return 0;
+}
diff --git a/src/boost/libs/signals2/example/doc_view_acm_deconstruct.cpp b/src/boost/libs/signals2/example/doc_view_acm_deconstruct.cpp
new file mode 100644
index 000000000..1855c7806
--- /dev/null
+++ b/src/boost/libs/signals2/example/doc_view_acm_deconstruct.cpp
@@ -0,0 +1,135 @@
+// Document/View sample for Boost.Signals2.
+// Expands on doc_view_acm.cpp example by using boost::signals2::deconstruct
+// as a post-constructing factory function.
+//
+// Copyright Keith MacDonald 2005.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <string>
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/signals2/deconstruct.hpp>
+#include <boost/signals2/signal.hpp>
+#include <boost/shared_ptr.hpp>
+
+class Document
+{
+public:
+ typedef boost::signals2::signal<void ()> signal_t;
+
+public:
+ Document()
+ {}
+
+ /* Connect a slot to the signal which will be emitted whenever
+ text is appended to the document. */
+ boost::signals2::connection connect(const signal_t::slot_type &subscriber)
+ {
+ return m_sig.connect(subscriber);
+ }
+
+ void append(const char* s)
+ {
+ m_text += s;
+ m_sig();
+ }
+
+ const std::string& getText() const
+ {
+ return m_text;
+ }
+
+private:
+ signal_t m_sig;
+ std::string m_text;
+};
+
+class TextView
+{
+public:
+ /* This adl_postconstruct function will be found
+ via argument-dependent lookup when using boost::signals2::deconstruct. */
+ template<typename T>
+ friend void adl_postconstruct(const boost::shared_ptr<T> &view_sp, TextView *view, Document& doc)
+ {
+ view->m_document = &doc;
+ {
+ typedef Document::signal_t::slot_type slot_type;
+ slot_type myslot(&TextView::refresh, view);
+ doc.connect(myslot.track(view_sp));
+ }
+ }
+
+ void refresh() const
+ {
+ std::cout << "TextView: " << m_document->getText() << std::endl;
+ }
+private:
+ // give boost::signals2::deconstruct access to private constructor
+ friend class boost::signals2::deconstruct_access;
+ // private constructor to force use of deconstruct
+ TextView() : m_document(0)
+ {}
+
+ Document* m_document;
+};
+
+class HexView
+{
+public:
+ /* This adl_postconstruct function will be found
+ via argument-dependent lookup when using boost::signals2::deconstruct. */
+ template<typename T>
+ friend void adl_postconstruct(const boost::shared_ptr<T> &view_sp, HexView *view, Document& doc)
+ {
+ view->m_document = &doc;
+ {
+ typedef Document::signal_t::slot_type slot_type;
+ slot_type myslot(&HexView::refresh, view);
+ doc.connect(myslot.track(view_sp));
+ }
+ }
+
+ void refresh() const
+ {
+ const std::string& s = m_document->getText();
+
+ std::cout << "HexView:";
+
+ for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
+ std::cout << ' ' << std::hex << static_cast<int>(*it);
+
+ std::cout << std::endl;
+ }
+private:
+ // give boost::signals2::deconstruct access to private constructor
+ friend class boost::signals2::deconstruct_access;
+ // private constructor to force use of deconstruct
+ HexView(): m_document(0)
+ {}
+
+ Document* m_document;
+};
+
+namespace bs2 = boost::signals2;
+
+int main(int argc, char* argv[])
+{
+ Document doc;
+ boost::shared_ptr<TextView> v1 = bs2::deconstruct<TextView>().postconstruct(boost::ref(doc));
+ boost::shared_ptr<HexView> v2 = bs2::deconstruct<HexView>().postconstruct(boost::ref(doc));
+
+ doc.append(argc >= 2 ? argv[1] : "Hello world!");
+
+ v2.reset(); // destroy the HexView, automatically disconnecting
+ doc.append(" HexView should no longer be connected.");
+
+ return 0;
+}
diff --git a/src/boost/libs/signals2/example/extended_slot.cpp b/src/boost/libs/signals2/example/extended_slot.cpp
new file mode 100644
index 000000000..40699e53c
--- /dev/null
+++ b/src/boost/libs/signals2/example/extended_slot.cpp
@@ -0,0 +1,42 @@
+// Example program for connecting an extended slot,
+// using a signal's connect_extended and extended_slot_type.
+//
+// Copyright Frank Mori Hess 2009.
+//
+// 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/signals2/signal.hpp>
+#include <iostream>
+#include <string>
+
+namespace bs2 = boost::signals2;
+
+void single_shot_slot(const bs2::connection &conn, const std::string &message)
+{
+ conn.disconnect();
+ std::cout << message;
+}
+
+int main()
+{
+ typedef bs2::signal<void (void)> sig_type;
+ sig_type sig;
+ {
+ sig_type::extended_slot_type hello(&single_shot_slot, _1, "Hello");
+ sig.connect_extended(hello);
+ }
+ sig(); // prints "Hello"
+ {
+ sig_type::extended_slot_type world(&single_shot_slot, _1, ", World!\n");
+ sig.connect_extended(world);
+ }
+ sig(); // only prints ", World!\n" since hello slot has disconnected itself
+ sig(); // prints nothing, world slot has disconnected itself
+
+ return 0;
+}
+
diff --git a/src/boost/libs/signals2/example/hello_world_multi_slot.cpp b/src/boost/libs/signals2/example/hello_world_multi_slot.cpp
new file mode 100644
index 000000000..f47835148
--- /dev/null
+++ b/src/boost/libs/signals2/example/hello_world_multi_slot.cpp
@@ -0,0 +1,47 @@
+// Multiple slot hello world example for Boost.Signals2
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+
+//[ hello_def_code_snippet
+struct Hello
+{
+ void operator()() const
+ {
+ std::cout << "Hello";
+ }
+};
+//]
+
+//[ world_def_code_snippet
+struct World
+{
+ void operator()() const
+ {
+ std::cout << ", World!" << std::endl;
+ }
+};
+//]
+
+int main()
+{
+//[ hello_world_multi_code_snippet
+ boost::signals2::signal<void ()> sig;
+
+ sig.connect(Hello());
+ sig.connect(World());
+
+ sig();
+//]
+
+ return 0;
+}
+
diff --git a/src/boost/libs/signals2/example/hello_world_slot.cpp b/src/boost/libs/signals2/example/hello_world_slot.cpp
new file mode 100644
index 000000000..18e3c6a38
--- /dev/null
+++ b/src/boost/libs/signals2/example/hello_world_slot.cpp
@@ -0,0 +1,40 @@
+// Beginner hello world example for Boost.Signals2
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+
+//[ hello_world_def_code_snippet
+struct HelloWorld
+{
+ void operator()() const
+ {
+ std::cout << "Hello, World!" << std::endl;
+ }
+};
+//]
+
+int main()
+{
+//[ hello_world_single_code_snippet
+ // Signal with no arguments and a void return value
+ boost::signals2::signal<void ()> sig;
+
+ // Connect a HelloWorld slot
+ HelloWorld hello;
+ sig.connect(hello);
+
+ // Call all of the slots
+ sig();
+//]
+
+ return 0;
+}
+
diff --git a/src/boost/libs/signals2/example/ordering_slots.cpp b/src/boost/libs/signals2/example/ordering_slots.cpp
new file mode 100644
index 000000000..f69bc182c
--- /dev/null
+++ b/src/boost/libs/signals2/example/ordering_slots.cpp
@@ -0,0 +1,62 @@
+// Ordered slots hello world example for Boost.Signals2
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+
+struct Hello
+{
+ void operator()() const
+ {
+ std::cout << "Hello";
+ }
+};
+
+struct World
+{
+ void operator()() const
+ {
+ std::cout << ", World!" << std::endl;
+ }
+};
+
+//[ good_morning_def_code_snippet
+struct GoodMorning
+{
+ void operator()() const
+ {
+ std::cout << "... and good morning!" << std::endl;
+ }
+};
+//]
+
+int main()
+{
+//[ hello_world_ordered_code_snippet
+ boost::signals2::signal<void ()> sig;
+
+ sig.connect(1, World()); // connect with group 1
+ sig.connect(0, Hello()); // connect with group 0
+//]
+
+//[ hello_world_ordered_invoke_code_snippet
+ // by default slots are connected at the end of the slot list
+ sig.connect(GoodMorning());
+
+ // slots are invoked this order:
+ // 1) ungrouped slots connected with boost::signals2::at_front
+ // 2) grouped slots according to ordering of their groups
+ // 3) ungrouped slots connected with boost::signals2::at_back
+ sig();
+//]
+
+ return 0;
+}
+
diff --git a/src/boost/libs/signals2/example/passing_slots.cpp b/src/boost/libs/signals2/example/passing_slots.cpp
new file mode 100644
index 000000000..d2c098cb3
--- /dev/null
+++ b/src/boost/libs/signals2/example/passing_slots.cpp
@@ -0,0 +1,55 @@
+// Example program showing passing of slots through an interface.
+//
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+
+//[ passing_slots_defs_code_snippet
+// a pretend GUI button
+class Button
+{
+ typedef boost::signals2::signal<void (int x, int y)> OnClick;
+public:
+ typedef OnClick::slot_type OnClickSlotType;
+ // forward slots through Button interface to its private signal
+ boost::signals2::connection doOnClick(const OnClickSlotType & slot);
+
+ // simulate user clicking on GUI button at coordinates 52, 38
+ void simulateClick();
+private:
+ OnClick onClick;
+};
+
+boost::signals2::connection Button::doOnClick(const OnClickSlotType & slot)
+{
+ return onClick.connect(slot);
+}
+
+void Button::simulateClick()
+{
+ onClick(52, 38);
+}
+
+void printCoordinates(long x, long y)
+{
+ std::cout << "(" << x << ", " << y << ")\n";
+}
+//]
+
+int main()
+{
+//[ passing_slots_usage_code_snippet
+ Button button;
+ button.doOnClick(&printCoordinates);
+ button.simulateClick();
+//]
+ return 0;
+}
diff --git a/src/boost/libs/signals2/example/postconstructor_ex1.cpp b/src/boost/libs/signals2/example/postconstructor_ex1.cpp
new file mode 100644
index 000000000..89f684bba
--- /dev/null
+++ b/src/boost/libs/signals2/example/postconstructor_ex1.cpp
@@ -0,0 +1,45 @@
+// Minimal example of defining a postconstructor for a class which
+// uses boost::signals2::deconstruct as its factory function.
+//
+// Copyright Frank Mori Hess 2009.
+
+// 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/shared_ptr.hpp>
+#include <boost/signals2/deconstruct.hpp>
+#include <iostream>
+
+namespace bs2 = boost::signals2;
+
+namespace mynamespace
+{
+ class X
+ {
+ public:
+ /* This adl_postconstruct function will be found
+ via argument-dependent lookup when using boost::signals2::deconstruct. */
+ template<typename T> friend
+ void adl_postconstruct(const boost::shared_ptr<T> &, X *)
+ {
+ std::cout << "world!" << std::endl;
+ }
+ private:
+ friend class bs2::deconstruct_access; // give boost::signals2::deconstruct access to private constructor
+ // private constructor forces use of boost::signals2::deconstruct to create objects.
+ X()
+ {
+ std::cout << "Hello, ";
+ }
+ };
+}
+
+int main()
+{
+ // adl_postconstruct will be called during implicit conversion of return value to shared_ptr
+ boost::shared_ptr<mynamespace::X> x = bs2::deconstruct<mynamespace::X>();
+ return 0;
+}
diff --git a/src/boost/libs/signals2/example/postconstructor_ex2.cpp b/src/boost/libs/signals2/example/postconstructor_ex2.cpp
new file mode 100644
index 000000000..fdd1bd4ec
--- /dev/null
+++ b/src/boost/libs/signals2/example/postconstructor_ex2.cpp
@@ -0,0 +1,55 @@
+// An example of defining a postconstructor for a class which
+// uses boost::signals2::deconstruct as its factory function.
+// This example expands on the basic postconstructor_ex1.cpp example
+// by passing arguments to the constructor and postconstructor.
+//
+// Copyright Frank Mori Hess 2009.
+
+// 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/shared_ptr.hpp>
+#include <boost/signals2/deconstruct.hpp>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+namespace bs2 = boost::signals2;
+
+namespace mynamespace
+{
+ class Y
+ {
+ public:
+ /* This adl_postconstruct function will be found
+ via argument-dependent lookup when using boost::signals2::deconstruct. */
+ template<typename T> friend
+ void adl_postconstruct(const boost::shared_ptr<T> &, Y *y, const std::string &text)
+ {
+ y->_text_stream << text;
+ }
+ void print() const
+ {
+ std::cout << _text_stream.str() << std::endl;
+ }
+ private:
+ friend class bs2::deconstruct_access; // give boost::signals2::deconstruct access to private constructor
+ // private constructor forces use of boost::signals2::deconstruct to create objects.
+ Y(const std::string &text)
+ {
+ _text_stream << text;
+ }
+
+ std::ostringstream _text_stream;
+ };
+}
+
+int main()
+{
+ boost::shared_ptr<mynamespace::Y> y = bs2::deconstruct<mynamespace::Y>("Hello, ").postconstruct("world!");
+ y->print();
+ return 0;
+}
diff --git a/src/boost/libs/signals2/example/predestructor_example.cpp b/src/boost/libs/signals2/example/predestructor_example.cpp
new file mode 100644
index 000000000..6f10195e5
--- /dev/null
+++ b/src/boost/libs/signals2/example/predestructor_example.cpp
@@ -0,0 +1,52 @@
+// Minimal example of defining a predestructor for a class which
+// uses boost::signals2::deconstruct as its factory function.
+//
+// Copyright Frank Mori Hess 2009.
+
+// 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/shared_ptr.hpp>
+#include <boost/signals2/deconstruct.hpp>
+#include <iostream>
+
+namespace bs2 = boost::signals2;
+
+namespace mynamespace
+{
+ class X
+ {
+ public:
+ ~X()
+ {
+ std::cout << "cruel world!" << std::endl;
+ }
+ /* This adl_predestruct friend function will be found by
+ via argument-dependent lookup when using boost::signals2::deconstruct. */
+ friend void adl_predestruct(X *)
+ {
+ std::cout << "Goodbye, ";
+ }
+ /* boost::signals2::deconstruct always requires an adl_postconstruct function
+ which can be found via argument-dependent, so we define one which does nothing. */
+ template<typename T> friend
+ void adl_postconstruct(const boost::shared_ptr<T> &, X *)
+ {}
+ private:
+ friend class bs2::deconstruct_access; // give boost::signals2::deconstruct access to private constructor
+ // private constructor forces use of boost::signals2::deconstruct to create objects.
+ X()
+ {}
+ };
+}
+
+int main()
+{
+ {
+ boost::shared_ptr<mynamespace::X> x = bs2::deconstruct<mynamespace::X>();
+ }
+ return 0;
+}
diff --git a/src/boost/libs/signals2/example/signal_return_value.cpp b/src/boost/libs/signals2/example/signal_return_value.cpp
new file mode 100644
index 000000000..163f29abf
--- /dev/null
+++ b/src/boost/libs/signals2/example/signal_return_value.cpp
@@ -0,0 +1,38 @@
+// Example program for returning a value from slots to signal invocation.
+//
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+
+//[ signal_return_value_slot_defs_code_snippet
+float product(float x, float y) { return x * y; }
+float quotient(float x, float y) { return x / y; }
+float sum(float x, float y) { return x + y; }
+float difference(float x, float y) { return x - y; }
+//]
+
+int main()
+{
+ boost::signals2::signal<float (float x, float y)> sig;
+
+//[ signal_return_value_main_code_snippet
+ sig.connect(&product);
+ sig.connect(&quotient);
+ sig.connect(&sum);
+ sig.connect(&difference);
+
+ // The default combiner returns a boost::optional containing the return
+ // value of the last slot in the slot list, in this case the
+ // difference function.
+ std::cout << *sig(5, 3) << std::endl;
+//]
+}
+
diff --git a/src/boost/libs/signals2/example/slot_arguments.cpp b/src/boost/libs/signals2/example/slot_arguments.cpp
new file mode 100644
index 000000000..86c49cb6f
--- /dev/null
+++ b/src/boost/libs/signals2/example/slot_arguments.cpp
@@ -0,0 +1,57 @@
+// Example program for passing arguments from signal invocations to slots.
+//
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2009.
+//
+// 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 <iostream>
+#include <boost/signals2/signal.hpp>
+
+//[ slot_arguments_slot_defs_code_snippet
+void print_args(float x, float y)
+{
+ std::cout << "The arguments are " << x << " and " << y << std::endl;
+}
+
+void print_sum(float x, float y)
+{
+ std::cout << "The sum is " << x + y << std::endl;
+}
+
+void print_product(float x, float y)
+{
+ std::cout << "The product is " << x * y << std::endl;
+}
+
+void print_difference(float x, float y)
+{
+ std::cout << "The difference is " << x - y << std::endl;
+}
+
+void print_quotient(float x, float y)
+{
+ std::cout << "The quotient is " << x / y << std::endl;
+}
+//]
+
+int main()
+{
+//[ slot_arguments_main_code_snippet
+ boost::signals2::signal<void (float, float)> sig;
+
+ sig.connect(&print_args);
+ sig.connect(&print_sum);
+ sig.connect(&print_product);
+ sig.connect(&print_difference);
+ sig.connect(&print_quotient);
+
+ sig(5., 3.);
+//]
+ return 0;
+}
+
diff --git a/src/boost/libs/signals2/index.html b/src/boost/libs/signals2/index.html
new file mode 100644
index 000000000..53a66dffa
--- /dev/null
+++ b/src/boost/libs/signals2/index.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../doc/html/signals2.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../../doc/html/signals2.html">../../doc/html/signals2.html</a> &nbsp;<hr>
+<p>© Copyright Beman Dawes, 2001</p>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
+file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
+at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/src/boost/libs/signals2/meta/libraries.json b/src/boost/libs/signals2/meta/libraries.json
new file mode 100644
index 000000000..cb5e0654f
--- /dev/null
+++ b/src/boost/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/src/boost/libs/signals2/test/Jamfile.v2 b/src/boost/libs/signals2/test/Jamfile.v2
new file mode 100644
index 000000000..aacb3a4ce
--- /dev/null
+++ b/src/boost/libs/signals2/test/Jamfile.v2
@@ -0,0 +1,51 @@
+# Boost.Signals2 Library
+
+# Copyright Douglas Gregor 2001-2003.
+# Copyright Frank Mori Hess 2009.
+# 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
+
+# bring in rules for testing
+import testing ;
+
+project
+ : source-location .
+ : requirements
+ <hardcode-dll-paths>true
+# <library>/boost/test//boost_unit_test_framework
+# <link>static
+ ;
+
+rule thread-run ( sources )
+{
+ return
+ [ run $(sources) : : : <library>/boost/thread//boost_thread/
+ <threading>multi ]
+ ;
+}
+
+{
+ test-suite signals2
+ :
+ [ run connection_test.cpp ]
+ [ run dead_slot_test.cpp ]
+ [ run deadlock_regression_test.cpp ]
+ [ run deconstruct_test.cpp ]
+ [ run deletion_test.cpp ]
+ [ thread-run mutex_test.cpp ]
+ [ run ordering_test.cpp ]
+ [ run regression_test.cpp ]
+ [ run shared_connection_block_test.cpp ]
+ [ run signal_n_test.cpp ]
+ [ run signal_test.cpp ]
+ [ run signal_type_test.cpp ]
+ [ run slot_compile_test.cpp ]
+ [ thread-run threading_models_test.cpp ]
+ [ run trackable_test.cpp ]
+ [ run track_test.cpp ]
+ ;
+}
diff --git a/src/boost/libs/signals2/test/connection_test.cpp b/src/boost/libs/signals2/test/connection_test.cpp
new file mode 100644
index 000000000..bfe0894bc
--- /dev/null
+++ b/src/boost/libs/signals2/test/connection_test.cpp
@@ -0,0 +1,130 @@
+// Signals2 library
+// tests for connection class
+
+// Copyright Frank Mori Hess 2008
+// 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/signals2.hpp>
+#define BOOST_TEST_MODULE connection_test
+#include <boost/test/included/unit_test.hpp>
+
+namespace bs2 = boost::signals2;
+
+typedef bs2::signal<void ()> sig_type;
+
+void myslot()
+{}
+
+void swap_test()
+{
+ sig_type sig;
+
+ {
+ bs2::connection conn1 = sig.connect(&myslot);
+ BOOST_CHECK(conn1.connected());
+ bs2::connection conn2;
+ BOOST_CHECK(conn2.connected() == false);
+
+ conn1.swap(conn2);
+ BOOST_CHECK(conn2.connected());
+ BOOST_CHECK(conn1.connected() == false);
+
+ swap(conn1, conn2);
+ BOOST_CHECK(conn1.connected());
+ BOOST_CHECK(conn2.connected() == false);
+ }
+
+ {
+ bs2::scoped_connection conn1;
+ conn1 = sig.connect(&myslot);
+ BOOST_CHECK(conn1.connected());
+ bs2::scoped_connection conn2;
+ BOOST_CHECK(conn2.connected() == false);
+
+ conn1.swap(conn2);
+ BOOST_CHECK(conn2.connected());
+ BOOST_CHECK(conn1.connected() == false);
+
+ swap(conn1, conn2);
+ BOOST_CHECK(conn1.connected());
+ BOOST_CHECK(conn2.connected() == false);
+ }
+}
+
+void release_test()
+{
+ sig_type sig;
+ bs2::connection conn;
+ {
+ bs2::scoped_connection scoped(sig.connect(&myslot));
+ BOOST_CHECK(scoped.connected());
+ conn = scoped.release();
+ }
+ BOOST_CHECK(conn.connected());
+
+ bs2::connection conn2;
+ {
+ bs2::scoped_connection scoped(conn);
+ BOOST_CHECK(scoped.connected());
+ conn = scoped.release();
+ BOOST_CHECK(conn.connected());
+ BOOST_CHECK(scoped.connected() == false);
+ conn.disconnect();
+
+ // earlier release shouldn't affect new connection
+ conn2 = sig.connect(&myslot);
+ scoped = conn2;
+ }
+ 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)
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ release_test();
+ swap_test();
+ move_test();
+}
diff --git a/src/boost/libs/signals2/test/dead_slot_test.cpp b/src/boost/libs/signals2/test/dead_slot_test.cpp
new file mode 100644
index 000000000..b1ec1d5a0
--- /dev/null
+++ b/src/boost/libs/signals2/test/dead_slot_test.cpp
@@ -0,0 +1,47 @@
+// Boost.Signals library
+
+// Copyright (C) Douglas Gregor 2001-2006. 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/bind/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
+#define BOOST_TEST_MODULE dead_slot_test
+#include <boost/test/included/unit_test.hpp>
+
+using namespace boost::placeholders;
+
+typedef boost::signals2::signal<int (int)> sig_type;
+
+class with_constant {
+public:
+ with_constant(int c) : constant(c) {}
+
+ int add(int i) { return i + constant; }
+
+private:
+ int constant;
+};
+
+void do_delayed_connect(boost::shared_ptr<with_constant> &wc,
+ sig_type& sig,
+ sig_type::slot_type slot)
+{
+ // Should invalidate the slot, so that we cannot connect to it
+ wc.reset();
+
+ boost::signals2::connection c = sig.connect(slot);
+ BOOST_CHECK(!c.connected());
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ sig_type s1;
+ boost::shared_ptr<with_constant> wc1(new with_constant(7));
+
+ do_delayed_connect(wc1, s1, sig_type::slot_type(&with_constant::add, wc1.get(), _1).track(wc1));
+}
diff --git a/src/boost/libs/signals2/test/deadlock_regression_test.cpp b/src/boost/libs/signals2/test/deadlock_regression_test.cpp
new file mode 100644
index 000000000..ac9d89190
--- /dev/null
+++ b/src/boost/libs/signals2/test/deadlock_regression_test.cpp
@@ -0,0 +1,109 @@
+// Signals2 library
+//
+// Regression test based on bug report from Arian Alin Radu.
+// The problem was that tracked objects could be released
+// while holding the signal mutex during signal invocation.
+// This could result in a recursive
+// lock attempt if the tracked object manipulates the signal
+// in its destructor.
+
+// Copyright Frank Mori Hess 2019
+// 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
+
+#define BOOST_TEST_MODULE signals2 deadlock regression test
+#include <boost/test/included/unit_test.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/signals2/signal.hpp>
+#include <boost/signals2/signal_type.hpp>
+
+namespace bs2 = boost::signals2;
+
+
+// dummy mutex that detects attempts to recursively lock
+class test_mutex
+{
+public:
+ test_mutex(): m_locked(false) {}
+ void lock()
+ {
+ BOOST_CHECK(m_locked == false);
+ m_locked = true;
+ }
+ bool try_lock()
+ {
+ if(m_locked) return false;
+ lock();
+ return true;
+ }
+ void unlock()
+ {
+ m_locked = false;
+ }
+private:
+ bool m_locked;
+};
+
+using namespace bs2::keywords;
+typedef bs2::signal_type<void(), mutex_type<test_mutex> >::type Signal;
+
+class SelfReference: private boost::noncopyable
+{
+public:
+ boost::shared_ptr<SelfReference> m_self;
+ boost::shared_ptr<Signal> m_signal;
+
+ boost::signals2::connection m_conReleaseSelf;
+ boost::signals2::connection m_conDoNothing;
+
+ SelfReference()
+ {
+ m_signal = boost::make_shared<Signal>();
+ }
+
+ ~SelfReference()
+ {
+ // the first slot (ReleaseSelf) has been called; now the trackable object (this)
+ // was released, while the second slot is locked
+ BOOST_CHECK(!m_conReleaseSelf.connected());
+ // the second slot is locked, and we enter a recursive (pthread: dead) lock
+ BOOST_CHECK(m_conDoNothing.connected());
+ m_conReleaseSelf.disconnect();
+ m_conDoNothing.disconnect();
+ // enter recursive (pthread: dead) lock again:
+ BOOST_CHECK(m_signal->empty());
+ }
+
+ void ReleaseSelf()
+ {
+ m_self.reset();
+ }
+
+ static void DoNothing()
+ {
+ }
+
+ static void Run()
+ {
+ boost::shared_ptr<Signal> signal;
+ {
+ boost::shared_ptr<SelfReference> obj = boost::make_shared<SelfReference>();
+ obj->m_self = obj;
+ signal = obj->m_signal;
+
+ obj->m_conReleaseSelf = signal->connect(Signal::slot_type(&SelfReference::ReleaseSelf, obj.get()).track(obj));
+ obj->m_conDoNothing = signal->connect(Signal::slot_type(&SelfReference::DoNothing));
+ }
+ (*signal)();
+ }
+};
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ SelfReference::Run();
+}
diff --git a/src/boost/libs/signals2/test/deconstruct_test.cpp b/src/boost/libs/signals2/test/deconstruct_test.cpp
new file mode 100644
index 000000000..96d9949e4
--- /dev/null
+++ b/src/boost/libs/signals2/test/deconstruct_test.cpp
@@ -0,0 +1,174 @@
+// Tests for boost::signals2::deconstruct_ptr and friends
+
+// Copyright Frank Mori Hess 2007-2008.
+// Distributed under 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)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2/deconstruct.hpp>
+#include <boost/signals2/deconstruct_ptr.hpp>
+#define BOOST_TEST_MODULE deconstruct_test
+#include <boost/test/included/unit_test.hpp>
+
+class X: public boost::signals2::postconstructible {
+public:
+ X(): _postconstructed(false)
+ {}
+ ~X()
+ {
+ BOOST_CHECK(_postconstructed);
+ }
+protected:
+ virtual void postconstruct()
+ {
+ BOOST_CHECK(!_postconstructed);
+ _postconstructed = true;
+ }
+ bool _postconstructed;
+};
+
+class Y: public boost::signals2::predestructible {
+public:
+ Y(): _predestructed(false)
+ {}
+ ~Y()
+ {
+ BOOST_CHECK(_predestructed);
+ }
+protected:
+ virtual void predestruct()
+ {
+ _predestructed = true;
+ }
+ bool _predestructed;
+};
+
+class Z: public X, public Y
+{};
+
+class by_deconstruct_only: public boost::signals2::postconstructible {
+public:
+ ~by_deconstruct_only()
+ {
+ BOOST_CHECK(_postconstructed);
+ }
+ int value;
+protected:
+ virtual void postconstruct()
+ {
+ BOOST_CHECK(!_postconstructed);
+ _postconstructed = true;
+ }
+ bool _postconstructed;
+private:
+ friend class boost::signals2::deconstruct_access;
+ by_deconstruct_only(int value_in):
+ value(value_in), _postconstructed(false)
+ {}
+};
+
+namespace mytest
+{
+ class A
+ {
+ public:
+ template<typename T> friend
+ void adl_postconstruct(const boost::shared_ptr<T> &sp, A *p)
+ {
+ BOOST_CHECK(!p->_postconstructed);
+ p->_postconstructed = true;
+ }
+ template<typename T> friend
+ void adl_postconstruct(const boost::shared_ptr<T> &sp, A *p, int val)
+ {
+ p->value = val;
+ BOOST_CHECK(!p->_postconstructed);
+ p->_postconstructed = true;
+ }
+ friend void adl_predestruct(A *p)
+ {
+ p->_predestructed = true;
+ }
+ ~A()
+ {
+ BOOST_CHECK(_postconstructed);
+ BOOST_CHECK(_predestructed);
+ }
+ int value;
+ private:
+ friend class boost::signals2::deconstruct_access;
+ A(int value_in = 0):
+ value(value_in),
+ _postconstructed(false),
+ _predestructed(false)
+ {}
+ bool _postconstructed;
+ bool _predestructed;
+ };
+}
+
+void deconstruct_ptr_test()
+{
+ {
+ boost::shared_ptr<X> x = boost::signals2::deconstruct_ptr(new X);
+ }
+ {
+ boost::shared_ptr<Y> x = boost::signals2::deconstruct_ptr(new Y);
+ }
+ {
+ boost::shared_ptr<Z> z = boost::signals2::deconstruct_ptr(new Z);
+ }
+}
+
+class deconstructed_esft : public boost::enable_shared_from_this<deconstructed_esft>
+{
+public:
+ deconstructed_esft() : x(0) {}
+
+private:
+ friend void adl_postconstruct(boost::shared_ptr<void>, deconstructed_esft *) {}
+ int x;
+};
+
+void deconstruct_test()
+{
+ {
+ boost::shared_ptr<X> x = boost::signals2::deconstruct<X>();
+ }
+ {
+ boost::shared_ptr<Y> x = boost::signals2::deconstruct<Y>();
+ }
+ {
+ boost::shared_ptr<Z> z = boost::signals2::deconstruct<Z>();
+ }
+ {
+ boost::shared_ptr<by_deconstruct_only> a = boost::signals2::deconstruct<by_deconstruct_only>(1);
+ BOOST_CHECK(a->value == 1);
+ }
+ {
+ boost::shared_ptr<mytest::A> a = boost::signals2::deconstruct<mytest::A>(1);
+ BOOST_CHECK(a->value == 1);
+ }
+ {// deconstruct const type
+ boost::shared_ptr<const mytest::A> a = boost::signals2::deconstruct<const mytest::A>(3);
+ BOOST_CHECK(a->value == 3);
+ }
+ {// passing arguments to postconstructor
+ boost::shared_ptr<mytest::A> a = boost::signals2::deconstruct<mytest::A>().postconstruct(2);
+ BOOST_CHECK(a->value == 2);
+ }
+ {// enable_shared_from_this with deconstruct
+ boost::shared_ptr<deconstructed_esft> a = boost::signals2::deconstruct<deconstructed_esft>();
+ BOOST_CHECK(!(a->shared_from_this() < a || a < a->shared_from_this()));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ deconstruct_ptr_test();
+ deconstruct_test();
+}
diff --git a/src/boost/libs/signals2/test/deletion_test.cpp b/src/boost/libs/signals2/test/deletion_test.cpp
new file mode 100644
index 000000000..577c8512a
--- /dev/null
+++ b/src/boost/libs/signals2/test/deletion_test.cpp
@@ -0,0 +1,297 @@
+// 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/signals2.hpp>
+#define BOOST_TEST_MODULE deletion_test
+#include <boost/test/included/unit_test.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);
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ test_remove_self();
+ test_remove_prior();
+ test_remove_after();
+ test_bloodbath();
+ test_disconnect_equal();
+ test_signal_deletion();
+}
diff --git a/src/boost/libs/signals2/test/invocation_benchmark.cpp b/src/boost/libs/signals2/test/invocation_benchmark.cpp
new file mode 100644
index 000000000..6a464fc52
--- /dev/null
+++ b/src/boost/libs/signals2/test/invocation_benchmark.cpp
@@ -0,0 +1,60 @@
+/* multi-threaded signal invocation benchmark */
+
+// Copyright Frank Mori Hess 2007-2008.
+// Distributed under 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)
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/bind/bind.hpp>
+#include <boost/signals2.hpp>
+#include <boost/thread/thread.hpp>
+
+using namespace boost::placeholders;
+
+typedef boost::signals2::signal<void ()> signal_type;
+
+void myslot()
+{
+/* std::cout << __FUNCTION__ << std::endl;
+ sleep(1);*/
+}
+
+void thread_initial(signal_type *signal, unsigned num_invocations)
+{
+ unsigned i;
+ for(i = 0; i < num_invocations; ++i)
+ {
+ (*signal)();
+ }
+}
+
+int main(int argc, const char **argv)
+{
+ if(argc < 3)
+ {
+ std::cerr << "usage: " << argv[0] << " <num threads> <num connections>" << std::endl;
+ return -1;
+ }
+ static const unsigned num_threads = std::strtol(argv[1], 0, 0);
+ static const unsigned num_connections = std::strtol(argv[2], 0, 0);
+ boost::thread_group threads;
+ signal_type sig;
+
+ std::cout << "Connecting " << num_connections << " connections to signal.\n";
+ unsigned i;
+ for(i = 0; i < num_connections; ++i)
+ {
+ sig.connect(&myslot);
+ }
+ const unsigned num_slot_invocations = 1000000;
+ const unsigned signal_invocations_per_thread = num_slot_invocations / (num_threads * num_connections);
+ std::cout << "Launching " << num_threads << " thread(s) to invoke signal " << signal_invocations_per_thread << " times per thread.\n";
+ for(i = 0; i < num_threads; ++i)
+ {
+ threads.create_thread(boost::bind(&thread_initial, &sig, signal_invocations_per_thread));
+ }
+ threads.join_all();
+ return 0;
+}
diff --git a/src/boost/libs/signals2/test/mutex_test.cpp b/src/boost/libs/signals2/test/mutex_test.cpp
new file mode 100644
index 000000000..8da2972a5
--- /dev/null
+++ b/src/boost/libs/signals2/test/mutex_test.cpp
@@ -0,0 +1,292 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// Copyright Frank Mori Hess 2009
+//
+// 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)
+
+// This is a simplified/modified version of libs/thread/test/test_mutex.cpp
+// added to test boost::signals2::mutex.
+// For more information, see http://www.boost.org
+
+// Note boost/test/minimal.hpp can cause windows.h to get included, which
+// can screw up our checks of _WIN32_WINNT if it is included
+// after boost/signals2/mutex.hpp. Frank Hess 2009-03-07.
+// We now use boost/test/included/unit_test.hpp, not sure if above still
+// applies, but might as well leave the include where it is.
+#define BOOST_TEST_MODULE mutex_test
+#include <boost/test/included/unit_test.hpp>
+
+#include <boost/bind/bind.hpp>
+#include <boost/signals2/dummy_mutex.hpp>
+#include <boost/signals2/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/condition.hpp>
+
+using namespace boost::placeholders;
+
+class execution_monitor
+{
+public:
+ execution_monitor(int secs)
+ : done(false), m_secs(secs) { }
+ void start()
+ {
+ boost::mutex::scoped_lock lock(mutex);
+ done = false;
+ }
+ void finish()
+ {
+ boost::mutex::scoped_lock lock(mutex);
+ done = true;
+ cond.notify_one();
+ }
+ bool wait()
+ {
+ boost::posix_time::time_duration timeout = boost::posix_time::seconds(m_secs);
+ boost::mutex::scoped_lock lock(mutex);
+ while (!done) {
+ if (!cond.timed_wait(lock, timeout))
+ break;
+ }
+ return done;
+ }
+
+private:
+ boost::mutex mutex;
+ boost::condition cond;
+ bool done;
+ int m_secs;
+};
+
+template <typename F>
+class indirect_adapter
+{
+public:
+ indirect_adapter(F func, execution_monitor& monitor)
+ : m_func(func), m_monitor(monitor) { }
+ void operator()() const
+ {
+ try
+ {
+ boost::thread thrd(m_func);
+ thrd.join();
+ }
+ catch (...)
+ {
+ m_monitor.finish();
+ throw;
+ }
+ m_monitor.finish();
+ }
+
+private:
+ F m_func;
+ execution_monitor& m_monitor;
+ void operator=(indirect_adapter&);
+};
+
+template <typename F>
+void timed_test(F func, int secs)
+{
+ execution_monitor monitor(secs);
+ indirect_adapter<F> ifunc(func, monitor);
+ monitor.start();
+ boost::thread thrd(ifunc);
+ BOOST_REQUIRE(monitor.wait()); // Timed test didn't complete in time, possible deadlock
+}
+
+template <typename M>
+struct test_lock
+{
+ typedef M mutex_type;
+ typedef typename boost::unique_lock<M> lock_type;
+
+ void operator()()
+ {
+ mutex_type mutex;
+ boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ lock_type lock(mutex, boost::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ // Construct a fast time out.
+ boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(100);
+
+ // Test the lock and the mutex with condition variables.
+ // No one is going to notify this condition variable. We expect to
+ // time out.
+ BOOST_CHECK(!condition.timed_wait(lock, timeout));
+ BOOST_CHECK(lock ? true : false);
+
+ // Test the lock and unlock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ }
+};
+
+template <typename M>
+struct test_trylock
+{
+ typedef M mutex_type;
+ typedef typename boost::unique_lock<M> lock_type;
+
+ void operator()()
+ {
+ mutex_type mutex;
+ boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ lock_type lock(mutex, boost::try_to_lock);
+ BOOST_CHECK(lock ? true : false);
+ }
+ {
+ lock_type lock(mutex, boost::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ lock_type lock(mutex, boost::try_to_lock);
+ BOOST_CHECK(lock ? true : false);
+
+ // Construct a fast time out.
+ boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(100);
+
+ // Test the lock and the mutex with condition variables.
+ // No one is going to notify this condition variable. We expect to
+ // time out.
+ BOOST_CHECK(!condition.timed_wait(lock, timeout));
+ BOOST_CHECK(lock ? true : false);
+
+ // Test the lock, unlock and trylock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ BOOST_CHECK(lock.try_lock());
+ BOOST_CHECK(lock ? true : false);
+ }
+};
+
+template<typename Mutex>
+struct test_lock_exclusion
+{
+ typedef boost::unique_lock<Mutex> Lock;
+
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_lock_exclusion():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+ typedef test_lock_exclusion<Mutex> this_type;
+
+ void do_test(void (this_type::*test_func)())
+ {
+ Lock lock(m);
+
+ {
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=false;
+ }
+
+ done=false;
+
+ boost::thread t(test_func,this);
+
+ try
+ {
+ {
+ boost::mutex::scoped_lock lk(done_mutex);
+ BOOST_CHECK(!done_cond.timed_wait(lk, boost::posix_time::seconds(1),
+ boost::bind(&this_type::is_done,this)));
+ }
+ lock.unlock();
+ {
+ boost::mutex::scoped_lock lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk, boost::posix_time::seconds(1),
+ boost::bind(&this_type::is_done,this)));
+ }
+ t.join();
+ BOOST_CHECK(locked);
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+
+
+ void operator()()
+ {
+ do_test(&this_type::locking_thread);
+ }
+};
+
+
+void do_test_mutex()
+{
+ test_lock<boost::signals2::mutex>()();
+// try_lock not supported on old versions of windows
+#if !defined(BOOST_HAS_WINTHREADS) || (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400))
+ test_trylock<boost::signals2::mutex>()();
+#endif
+ test_lock_exclusion<boost::signals2::mutex>()();
+}
+
+void test_mutex()
+{
+ timed_test(&do_test_mutex, 3);
+}
+
+void do_test_dummy_mutex()
+{
+ test_lock<boost::signals2::dummy_mutex>()();
+ test_trylock<boost::signals2::dummy_mutex>()();
+}
+
+void test_dummy_mutex()
+{
+ timed_test(&do_test_dummy_mutex, 2);
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ test_mutex();
+ test_dummy_mutex();
+}
diff --git a/src/boost/libs/signals2/test/ordering_test.cpp b/src/boost/libs/signals2/test/ordering_test.cpp
new file mode 100644
index 000000000..9636fb016
--- /dev/null
+++ b/src/boost/libs/signals2/test/ordering_test.cpp
@@ -0,0 +1,128 @@
+// Boost.Signals2 library
+
+// Copyright Douglas Gregor 2002-2004. 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/signals2.hpp>
+#define BOOST_TEST_MODULE ordering_test
+#include <boost/test/included/unit_test.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cstdlib>
+#include <ctime>
+#include <functional>
+
+std::vector<int> valuesOutput;
+bool ungrouped1 = false;
+bool ungrouped2 = false;
+bool ungrouped3 = false;
+
+struct emit_int {
+ emit_int(int v) : value(v) {}
+
+ void operator()() const
+ {
+ BOOST_CHECK(value == 42 || (!ungrouped1 && !ungrouped2 && !ungrouped3));
+ valuesOutput.push_back(value);
+ std::cout << value << ' ';
+ }
+
+private:
+ int value;
+};
+
+struct write_ungrouped1 {
+ void operator()() const
+ {
+ BOOST_CHECK(!ungrouped1);
+ ungrouped1 = true;
+ std::cout << "(Ungrouped #1)" << ' ';
+ }
+};
+
+struct write_ungrouped2 {
+ void operator()() const
+ {
+ BOOST_CHECK(!ungrouped2);
+ ungrouped2 = true;
+ std::cout << "(Ungrouped #2)" << ' ';
+ }
+};
+
+struct write_ungrouped3 {
+ void operator()() const
+ {
+ BOOST_CHECK(!ungrouped3);
+ ungrouped3 = true;
+ std::cout << "(Ungrouped #3)" << ' ';
+ }
+};
+
+int return_argument(int x)
+{
+ return x;
+}
+
+void test_group_compare()
+{
+ boost::signals2::signal
+ <
+ int (),
+ boost::signals2::last_value<int>,
+ int,
+ std::greater< int >
+ > sig;
+
+ sig.connect( 1, boost::bind( &return_argument, 1) );
+ sig.connect( 2, boost::bind( &return_argument, 2) );
+
+ BOOST_CHECK(sig() == 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ using namespace std;
+ srand(time(0));
+
+ std::vector<int> sortedValues;
+
+ boost::signals2::signal<void ()> sig;
+ sig.connect(write_ungrouped1());
+ for (int i = 0; i < 100; ++i) {
+#ifdef BOOST_NO_STDC_NAMESPACE
+ int v = rand() % 100;
+#else
+ int v = std::rand() % 100;
+#endif
+ sortedValues.push_back(v);
+ sig.connect(v, emit_int(v));
+
+ if (i == 50) {
+ sig.connect(write_ungrouped2());
+ }
+ }
+ sig.connect(write_ungrouped3());
+
+ std::sort(sortedValues.begin(), sortedValues.end());
+
+ // 17 at beginning, 42 at end
+ sortedValues.insert(sortedValues.begin(), 17);
+ sig.connect(emit_int(17), boost::signals2::at_front);
+ sortedValues.push_back(42);
+ sig.connect(emit_int(42));
+
+ sig();
+ std::cout << std::endl;
+
+ BOOST_CHECK(valuesOutput == sortedValues);
+ BOOST_CHECK(ungrouped1);
+ BOOST_CHECK(ungrouped2);
+ BOOST_CHECK(ungrouped3);
+
+ test_group_compare();
+}
diff --git a/src/boost/libs/signals2/test/regression_test.cpp b/src/boost/libs/signals2/test/regression_test.cpp
new file mode 100644
index 000000000..59187353c
--- /dev/null
+++ b/src/boost/libs/signals2/test/regression_test.cpp
@@ -0,0 +1,109 @@
+// thread_safe_signals library
+// Some assorted tests to expose various bugs that existed at some point,
+// to make sure they stay fixed
+
+// Copyright Frank Mori Hess 2008
+// 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/signals2.hpp>
+#define BOOST_TEST_MODULE regression_test
+#include <boost/test/included/unit_test.hpp>
+
+typedef boost::signals2::signal<void ()> sig0_type;
+
+// combiner that returns the number of slots invoked
+struct slot_counter {
+ typedef unsigned result_type;
+ template<typename InputIterator>
+ unsigned operator()(InputIterator first, InputIterator last) const
+ {
+ unsigned count = 0;
+ for (; first != last; ++first)
+ {
+ try
+ {
+ *first;
+ ++count;
+ }
+ catch(const boost::bad_weak_ptr &)
+ {}
+ }
+ return count;
+ }
+};
+
+void my_slot()
+{
+}
+
+void my_connecting_slot(sig0_type &sig)
+{
+ sig.connect(&my_slot);
+}
+
+void slot_connect_test()
+{
+ sig0_type sig;
+ sig.connect(sig0_type::slot_type(&my_connecting_slot, boost::ref(sig)).track(sig));
+ /* 2008-02-28: the following signal invocation triggered a (bogus) failed assertion of _shared_state.unique()
+ at detail/signal_template.hpp:285 */
+ sig();
+ BOOST_CHECK(sig.num_slots() == 2);
+ sig.disconnect(&my_slot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ /* 2008-03-11: checked iterator barfed on next line, due to bad semantics of copy construction
+ for boost::signals2::detail::grouped_list */
+ sig();
+ BOOST_CHECK(sig.num_slots() == 2);
+}
+
+/* 2008-03-10: we weren't disconnecting old connection in scoped_connection assignment operator */
+void scoped_connection_test()
+{
+ typedef boost::signals2::signal<void (), slot_counter> signal_type;
+ signal_type sig;
+ {
+ boost::signals2::scoped_connection conn(sig.connect(&my_slot));
+ BOOST_CHECK(sig() == 1);
+ conn = sig.connect(&my_slot);
+ BOOST_CHECK(sig() == 1);
+ }
+ BOOST_CHECK(sig() == 0);
+}
+
+// testsignal that returns a reference type
+
+struct ref_returner
+{
+ static int i;
+
+ int& ref_return_slot()
+ {
+ return i;
+ }
+};
+
+int ref_returner::i = 0;
+
+void reference_return_test()
+{
+ boost::signals2::signal<int& ()> rTest;
+ ref_returner rr;
+ rTest.connect(boost::bind(&ref_returner::ref_return_slot, &rr));
+ int& r = *rTest();
+ BOOST_CHECK(ref_returner::i == 0);
+ r = 1;
+ BOOST_CHECK(ref_returner::i == 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ slot_connect_test();
+ scoped_connection_test();
+ reference_return_test();
+}
diff --git a/src/boost/libs/signals2/test/shared_connection_block_test.cpp b/src/boost/libs/signals2/test/shared_connection_block_test.cpp
new file mode 100644
index 000000000..4ad5bdf33
--- /dev/null
+++ b/src/boost/libs/signals2/test/shared_connection_block_test.cpp
@@ -0,0 +1,112 @@
+// 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/array.hpp>
+#include <boost/signals2/shared_connection_block.hpp>
+#include <boost/signals2/signal.hpp>
+#define BOOST_TEST_MODULE shared_connection_block_test
+#include <boost/test/included/unit_test.hpp>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+static boost::array<boost::signals2::connection, 4> connections;
+
+static std::ostringstream test_output;
+
+struct test_slot {
+ explicit test_slot(int v = 0) : value(v)
+ {}
+
+ void operator()() const {
+ test_output << value;
+ }
+
+ int value;
+};
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ boost::signals2::signal<void ()> s0;
+
+ for(unsigned i = 0; i < connections.size(); ++i)
+ {
+ connections.at(i) = s0.connect(test_slot(i));
+ }
+
+
+ {
+ // Blocking 2
+ boost::signals2::shared_connection_block block(connections.at(2));
+ BOOST_CHECK(block.blocking());
+ test_output.str("");
+ s0();
+ BOOST_CHECK(test_output.str() == "013");
+ }
+
+ // Unblocking 2
+ test_output.str("");
+ s0();
+ BOOST_CHECK(test_output.str() == "0123");
+
+ {
+ // Blocking 1 through const connection
+ const boost::signals2::connection conn = connections.at(1);
+ boost::signals2::shared_connection_block block(conn);
+ test_output.str("");
+ s0();
+ std::cout << test_output.str() << std::endl;
+ BOOST_CHECK(test_output.str() == "023");
+ // Unblocking 1
+ block.unblock();
+ BOOST_CHECK(block.blocking() == false);
+ test_output.str("");
+ s0();
+ BOOST_CHECK(test_output.str() == "0123");
+ }
+
+ {
+ // initially unblocked
+ boost::signals2::shared_connection_block block(connections.at(3), false);
+ BOOST_CHECK(block.blocking() == false);
+ test_output.str("");
+ s0();
+ BOOST_CHECK(test_output.str() == "0123");
+ // block
+ block.block();
+ test_output.str("");
+ s0();
+ BOOST_CHECK(test_output.str() == "012");
+ }
+
+ {
+ // test default constructed block
+ boost::signals2::shared_connection_block block;
+ BOOST_CHECK(block.blocking() == true);
+ block.unblock();
+ BOOST_CHECK(block.blocking() == false);
+ block.block();
+ BOOST_CHECK(block.blocking() == true);
+
+ // test assignment
+ {
+ block.unblock();
+ boost::signals2::shared_connection_block block2(connections.at(0));
+ BOOST_CHECK(block.connection() != block2.connection());
+ BOOST_CHECK(block.blocking() != block2.blocking());
+ block = block2;
+ BOOST_CHECK(block.connection() == block2.connection());
+ BOOST_CHECK(block.blocking() == block2.blocking());
+ }
+ test_output.str("");
+ s0();
+ BOOST_CHECK(test_output.str() == "123");
+ }
+}
diff --git a/src/boost/libs/signals2/test/signal_n_test.cpp b/src/boost/libs/signals2/test/signal_n_test.cpp
new file mode 100644
index 000000000..c1c2b4027
--- /dev/null
+++ b/src/boost/libs/signals2/test/signal_n_test.cpp
@@ -0,0 +1,352 @@
+// Boost.Signals 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/bind/bind.hpp>
+#include <boost/config.hpp>
+#define BOOST_TEST_MODULE signal_n_test
+#include <boost/test/included/unit_test.hpp>
+
+using namespace boost::placeholders;
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+BOOST_AUTO_TEST_CASE(test_main)
+{
+}
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#include <boost/optional.hpp>
+#include <boost/ref.hpp>
+#include <boost/signals2.hpp>
+#include <functional>
+
+template<typename T>
+struct max_or_default {
+ typedef T result_type;
+ template<typename InputIterator>
+ typename InputIterator::value_type
+ operator()(InputIterator first, InputIterator last) const
+ {
+ boost::optional<T> max;
+ for (; first != last; ++first)
+ {
+ try
+ {
+ if(!max) max = *first;
+ else max = (*first > max.get())? *first : max;
+ }
+ catch(const boost::bad_weak_ptr &)
+ {}
+ }
+ if(max) return max.get();
+ return T();
+ }
+};
+
+struct make_int {
+ make_int(int n, int cn) : N(n), CN(n) {}
+ int operator()() { return N; }
+ int operator()() const { return CN; }
+
+ int N;
+ int CN;
+};
+
+template<int N>
+struct make_increasing_int {
+ make_increasing_int() : n(N) {}
+
+ int operator()() const { return n++; }
+
+ mutable int n;
+};
+
+int get_37() { return 37; }
+
+static void
+test_zero_args()
+{
+ make_int i42(42, 41);
+ make_int i2(2, 1);
+ make_int i72(72, 71);
+ make_int i63(63, 63);
+ make_int i62(62, 61);
+
+ {
+ boost::signals2::signal0<int, max_or_default<int>, std::string> s0;
+ boost::signals2::connection c2 = s0.connect(i2);
+ boost::signals2::connection c72 = s0.connect("72", i72);
+ boost::signals2::connection c62 = s0.connect("6x", i62);
+ boost::signals2::connection c42 = s0.connect(i42);
+ boost::signals2::connection c37 = s0.connect(&get_37);
+
+ BOOST_CHECK(s0() == 72);
+
+ s0.disconnect("72");
+ BOOST_CHECK(s0() == 62);
+
+ c72.disconnect(); // Double-disconnect should be safe
+ BOOST_CHECK(s0() == 62);
+
+ s0.disconnect("72"); // Triple-disconect should be safe
+ BOOST_CHECK(s0() == 62);
+
+ // Also connect 63 in the same group as 62
+ s0.connect("6x", i63);
+ BOOST_CHECK(s0() == 63);
+
+ // Disconnect all of the 60's
+ s0.disconnect("6x");
+ BOOST_CHECK(s0() == 42);
+
+ c42.disconnect();
+ BOOST_CHECK(s0() == 37);
+
+ c37.disconnect();
+ BOOST_CHECK(s0() == 2);
+
+ c2.disconnect();
+ BOOST_CHECK(s0() == 0);
+ }
+
+ {
+ boost::signals2::signal0<int, max_or_default<int> > s0;
+ boost::signals2::connection c2 = s0.connect(i2);
+ boost::signals2::connection c72 = s0.connect(i72);
+ boost::signals2::connection c62 = s0.connect(i62);
+ boost::signals2::connection c42 = s0.connect(i42);
+
+ const boost::signals2::signal0<int, max_or_default<int> >& cs0 = s0;
+ BOOST_CHECK(cs0() == 72);
+ }
+
+ {
+ make_increasing_int<7> i7;
+ make_increasing_int<10> i10;
+
+ boost::signals2::signal0<int, max_or_default<int> > s0;
+ boost::signals2::connection c7 = s0.connect(i7);
+ boost::signals2::connection c10 = s0.connect(i10);
+
+ BOOST_CHECK(s0() == 10);
+ BOOST_CHECK(s0() == 11);
+ }
+}
+
+static void
+test_one_arg()
+{
+ boost::signals2::signal1<int, int, max_or_default<int> > s1;
+
+ s1.connect(std::negate<int>());
+ s1.connect(boost::bind(std::multiplies<int>(), 2, _1));
+
+ BOOST_CHECK(s1(1) == 2);
+ BOOST_CHECK(s1(-1) == 1);
+}
+
+static void
+test_signal_signal_connect()
+{
+ typedef boost::signals2::signal1<int, int, max_or_default<int> > signal_type;
+ signal_type s1;
+
+ s1.connect(std::negate<int>());
+
+ BOOST_CHECK(s1(3) == -3);
+
+ {
+ signal_type s2;
+ s1.connect(s2);
+ s2.connect(boost::bind(std::multiplies<int>(), 2, _1));
+ s2.connect(boost::bind(std::multiplies<int>(), -3, _1));
+
+ BOOST_CHECK(s2(-3) == 9);
+ BOOST_CHECK(s1(3) == 6);
+ } // s2 goes out of scope and disconnects
+
+ BOOST_CHECK(s1(3) == -3);
+
+ // test auto-track of signal wrapped in a reference_wrapper
+ {
+ signal_type s2;
+ s1.connect(boost::cref(s2));
+ s2.connect(boost::bind(std::multiplies<int>(), 2, _1));
+ s2.connect(boost::bind(std::multiplies<int>(), -3, _1));
+
+ BOOST_CHECK(s2(-3) == 9);
+ BOOST_CHECK(s1(3) == 6);
+ } // s2 goes out of scope and disconnects
+
+ BOOST_CHECK(s1(3) == -3);
+}
+
+struct EventCounter
+{
+ EventCounter() : count(0) {}
+
+ void operator()()
+ {
+ ++count;
+ }
+
+ int count;
+};
+
+static void
+test_ref()
+{
+ EventCounter ec;
+ boost::signals2::signal0<void> s;
+
+ {
+ boost::signals2::scoped_connection c(s.connect(boost::ref(ec)));
+ BOOST_CHECK(ec.count == 0);
+ s();
+ BOOST_CHECK(ec.count == 1);
+ }
+ s();
+ BOOST_CHECK(ec.count == 1);
+}
+
+static void test_default_combiner()
+{
+ boost::signals2::signal0<int> sig;
+ boost::optional<int> result;
+ result = sig();
+ BOOST_CHECK(!result);
+
+ sig.connect(make_int(0, 0));
+ result = sig();
+ BOOST_CHECK(result);
+ BOOST_CHECK(*result == 0);
+
+ sig.connect(make_int(1, 1));
+ result = sig();
+ BOOST_CHECK(result);
+ BOOST_CHECK(*result == 1);
+}
+
+template<typename ResultType>
+ ResultType disconnecting_slot(const boost::signals2::connection &conn, int)
+{
+ conn.disconnect();
+ return ResultType();
+}
+
+#ifdef BOOST_NO_VOID_RETURNS
+template<>
+ void disconnecting_slot<void>(const boost::signals2::connection &conn, int)
+{
+ conn.disconnect();
+ return;
+}
+#endif
+
+template<typename ResultType>
+ void test_extended_slot()
+{
+ {
+ typedef boost::signals2::signal1<ResultType, int> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
+ ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
+ slot_type myslot(fp);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig(0);
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
+ { // test 0 arg signal
+ typedef boost::signals2::signal0<ResultType> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
+ ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
+ slot_type myslot(fp, _1, 0);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig();
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
+ // test disconnection by slot
+ {
+ typedef boost::signals2::signal1<ResultType, int> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
+ ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
+ slot_type myslot(fp);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig.disconnect(fp);
+ 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);
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ test_zero_args();
+ test_one_arg();
+ test_signal_signal_connect();
+ test_ref();
+ test_default_combiner();
+ test_extended_slot<void>();
+ test_extended_slot<int>();
+ test_set_combiner();
+ test_swap();
+}
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
diff --git a/src/boost/libs/signals2/test/signal_test.cpp b/src/boost/libs/signals2/test/signal_test.cpp
new file mode 100644
index 000000000..3ae2817f7
--- /dev/null
+++ b/src/boost/libs/signals2/test/signal_test.cpp
@@ -0,0 +1,348 @@
+// Boost.Signals library
+
+// Copyright Frank Mori Hess 2008-2009.
+// 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/bind/bind.hpp>
+#include <boost/optional.hpp>
+#include <boost/signals2.hpp>
+#define BOOST_TEST_MODULE signal_test
+#include <boost/test/included/unit_test.hpp>
+#include <functional>
+#include <iostream>
+#include <typeinfo>
+
+using namespace boost::placeholders;
+
+template<typename T>
+struct max_or_default {
+ typedef T result_type;
+ template<typename InputIterator>
+ typename InputIterator::value_type
+ operator()(InputIterator first, InputIterator last) const
+ {
+ boost::optional<T> max;
+ for (; first != last; ++first)
+ {
+ try
+ {
+ if(!max) max = *first;
+ else max = (*first > max.get())? *first : max;
+ }
+ catch(const boost::bad_weak_ptr &)
+ {}
+ }
+ if(max) return max.get();
+ return T();
+ }
+};
+
+struct make_int {
+ make_int(int n, int cn) : N(n), CN(cn) {}
+
+ int operator()() { return N; }
+ int operator()() const { return CN; }
+
+ int N;
+ int CN;
+};
+
+template<int N>
+struct make_increasing_int {
+ make_increasing_int() : n(N) {}
+
+ int operator()() const { return n++; }
+
+ mutable int n;
+};
+
+static void
+test_zero_args()
+{
+ make_int i42(42, 41);
+ make_int i2(2, 1);
+ make_int i72(72, 71);
+ make_int i63(63, 63);
+ make_int i62(62, 61);
+
+ {
+ boost::signals2::signal<int (), max_or_default<int> > s0;
+
+ std::cout << "sizeof(signal) = " << sizeof(s0) << std::endl;
+ boost::signals2::connection c2 = s0.connect(i2);
+ boost::signals2::connection c72 = s0.connect(72, i72);
+ boost::signals2::connection c62 = s0.connect(60, i62);
+ boost::signals2::connection c42 = s0.connect(i42);
+
+ BOOST_CHECK(s0() == 72);
+
+ s0.disconnect(72);
+ BOOST_CHECK(s0() == 62);
+
+ c72.disconnect(); // Double-disconnect should be safe
+ BOOST_CHECK(s0() == 62);
+
+ s0.disconnect(72); // Triple-disconect should be safe
+ BOOST_CHECK(s0() == 62);
+
+ // Also connect 63 in the same group as 62
+ s0.connect(60, i63);
+ BOOST_CHECK(s0() == 63);
+
+ // Disconnect all of the 60's
+ s0.disconnect(60);
+ BOOST_CHECK(s0() == 42);
+
+ c42.disconnect();
+ BOOST_CHECK(s0() == 2);
+
+ c2.disconnect();
+ BOOST_CHECK(s0() == 0);
+ }
+
+ {
+ boost::signals2::signal<int (), max_or_default<int> > s0;
+ boost::signals2::connection c2 = s0.connect(i2);
+ boost::signals2::connection c72 = s0.connect(i72);
+ boost::signals2::connection c62 = s0.connect(i62);
+ boost::signals2::connection c42 = s0.connect(i42);
+
+ const boost::signals2::signal<int (), max_or_default<int> >& cs0 = s0;
+ BOOST_CHECK(cs0() == 72);
+ }
+
+ {
+ make_increasing_int<7> i7;
+ make_increasing_int<10> i10;
+
+ boost::signals2::signal<int (), max_or_default<int> > s0;
+ boost::signals2::connection c7 = s0.connect(i7);
+ boost::signals2::connection c10 = s0.connect(i10);
+
+ BOOST_CHECK(s0() == 10);
+ BOOST_CHECK(s0() == 11);
+ }
+}
+
+static void
+test_one_arg()
+{
+ boost::signals2::signal<int (int value), max_or_default<int> > s1;
+
+ s1.connect(std::negate<int>());
+ s1.connect(boost::bind(std::multiplies<int>(), 2, _1));
+
+ BOOST_CHECK(s1(1) == 2);
+ BOOST_CHECK(s1(-1) == 1);
+}
+
+static void
+test_signal_signal_connect()
+{
+ typedef boost::signals2::signal<int (int value), max_or_default<int> > signal_type;
+ signal_type s1;
+
+ s1.connect(std::negate<int>());
+
+ BOOST_CHECK(s1(3) == -3);
+
+ {
+ signal_type s2;
+ s1.connect(s2);
+ s2.connect(boost::bind(std::multiplies<int>(), 2, _1));
+ s2.connect(boost::bind(std::multiplies<int>(), -3, _1));
+
+ BOOST_CHECK(s2(-3) == 9);
+ BOOST_CHECK(s1(3) == 6);
+ } // s2 goes out of scope and disconnects
+ BOOST_CHECK(s1(3) == -3);
+}
+
+template<typename ResultType>
+ ResultType disconnecting_slot(const boost::signals2::connection &conn, int)
+{
+ conn.disconnect();
+ return ResultType();
+}
+
+#ifdef BOOST_NO_VOID_RETURNS
+template<>
+ void disconnecting_slot<void>(const boost::signals2::connection &conn, int)
+{
+ conn.disconnect();
+ return;
+}
+#endif
+
+template<typename ResultType>
+ void test_extended_slot()
+{
+ {
+ typedef boost::signals2::signal<ResultType (int)> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
+ ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
+ slot_type myslot(fp);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig(0);
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
+ { // test 0 arg signal
+ typedef boost::signals2::signal<ResultType ()> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
+ ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
+ slot_type myslot(fp, _1, 0);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig();
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
+ // test disconnection by slot
+ {
+ typedef boost::signals2::signal<ResultType (int)> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
+ ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
+ slot_type myslot(fp);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig.disconnect(fp);
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
+}
+
+void increment_arg(int &value)
+{
+ ++value;
+}
+
+static void
+test_reference_args()
+{
+ typedef boost::signals2::signal<void (int &)> signal_type;
+ signal_type s1;
+
+ s1.connect(&increment_arg);
+ int value = 0;
+ s1(value);
+ BOOST_CHECK(value == 1);
+}
+
+static void
+test_typedefs_etc()
+{
+ typedef boost::signals2::signal<int (double, long)> signal_type;
+ typedef signal_type::slot_type slot_type;
+
+ BOOST_CHECK(typeid(signal_type::slot_result_type) == typeid(int));
+ BOOST_CHECK(typeid(signal_type::result_type) == typeid(boost::optional<int>));
+ BOOST_CHECK(typeid(signal_type::arg<0>::type) == typeid(double));
+ BOOST_CHECK(typeid(signal_type::arg<1>::type) == typeid(long));
+ BOOST_CHECK(typeid(signal_type::arg<0>::type) == typeid(signal_type::first_argument_type));
+ BOOST_CHECK(typeid(signal_type::arg<1>::type) == typeid(signal_type::second_argument_type));
+ BOOST_CHECK(typeid(signal_type::signature_type) == typeid(int (double, long)));
+ BOOST_CHECK(signal_type::arity == 2);
+
+ BOOST_CHECK(typeid(slot_type::result_type) == typeid(signal_type::slot_result_type));
+ BOOST_CHECK(typeid(slot_type::arg<0>::type) == typeid(signal_type::arg<0>::type));
+ BOOST_CHECK(typeid(slot_type::arg<1>::type) == typeid(signal_type::arg<1>::type));
+ BOOST_CHECK(typeid(slot_type::arg<0>::type) == typeid(slot_type::first_argument_type));
+ BOOST_CHECK(typeid(slot_type::arg<1>::type) == typeid(slot_type::second_argument_type));
+ BOOST_CHECK(typeid(slot_type::signature_type) == typeid(signal_type::signature_type));
+ BOOST_CHECK(slot_type::arity == signal_type::arity);
+
+ typedef boost::signals2::signal<void (short)> unary_signal_type;
+ BOOST_CHECK(typeid(unary_signal_type::slot_result_type) == typeid(void));
+ BOOST_CHECK(typeid(unary_signal_type::argument_type) == typeid(short));
+ BOOST_CHECK(typeid(unary_signal_type::slot_type::argument_type) == typeid(short));
+}
+
+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::signal<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::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)
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ test_zero_args();
+ test_one_arg();
+ test_signal_signal_connect();
+ test_extended_slot<void>();
+ test_extended_slot<int>();
+ test_reference_args();
+ test_typedefs_etc();
+ test_set_combiner();
+ test_swap();
+ test_move();
+}
diff --git a/src/boost/libs/signals2/test/signal_type_test.cpp b/src/boost/libs/signals2/test/signal_type_test.cpp
new file mode 100644
index 000000000..94c746429
--- /dev/null
+++ b/src/boost/libs/signals2/test/signal_type_test.cpp
@@ -0,0 +1,43 @@
+// Tests for boost::signals2::signal_type
+
+// Copyright Frank Mori Hess 2009.
+// Distributed under 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)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#include <boost/signals2.hpp>
+#define BOOST_TEST_MODULE signal_type_test
+#include <boost/test/included/unit_test.hpp>
+
+namespace bs2 = boost::signals2;
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ {
+ bs2::signal_type<void ()>::type mysig;
+ bs2::signal<void ()> mysig2;
+ BOOST_CHECK(typeid(mysig) == typeid(mysig2));
+ }
+
+ {
+ bs2::signal_type<double (int), bs2::last_value<double> >::type mysig;
+ bs2::signal<double (int), bs2::last_value<double> > mysig2;
+ BOOST_CHECK(typeid(mysig) == typeid(mysig2));
+ }
+
+ {
+ using namespace bs2::keywords;
+ bs2::signal_type<double (int), group_compare_type<std::less<float> >, group_type<float> >::type mysig;
+ bs2::signal<double (int), bs2::optional_last_value<double>, float, std::less<float> > mysig2;
+ BOOST_CHECK(typeid(mysig) == typeid(mysig2));
+ }
+
+ {
+ using namespace bs2::keywords;
+ bs2::signal_type<signature_type<float (long*)> >::type mysig;
+ bs2::signal<float (long*)> mysig2;
+ BOOST_CHECK(typeid(mysig) == typeid(mysig2));
+ }
+}
diff --git a/src/boost/libs/signals2/test/slot_compile_test.cpp b/src/boost/libs/signals2/test/slot_compile_test.cpp
new file mode 100644
index 000000000..6ce6c3715
--- /dev/null
+++ b/src/boost/libs/signals2/test/slot_compile_test.cpp
@@ -0,0 +1,27 @@
+// Signals2 library
+// test for compilation of boost/signals2/slot.hpp
+
+// Copyright Frank Mori Hess 2008
+// 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/signals2/slot.hpp>
+#define BOOST_TEST_MODULE slot_compile_test
+#include <boost/test/included/unit_test.hpp>
+
+void myslot()
+{}
+
+int myslot2(int)
+{
+ return 0;
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ boost::signals2::slot<void (void)> sl0(&myslot);
+}
diff --git a/src/boost/libs/signals2/test/threading_models_test.cpp b/src/boost/libs/signals2/test/threading_models_test.cpp
new file mode 100644
index 000000000..bddae17c0
--- /dev/null
+++ b/src/boost/libs/signals2/test/threading_models_test.cpp
@@ -0,0 +1,86 @@
+// thread_safe_signals library
+// basic test for alternate threading models
+
+// Copyright Frank Mori Hess 2008
+// 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/signals2.hpp>
+#define BOOST_TEST_MODULE threading_models_test
+#include <boost/test/included/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+
+// combiner that returns the number of slots invoked
+struct slot_counter {
+ typedef unsigned result_type;
+ template<typename InputIterator>
+ unsigned operator()(InputIterator first, InputIterator last) const
+ {
+ unsigned count = 0;
+ for (; first != last; ++first)
+ {
+ try
+ {
+ *first;
+ ++count;
+ }
+ catch(const boost::bad_weak_ptr &)
+ {}
+ }
+ return count;
+ }
+};
+
+void myslot()
+{
+}
+
+template<typename signal_type>
+void simple_test()
+{
+ signal_type sig;
+ sig.connect(typename signal_type::slot_type(&myslot));
+ BOOST_CHECK(sig() == 1);
+ sig.disconnect(&myslot);
+ BOOST_CHECK(sig() == 0);
+}
+
+class recursion_checking_dummy_mutex
+{
+ int recursion_count;
+public:
+ recursion_checking_dummy_mutex(): recursion_count(0)
+ {}
+ void lock()
+ {
+ BOOST_REQUIRE(recursion_count == 0);
+ ++recursion_count;
+ }
+ bool try_lock()
+ {
+ lock();
+ return true;
+ }
+ void unlock()
+ {
+ --recursion_count;
+ BOOST_REQUIRE(recursion_count == 0);
+ }
+};
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ typedef boost::signals2::signal<void (), slot_counter, int, std::less<int>, boost::function<void ()>,
+ boost::function<void (const boost::signals2::connection &)>, recursion_checking_dummy_mutex> sig0_rc_type;
+ simple_test<sig0_rc_type>();
+ typedef boost::signals2::signal<void (), slot_counter, int, std::less<int>, boost::function<void ()>,
+ boost::function<void (const boost::signals2::connection &)>, boost::mutex> sig0_mt_type;
+ simple_test<sig0_mt_type>();
+ typedef boost::signals2::signal<void (), slot_counter, int, std::less<int>, boost::function<void ()>,
+ boost::function<void (const boost::signals2::connection &)>, boost::signals2::dummy_mutex> sig0_st_type;
+ simple_test<sig0_st_type>();
+}
diff --git a/src/boost/libs/signals2/test/track_test.cpp b/src/boost/libs/signals2/test/track_test.cpp
new file mode 100644
index 000000000..405aa11b6
--- /dev/null
+++ b/src/boost/libs/signals2/test/track_test.cpp
@@ -0,0 +1,167 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2006
+// Copyright Frank Mori Hess 2007
+// 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 <memory>
+#include <boost/optional.hpp>
+#include <boost/ref.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
+#define BOOST_TEST_MODULE track_test
+#include <boost/test/included/unit_test.hpp>
+#include <boost/bind/bind.hpp>
+
+using namespace boost::placeholders;
+
+struct swallow {
+ typedef int result_type;
+ template<typename T> result_type operator()(const T*, int i) { return i; }
+};
+
+template<typename T>
+struct max_or_default {
+ typedef T result_type;
+
+ template<typename InputIterator>
+ T operator()(InputIterator first, InputIterator last) const
+ {
+ boost::optional<T> max;
+ for(; first != last; ++first)
+ {
+ T value = *first;
+ if(!max)
+ {
+ max = value;
+ }else if(value > *max)
+ {
+ max = value;
+ }
+ }
+ if(max) return *max;
+ else return T();
+ }
+};
+
+static int myfunc(int i, double z)
+{
+ return i;
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type;
+ sig_type s1;
+ boost::signals2::connection connection;
+
+ // Test auto-disconnection
+ BOOST_CHECK(s1(5) == 0);
+ {
+ boost::shared_ptr<int> shorty(new int());
+ s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track(shorty));
+ BOOST_CHECK(s1(5) == 5);
+ }
+ BOOST_CHECK(s1(5) == 0);
+
+ // Test auto-disconnection of slot before signal connection
+ {
+ boost::shared_ptr<int> shorty(new int(1));
+// doesn't work on gcc 3.3.5, it says: error: type specifier omitted for parameter `shorty'
+// does work on gcc 4.1.2
+// sig_type::slot_type slot(swallow(), shorty.get(), _1);
+ swallow myswallow;
+ sig_type::slot_type slot(myswallow, shorty.get(), _1);
+
+ slot.track(shorty);
+ shorty.reset();
+ s1.connect(slot);
+ BOOST_CHECK(s1(5) == 0);
+ }
+
+ // Test binding of a slot to another slot
+ {
+ boost::shared_ptr<int> shorty(new int(2));
+ boost::signals2::slot<int (double)> other_slot(&myfunc, boost::cref(*shorty.get()), _1);
+ other_slot.track(shorty);
+ connection = s1.connect(sig_type::slot_type(other_slot, 0.5).track(other_slot));
+ BOOST_CHECK(s1(3) == 2);
+ }
+ BOOST_CHECK(connection.connected() == false);
+ BOOST_CHECK(s1(3) == 0);
+
+ // Test binding of a signal as a slot
+ {
+ sig_type s2;
+ s1.connect(s2);
+ s2.connect(sig_type::slot_type(&myfunc, _1, 0.7));
+ BOOST_CHECK(s1(4) == 4);
+ }
+ BOOST_CHECK(s1(4) == 0);
+
+ // Test tracking of null but not empty shared_ptr
+ BOOST_CHECK(s1(2) == 0);
+ {
+ boost::shared_ptr<int> shorty((int*)(0));
+ s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track(shorty));
+ BOOST_CHECK(s1(2) == 2);
+ }
+ BOOST_CHECK(s1(2) == 0);
+
+#ifndef BOOST_NO_CXX11_SMART_PTR
+ // Test tracking through std::shared_ptr/weak_ptr
+ BOOST_CHECK(s1(5) == 0);
+ {
+ std::shared_ptr<int> shorty(new int());
+ s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(shorty));
+ BOOST_CHECK(s1(5) == 5);
+ }
+ BOOST_CHECK(s1(5) == 0);
+ {
+ std::shared_ptr<int> shorty(new int());
+ s1.connect
+ (
+ sig_type::slot_type
+ (
+ swallow(),
+ shorty.get(),
+ _1
+ ).track_foreign
+ (
+ std::weak_ptr<int>(shorty)
+ )
+ );
+ BOOST_CHECK(s1(5) == 5);
+ }
+ BOOST_CHECK(s1(5) == 0);
+ // make sure tracking foreign shared_ptr<const void> works
+ {
+ std::shared_ptr<const void> shorty(new int());
+ s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(shorty));
+ BOOST_CHECK(s1(5) == 5);
+ }
+ {
+ std::shared_ptr<int> shorty(new int());
+ s1.connect
+ (
+ sig_type::slot_type
+ (
+ swallow(),
+ shorty.get(),
+ _1
+ ).track_foreign
+ (
+ std::weak_ptr<const void>(shorty)
+ )
+ );
+ BOOST_CHECK(s1(5) == 5);
+ }
+ BOOST_CHECK(s1(5) == 0);
+ BOOST_CHECK(s1(5) == 0);
+#endif
+}
diff --git a/src/boost/libs/signals2/test/trackable_test.cpp b/src/boost/libs/signals2/test/trackable_test.cpp
new file mode 100644
index 000000000..b3049cdfd
--- /dev/null
+++ b/src/boost/libs/signals2/test/trackable_test.cpp
@@ -0,0 +1,112 @@
+// Boost.Signals2 library
+
+// Copyright Douglas Gregor 2001-2006.
+// Copyright Frank Mori Hess 2009.
+// 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/signals2/signal.hpp>
+#include <boost/signals2/trackable.hpp>
+#define BOOST_TEST_MODULE trackable_test
+#include <boost/test/included/unit_test.hpp>
+#include <boost/bind/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/weak_ptr.hpp>
+
+using namespace boost::placeholders;
+
+struct short_lived : public boost::signals2::trackable {
+ ~short_lived() {}
+};
+
+struct swallow {
+ typedef int result_type;
+ template<typename T> int operator()(const T*, int i) { return i; }
+ template<typename T> int operator()(T &, int i) { return i; }
+ template<typename T> int operator()(boost::weak_ptr<T>, int i) { return i; }
+};
+
+template<typename T>
+struct max_or_default {
+ typedef T result_type;
+
+ template<typename InputIterator>
+ T operator()(InputIterator first, InputIterator last) const
+ {
+ if (first == last)
+ return T();
+
+ T max = *first++;
+ for (; first != last; ++first)
+ max = (*first > max)? *first : max;
+
+ return max;
+ }
+};
+
+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();
+}
+
+BOOST_AUTO_TEST_CASE(test_main)
+{
+ typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type;
+ sig_type s1;
+
+ // Test auto-disconnection
+ BOOST_CHECK(s1(5) == 0);
+ {
+ short_lived shorty;
+ s1.connect(boost::bind<int>(swallow(), &shorty, _1));
+ BOOST_CHECK(s1(5) == 5);
+ }
+ BOOST_CHECK(s1(5) == 0);
+ // Test auto-disconnection of trackable inside reference_wrapper
+ {
+ short_lived shorty;
+ s1.connect(boost::bind<int>(swallow(), boost::ref(shorty), _1));
+ BOOST_CHECK(s1(5) == 5);
+ }
+ BOOST_CHECK(s1(5) == 0);
+
+ // Test multiple arg slot constructor
+ {
+ short_lived shorty;
+ s1.connect(sig_type::slot_type(swallow(), &shorty, _1));
+ BOOST_CHECK(s1(5) == 5);
+ }
+ BOOST_CHECK(s1(5) == 0);
+
+ // Test auto-disconnection of slot before signal connection
+ {
+ short_lived* shorty = new short_lived();
+
+ sig_type::slot_type slot(boost::bind<int>(swallow(), shorty, _1));
+ delete shorty;
+
+ BOOST_CHECK(s1(5) == 0);
+ }
+
+ test_immediate_disconnect_on_delete();
+}