Signals2 API Changes

Porting from Boost.Signals to Boost.Signals2

The changes made to the Boost.Signals2 API compared to the original Boost.Signals
library are summarized below. We also provide some notes on
dealing with each change while porting existing Boost.Signals code to Boost.Signals2.

The namespace boost::signals has been replaced by boost::signals2
to avoid conflict with the original Boost.Signals implementation, as well as the Qt "signals" macro.
All the Boost.Signals2 classes are inside the boost::signals2 namespace,
unlike the original Boost.Signals which has some classes in the boost
namespace in addition to its own boost::signals namespace.

The Boost.Signals2 header files are contained in the
boost/signals2/ subdirectory instead of the boost/signals
subdirectory used by the original Boost.Signals. Furthermore, all the headers except
for the convenience header boost/signals2.hpp are inside the
boost/signals2/ subdirectory, unlike the original Boost.Signals which
keeps a few headers in the parent boost/ directory
in addition to its own boost/signals/ subdirectory.

For example, the signal class is now
in the boost::signals2 namespace instead of the
boost namespace,
and it's header file is now at boost/signals2/signal.hpp instead of
boost/signal.hpp.

While porting, only trivial changes to #include directives
and namespace qualifications should be required to deal with these changes.
Furthermore, the new namespace and header locations for Boost.Signals2
allow it to coexist in the same program with the original Boost.Signals library,
and porting can be performed piecemeal.

Automatic connection management is now achieved through the use of
shared_ptr/weak_ptr
and signals2::slot::track(), as described in the
tutorial.
However, the old (thread-unsafe) Boost.Signals scheme of automatic connection management
is still supported via the boost::signals2::trackable class.

Support for postconstructors (and predestructors) on objects managed by shared_ptr
has been added with
the deconstruct factory function.
This was motivated by the importance of
shared_ptr for the new connection tracking scheme, and the
inability to obtain a shared_ptr to an object in its constructor.
The use of deconstruct is described in the
tutorial.

The use of deconstruct is in no way required,
it is only provided in the hope
it may be useful. You may wish to use it if you are porting code where
a class creates connections to its own member functions in its constructor,
and you also
wish to use the new automatic connection management scheme. You could then
move the connection creation from the constructor to to the an
adl_postconstruct function, where
a reference to the owning shared_ptr is available for
passing to signals2::slot::track.
The deconstruct function would be used create objects
of the class and run their associated adl_postconstruct function.
You can enforce use of deconstruct by
making the class' constructors private and declaring
deconstruct_access a friend.

The signals2::slot class takes a new Signature template parameter,
is useable as a function object, and has some additional features to support the
new Boost.Signals2 automatic connection management scheme.

The changes to the slot class should generally not cause any porting difficulties,
especially if you are using the boost::signals2::trackable
compatibility class mentioned above. If you are converting your code over to
use the new automatic connection management scheme, you will need to
employ some of the new slot features, as described in the
tutorial.

The signals2::last_value combiner is still provided, although its
behavior is slightly changed in that it
throws an exception when no slots are connected on signal invocation, instead of
always requiring at least one slot to be connected (except for its void specialization
which never required any slots to be connected).

If you are porting signals which have a void return type in their signature
and they use the default combiner, there are no changes required. If you are
using the default combiner with a non-void return type and care about the
value returned from signal invocation, you will have to take into account that
optional_last_value returns a
boost::optional instead of a plain value. One simple
way to deal with this is to use boost::optional::operator*() to access the
value wrapped inside the returned boost::optional.

Alternatively, you could do a port by specifying the Combiner template parameter
for your signals2::signal to be signals2::last_value.

These additions should have no effect on porting unless you are also converting
your program from a single threaded program into a multi-threaded one. In that case,
if you have slots which need access to their signals2::connection
to the signal invoking them (for example to block or disconnect their connection)
you may wish to connect the slots with
signals2::signal::connect_extended().
This also requires adding an additional connection argument to the slot.
More information on how and why to use extended slots is available
in the tutorial.

The signals2::signal class has a new Mutex template parameter for specifying
the mutex type used internally by the signal and its connections.

The Mutex template parameter can be left to its default value of
boost::signals2::mutex and should have little effect on porting.
However, if you have a single-threaded program and are
concerned about incuring a performance overhead from unneeded mutex locking, you may
wish to use a different mutex for your signals such as dummy_mutex.
See the tutorial
for more information on the Mutex parameter.

During porting it should be straightforward to replace uses of the old reference-returning
signal::combiner()
function with the new "by-value" signals2::signal::combiner
and signals2::signal::set_combiner functions.
However, you will need to inspect each call of the combiner method in your code
to determine if your program logic has been broken by the changed
return type.

Connections no longer have block() and unblock() methods. Blocking
of connections is now accomplished by creating shared_connection_block objects,
which provide RAII-style blocking.

Version 1.40 also introduces a variadic templates implementation of
Signals2, which is used when Boost detects compiler support for variadic templates
(variadic templates are a new feature of C++0x).
This change is mostly transparent to the user, however it does introduce a few
visible tweaks to the interface as described in the following.

The following library features are
deprecated, and are only available if your compiler is NOT using
variadic templates (i.e. BOOST_NO_VARIADIC_TEMPLATES is defined
by Boost.Config).