boost代码分析:signal中的回调及combiner(最终返回值)

用 cd boost_1_34_1/boost; cpp -I /home/Administrator/boost_1_34_1 signal.hpp 产生预处理过的代码

combiner中要遍历并dereference每个元素,在dereference时用户connect上的函数才真正被调用,因此发生形如下面的sig(5,3)的调用时,实际上调用connect连接的函数的责任落在maximum身上(++和操作)

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;
}

};
float product(float x, float y) { cout<<"product"<<endl; return xy; }
float quotient(float x, float y) { cout<<"quotient"<<endl; return x/y; }
float sum(float x, float y) { cout<<"sum"<<endl; return x+y; }
float difference(float x, float y) { cout<<"difference"<<endl; return x-y; }

int main(int argc, char
argv[])
{
boost::signal<float (float x, float y), maximum<float> > sig;
sig.connect(&product);
sig.connect(&quotient);
sig.connect(&sum);
sig.connect(&difference);

std::cout << sig(5, 3) << std::endl;
}
output:
product
quotient
sum
difference
15
/////////////////////////////////////////////////////////////////
// change maximum to the following:
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;
}

};
output:
product
15


Ref:
boost源码剖析之:多重回调机制signal(上)
http://www.ithao123.com/cpluspluslib/20071020/1677.html

——————————————————————————————————————————————————

    template<
        typename R,
        typename T1, typename T2
        ,
        typename Combiner,
        typename Group,
        typename GroupCompare,
        typename SlotFunction
    >
    typename signal2<
    R, T1, T2
    ,
    Combiner, Group, GroupCompare, SlotFunction>::result_type
    signal2<
    R, T1, T2
    ,
    Combiner, Group, GroupCompare, SlotFunction
    >::operator()(T1 a1, T2 a2)
    {

        signals::detail::call_notification notification(this->impl);

        signals::detail::args2<T1, T2> args(a1, a2);

        call_bound_slot f(&args);

        typedef typename call_bound_slot::result_type result_type;
        optional<result_type> cache;

        return combiner()(slot_calliterator(notification.impl->slots.begin(),
            impl->slots_.end(), f, cache),
            slot_calliterator(notification.impl->slots.end(),
            impl->slots_.end(), f, cache));
    }


      call_notification::
        call_notification(const shared_ptr<signal_base_impl>& b) :
          impl(b)
      {
        // A call will be made, so increment the call depth as a notification
        impl->call_depth++;
      }

      call_notification::~call_notification()
      {
        impl->call_depth–;

        // If the call depth is zero and we have some slots that have been
        // disconnected during the calls, remove those slots from the list
        if (impl->call_depth == 0 &&
            impl->flags.delayed_disconnect) {
          impl->remove_disconnected_slots();
          impl->flags.delayed_disconnect = false;
        }
      }


