// Boost.Signals library | |
// Copyright Douglas Gregor 2001-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 | |
#ifndef BOOST_SIGNALS_COMMON_HEADER | |
#define BOOST_SIGNALS_COMMON_HEADER | |
#ifndef BOOST_SIGNALS_NAMESPACE | |
# define BOOST_SIGNALS_NAMESPACE signals | |
#endif | |
#include <boost/type_traits/conversion_traits.hpp> | |
#include <boost/ref.hpp> | |
#include <boost/signals/detail/config.hpp> | |
#ifdef BOOST_HAS_ABI_HEADERS | |
# include BOOST_ABI_PREFIX | |
#endif | |
namespace boost { | |
namespace BOOST_SIGNALS_NAMESPACE { | |
namespace detail { | |
// The unusable class is a placeholder for unused function arguments | |
// It is also completely unusable except that it constructable from | |
// anything. This helps compilers without partial specialization | |
// handle slots returning void. | |
struct unusable { | |
unusable() {} | |
}; | |
// Determine the result type of a slot call | |
template<typename R> | |
struct slot_result_type { | |
typedef R type; | |
}; | |
template<> | |
struct slot_result_type<void> { | |
typedef unusable type; | |
}; | |
// Determine if the given type T is a signal | |
class signal_base; | |
template<typename T> | |
struct is_signal { | |
BOOST_STATIC_CONSTANT(bool, | |
value = (is_convertible<T*, signal_base*>::value)); | |
}; | |
/* | |
* The IF implementation is temporary code. When a Boost metaprogramming | |
* library is introduced, Boost.Signals will use it instead. | |
*/ | |
namespace intimate { | |
struct SelectThen | |
{ | |
template<typename Then, typename Else> | |
struct Result | |
{ | |
typedef Then type; | |
}; | |
}; | |
struct SelectElse | |
{ | |
template<typename Then, typename Else> | |
struct Result | |
{ | |
typedef Else type; | |
}; | |
}; | |
template<bool Condition> | |
struct Selector | |
{ | |
typedef SelectThen type; | |
}; | |
template<> | |
struct Selector<false> | |
{ | |
typedef SelectElse type; | |
}; | |
} // end namespace intimate | |
template<bool Condition, typename Then, typename Else> | |
struct IF | |
{ | |
typedef typename intimate::Selector<Condition>::type select; | |
typedef typename select::template Result<Then,Else>::type type; | |
}; | |
// Determine if the incoming argument is a reference_wrapper | |
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
template<typename T> | |
struct is_ref | |
{ | |
BOOST_STATIC_CONSTANT(bool, value = false); | |
}; | |
template<typename T> | |
struct is_ref<reference_wrapper<T> > | |
{ | |
BOOST_STATIC_CONSTANT(bool, value = true); | |
}; | |
#else // no partial specialization | |
typedef char yes_type; | |
typedef double no_type; | |
no_type is_ref_tester(...); | |
template<typename T> | |
yes_type is_ref_tester(reference_wrapper<T>*); | |
template<typename T> | |
struct is_ref | |
{ | |
static T* t; | |
BOOST_STATIC_CONSTANT(bool, | |
value = (sizeof(is_ref_tester(t)) == sizeof(yes_type))); | |
}; | |
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
// A slot can be a signal, a reference to a function object, or a | |
// function object. | |
struct signal_tag {}; | |
struct reference_tag {}; | |
struct value_tag {}; | |
// Classify the given slot as a signal, a reference-to-slot, or a | |
// standard slot | |
template<typename S> | |
class get_slot_tag { | |
typedef typename IF<(is_signal<S>::value), | |
signal_tag, | |
value_tag>::type signal_or_value; | |
public: | |
typedef typename IF<(is_ref<S>::value), | |
reference_tag, | |
signal_or_value>::type type; | |
}; | |
// Forward declaration needed in lots of places | |
class signal_base_impl; | |
class bound_objects_visitor; | |
class slot_base; | |
} // end namespace detail | |
} // end namespace BOOST_SIGNALS_NAMESPACE | |
} // end namespace boost | |
#ifdef BOOST_HAS_ABI_HEADERS | |
# include BOOST_ABI_SUFFIX | |
#endif | |
#endif // BOOST_SIGNALS_COMMON_HEADER |