Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:34

0001 // @(#)root/base:$Id$
0002 // Author: Vassil Vassilev 23/01/2017
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TVirtualQConnection
0013 #define ROOT_TVirtualQConnection
0014 
0015 #include "TList.h"
0016 #include "TInterpreter.h"
0017 
0018 /// Mediates the link between the signal and the slot. It decouples the setting of
0019 /// arguments and sending a signal.
0020 ///
0021 /// There are three different modes in argument setting required by TQObject's Emit/EmitVA:
0022 /// setting integral types, setting array types and setting const char*.
0023 class TVirtualQConnection : public TList {
0024 protected:
0025    virtual CallFunc_t *GetSlotCallFunc() const = 0;
0026    virtual void SetArg(Long_t) = 0;
0027    virtual void SetArg(ULong_t) = 0;
0028    virtual void SetArg(Float_t) = 0;
0029    virtual void SetArg(Double_t) = 0;
0030    virtual void SetArg(Long64_t) = 0;
0031    virtual void SetArg(ULong64_t) = 0;
0032 
0033    // Note: sets argument list (for potentially more than one arg).
0034    virtual void SetArg(const Longptr_t *, Int_t = -1) = 0;
0035    virtual void SetArg(const char *) = 0;
0036    void SetArg(const void *ptr) { SetArg((Longptr_t)ptr); };
0037 
0038    // We should 'widen' all types to one of the SetArg overloads.
0039    template <class T, class = typename std::enable_if<std::is_integral<T>::value>::type>
0040    void SetArg(const T& val)
0041    {
0042       if (std::is_signed<T>::value)
0043          SetArg((Longptr_t)val);
0044       else
0045          SetArg((ULongptr_t)val);
0046    }
0047 
0048    void SetArgsImpl() {} // SetArgsImpl terminator
0049    template <typename T, typename... Ts> void SetArgsImpl(const T& arg, const Ts&... tail)
0050    {
0051       SetArg(arg);
0052       SetArgsImpl(tail...);
0053    }
0054 public:
0055    virtual void SendSignal() = 0;
0056 
0057    /// Unpacks the template parameter type and sets arguments of integral and array (scalar) type.
0058    ///
0059    template <typename... T> void SetArgs(const T&... args)
0060    {
0061       // Do not reset the arguments if we have no arguments to reset with.
0062       // This is essential in order to support cases like:
0063       // void f(int) {}; TQObject::Connect (... "f(int=12");
0064       // The implementation will see we create a slot which has a 'default'
0065       // argument and create a CallFunc with preset argument values to later call.
0066       if (!sizeof...(args)) return;
0067       gInterpreter->CallFunc_ResetArg(GetSlotCallFunc());
0068       SetArgsImpl(args...);
0069    }
0070 
0071    /// Sets an array of arguments passed as a pointer type and size. If nargs is not specified
0072    /// the number of arguments expected by the slot is used.
0073    ///
0074    void SetArgs(const Longptr_t* argArray, Int_t nargs = -1)
0075    {
0076       SetArg(argArray, nargs);
0077    }
0078 };
0079 
0080 #endif