// 针对 signal2 分析
    template<
        typename R,
        typename T1, typename T2
        ,
        typename Combiner = last_value<R>,
        typename Group = int,
        typename GroupCompare = std::less<Group>,
        typename SlotFunction = function2<
        R ,
        T1, T2>
    >
    class signal2 :
        public signals::detail::signal_base,
        public signals::trackable
    {
    public:

        typedef SlotFunction slot_function_type;


        typedef typename signals::detail::slot_result_type<R>::type
            slot_result_type;


        typedef T1 arg2_type; typedef T2 arg3_type;




        typedef T1 first_argument_type;
        typedef T2 second_argument_type;


    private:

        typedef signals::detail::group_bridge_compare<GroupCompare, Group>
            real_group_compare_type;



        typedef signals::detail::call_bound2<R>
            outer_bound_slot_caller;
        typedef typename outer_bound_slot_caller::template
            caller<T1, T2
            ,
            slot_function_type>
            call_bound_slot;

    public:

        typedef typename Combiner::result_type result_type;


        typedef Combiner combiner_type;


        typedef slot<slot_function_type> slot_type;


        typedef Group group_type;
        typedef GroupCompare group_compare_type;

        typedef signals::detail::slot_call_iterator<
            call_bound_slot, iterator> slot_call_iterator;

        explicit
            signal2(const Combiner& c = Combiner(),
            const GroupCompare& comp = GroupCompare()) :
        signals::detail::signal_base(real_group_compare_type(comp),
            c)
        {
        }


        signals::connection
            connect(const slot_type&,
            signals::connect_position at
            = signals::at_back);


        signals::connection
            connect(const group_type&, const slot_type&,
            signals::connect_position at
            = signals::at_back);
# 220 "/home/Administrator/boost_1_34_1/boost/signals/signaltemplate.hpp"
        template<typename T>
            void disconnect(const T& t)
        {
            typedef mpl::bool
<(is_convertible<T, group_type>::value)> is_group;
            this->do_disconnect(t, is_group());
        }

    private:

        void do_disconnect(const grouptype& group, mpl::bool<true>)
        {
            impl->disconnect(group);
        }

        template<typename Function>
            void dodisconnect(const Function& f, mpl::bool<false>)
        {

            signals::detail::callnotification notification(this->impl);

            for (iterator i = impl->slots
.begin(); i != impl->slots_.end(); ++i) {
                slot_function_type& s =
unsafe_any_cast<slot_function_type>(&i->second);
                if (s == f) i->first.disconnect();
            }
        }


    public:


        result_type operator()(T1 a1, T2 a2);
        result_type operator()(T1 a1, T2 a2) const;

        Combiner& combiner()
        { return unsafe_anycast<Combiner>(&impl->combiner); }

        const Combiner& combiner() const
        { return
unsafe_anycast<const Combiner>(&impl->combiner); }
    };


// iterator_facade<…> 是比较一般性的 iterator 基类,由它会调用子类的 dereference,increment 等
            template<typename Function, typename Iterator>
            class slot_call_iterator
                : public iterator_facade<slot_call_iterator<Function, Iterator>,
                typename Function::result_type,
                single_pass_traversal_tag,
                typename Function::result_type const&>
            {
                typedef iterator_facade<slot_call_iterator<Function, Iterator>,
                    typename Function::result_type,
                    single_pass_traversal_tag,
                    typename Function::result_type const&>
                    inherited;

                typedef typename Function::result_type result_type;

                friend class iterator_core_access;

            public:
                slot_call_iterator(Iterator iter_in, Iterator end_in, Function f,
                    optional<result_type> &c)
                    : iter(iter_in), end(end_in), f(f), cache(&c)
                {
                    iter = std::find_if(iter, end, is_callable());
                }

                typename inherited::reference
                    dereference() const
                {
                    if (!cache->is_initialized()) {
                        cache->reset(f(iter));
                    }

                    return cache->get();
                }

                void increment()
                {
                    iter = std::find_if(++iter, end, is_callable());
                    cache->reset();
                }

                bool equal(const slot_call_iterator& other) const
                {
                    iter = std::find_if(iter, end, is_callable());
                    other.iter = std::find_if(other.iter, other.end,
                        is_callable());
                    return iter == other.iter;
                }

            private:
                mutable Iterator iter;
                Iterator end;
                Function f;
                optional<result_type>
cache;
            };

// 看看调用 combiner operator() 的参数类型
        typedef signals::detail::slot_call_iterator<
            call_bound_slot, iterator> slot_call_iterator;

        typedef typename outer_bound_slot_caller::template
            caller<T1, T2
            ,
            slot_function_type>
            call_bound_slot;

        typedef signals::detail::call_bound2<R>
            outer_bound_slot_caller;

            template<typename R>
            struct call_bound2 {
                template<typename T1, typename T2
                    ,
                    typename F>
                struct caller {
                    typedef args2<T1, T2>
                        args_type;

                    args_type args;

                    typedef R result_type;

                    caller() {}
                    caller(args_type a) : args(a) {}

                    template<typename Pair>
                        R operator()(const Pair& slot) const       // 对应于前面的f(
iter)调用
                    {
                        F target = const_cast<F>(unsafe_any_cast<F>(&slot.second));
                        return (*target)(args->a1, args->a2);
                    }
                };
            };