mercredi 6 mai 2020

How to generalize this function with variadic templates c++

I have the following function. It converts two bindings of T0 and T1 to a binding of a tuple<T0,T1>

The function is as follows

template<typename T0, typename T1>
typename RxBinding<std::tuple<T0,T1>>::Ptr
Combine(RxBinding<T0>::Ptr b0, RxBinding<T1>::Ptr b1)
{
    using Tuple = std::tuple<T0,T1>;
    RxBinding<Tuple>::Ptr binding = makeValueBinding(std::make_tuple(b0->Get(),b1->Get()));

    // Break the reference cycle. 
    auto bindingWeak = std::weak_ptr<RxBinding<Tuple>>(binding);

    auto s0 = b0->Subscribe([bindingWeak,b1](T0 const & v0){
        auto b = bindingWeak.lock();
        if(b)
            b->Update(std::make_tuple(v0,b1->Get()));
    });

    auto s1 = b1->Subscribe([bindingWeak,b0](T1 const & v1){
        auto b = bindingWeak.lock();
        if(b)
            b->Update(std::make_tuple(b0->Get(),v1));
    });

    auto sN =  binding->Subscribe([b0,b1](std::tuple<T0,T1> const & t){
        b0->Update(std::get<0>(t));
        b1->Update(std::get<1>(t));
    });

    binding->CleanupWith << s0 << s1 << sN;

    return binding;
}

Don't worry too much about what a binding is. Assume they work. I'm looking for a pattern to generalise this using C++11 variadic templates so I can have N bindings as input rather than just two and convert them to a single binding?

template <typename ...T>
typename RxBinding<std::tuple<T...>>::Ptr
Combine( RxBinding<T>::Ptr args...) /* is this possible ?? */
{
    using Tuple = std::tuple<T...>;
    auto binding = makeValueBinding(std::make_tuple( /* what do do here with args ?? */ ));

    // Break the reference cycle. 
    RxBinding<Tuple>::Ptr bindingWeak = std::weak_ptr<RxBinding<Tuple>>(binding);

    // Make N subscriptions b0,b1,....bN with the weak reference above

    /* What to do here ?? */

    // Make the final subscription

    auto sN = binding->Subscribe([](std::tuple<T...> const & t){
        // Update the N bindings.

        /* what to do here ? */

    });

    // Add all subscriptions to the cleanup on the final binding
    /* not sure what to do here */

    return binding;
}

Aucun commentaire:

Enregistrer un commentaire