// @(#)root/meta:$Id$
// Author: Fons Rademakers   13/06/96

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TMethodCall
#define ROOT_TMethodCall


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMethodCall                                                          //
//                                                                      //
// Method or function calling interface. Objects of this class contain  //
// the (CINT) environment to call a global function or a method for an  //
// object of a specific class with the desired arguments. This class is //
// espicially useful when a method has to be called more times for      //
// different objects and/or with different arguments. If a function or  //
// method needs to be called only once one better uses                  //
// TInterpreter::Execute().                                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TDictionary
#include "TDictionary.h"
#endif

#ifndef ROOT_TInterpreter
#include "TInterpreter.h"
#endif

class TClass;
class TFunction;

class TMethodCall : public TObject {

public:
   using EReturnType = TInterpreter::EReturnType;

   // For backward compatibility:
   static const EReturnType kLong = TInterpreter::EReturnType::kLong;
   static const EReturnType kDouble = TInterpreter::EReturnType::kDouble;
   static const EReturnType kString = TInterpreter::EReturnType::kString;
   static const EReturnType kOther = TInterpreter::EReturnType::kOther;
   static const EReturnType kNoReturnType = TInterpreter::EReturnType::kNoReturnType;
   // Historical name.
   static const EReturnType kNone = TInterpreter::EReturnType::kNoReturnType;

   // enum EReturnType { kLong, kDouble, kString, kOther, kNone };

private:
   CallFunc_t    *fFunc;      //CINT method invocation environment
   Long_t         fOffset;    //offset added to object pointer before method invocation
   TClass        *fClass;     //pointer to the class info
   TFunction     *fMetPtr;    //pointer to the method or function info
   TString        fMethod;    //method name
   TString        fParams;    //argument string
   TString        fProto;     //prototype string
   Bool_t         fDtorOnly;  //call only dtor and not delete when calling ~xxx
   EReturnType    fRetType;   //method return type

   void Execute(const char *,  const char *, int * /*error*/ = 0) { }    // versions of TObject
   void Execute(TMethod *, TObjArray *, int * /*error*/ = 0) { }

   void InitImplementation(const char *methodname, const char *params, const char *proto, Bool_t objectIsConst, TClass *cl, const ClassInfo_t *cinfo, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch);

public:
   TMethodCall();
   TMethodCall(TClass *cl, CallFunc_t *callfunc, Long_t offset = 0);
   TMethodCall(TClass *cl, const char *method, const char *params);
   TMethodCall(const char *function, const char *params);
   TMethodCall(TFunction *func);
   TMethodCall(const TMethodCall &org);
   TMethodCall& operator=(const TMethodCall &rhs);
   ~TMethodCall();

   void           Init(TFunction *func);
   void           Init(TClass *cl, CallFunc_t *func, Long_t offset = 0);
   void           Init(TClass *cl, const char *method, const char *params, Bool_t objectIsConst = kFALSE);
   void           Init(const char *function, const char *params);
   void           InitWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst = kFALSE, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch);
   void           InitWithPrototype(const char *function, const char *proto, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch);
   Bool_t         IsValid() const;
   TObject       *Clone(const char *newname="") const;
   void           CallDtorOnly(Bool_t set = kTRUE) { fDtorOnly = set; }

   TFunction     *GetMethod();
   const char    *GetMethodName() const { return fMethod.Data(); }
   const char    *GetParams() const { return fParams.Data(); }
   const char    *GetProto() const { return fProto.Data(); }
   CallFunc_t    *GetCallFunc() const { return fFunc; }
   EReturnType    ReturnType();

   void     SetParamPtrs(void *paramArr, Int_t nparam = -1);
   void     ResetParam();
   void     SetParam(Long_t l);
   void     SetParam(Float_t f);
   void     SetParam(Double_t d);
   void     SetParam(Long64_t ll);
   void     SetParam(ULong64_t ull);

   template <typename... T> void SetParams(const T&... params) {
      if (!fFunc) return;
      gInterpreter->CallFunc_SetArguments(fFunc,params...);
   }

   void     Execute(void *object);
   void     Execute(void *object, const char *params);
   void     Execute(void *object, Long_t &retLong);
   void     Execute(void *object, const char *params, Long_t &retLong);
   void     Execute(void *object, Double_t &retDouble);
   void     Execute(void *object, const char *params, Double_t &retDouble);

   void     Execute(void *object, char **retText);
   void     Execute(void *object, const char *params, char **retText);

   void     Execute();
   void     Execute(const char *params);
   void     Execute(Long_t &retLong);
   void     Execute(const char *params, Long_t &retLong);
   void     Execute(Double_t &retDouble);
   void     Execute(const char *params, Double_t &retDouble);

   ClassDef(TMethodCall,0)  //Method calling interface
};

inline void TMethodCall::Execute()
   { Execute((void *)0); }
inline void TMethodCall::Execute(const char *params)
   { Execute((void *)0, params); }
inline void TMethodCall::Execute(Long_t &retLong)
   { Execute((void *)0, retLong); }
inline void TMethodCall::Execute(const char *params, Long_t &retLong)
   { Execute((void *)0, params, retLong); }
inline void TMethodCall::Execute(Double_t &retDouble)
   { Execute((void *)0, retDouble); }
inline void TMethodCall::Execute(const char *params, Double_t &retDouble)
   { Execute((void *)0, params, retDouble); }

#endif
 TMethodCall.h:1
 TMethodCall.h:2
 TMethodCall.h:3
 TMethodCall.h:4
 TMethodCall.h:5
 TMethodCall.h:6
 TMethodCall.h:7
 TMethodCall.h:8
 TMethodCall.h:9
 TMethodCall.h:10
 TMethodCall.h:11
 TMethodCall.h:12
 TMethodCall.h:13
 TMethodCall.h:14
 TMethodCall.h:15
 TMethodCall.h:16
 TMethodCall.h:17
 TMethodCall.h:18
 TMethodCall.h:19
 TMethodCall.h:20
 TMethodCall.h:21
 TMethodCall.h:22
 TMethodCall.h:23
 TMethodCall.h:24
 TMethodCall.h:25
 TMethodCall.h:26
 TMethodCall.h:27
 TMethodCall.h:28
 TMethodCall.h:29
 TMethodCall.h:30
 TMethodCall.h:31
 TMethodCall.h:32
 TMethodCall.h:33
 TMethodCall.h:34
 TMethodCall.h:35
 TMethodCall.h:36
 TMethodCall.h:37
 TMethodCall.h:38
 TMethodCall.h:39
 TMethodCall.h:40
 TMethodCall.h:41
 TMethodCall.h:42
 TMethodCall.h:43
 TMethodCall.h:44
 TMethodCall.h:45
 TMethodCall.h:46
 TMethodCall.h:47
 TMethodCall.h:48
 TMethodCall.h:49
 TMethodCall.h:50
 TMethodCall.h:51
 TMethodCall.h:52
 TMethodCall.h:53
 TMethodCall.h:54
 TMethodCall.h:55
 TMethodCall.h:56
 TMethodCall.h:57
 TMethodCall.h:58
 TMethodCall.h:59
 TMethodCall.h:60
 TMethodCall.h:61
 TMethodCall.h:62
 TMethodCall.h:63
 TMethodCall.h:64
 TMethodCall.h:65
 TMethodCall.h:66
 TMethodCall.h:67
 TMethodCall.h:68
 TMethodCall.h:69
 TMethodCall.h:70
 TMethodCall.h:71
 TMethodCall.h:72
 TMethodCall.h:73
 TMethodCall.h:74
 TMethodCall.h:75
 TMethodCall.h:76
 TMethodCall.h:77
 TMethodCall.h:78
 TMethodCall.h:79
 TMethodCall.h:80
 TMethodCall.h:81
 TMethodCall.h:82
 TMethodCall.h:83
 TMethodCall.h:84
 TMethodCall.h:85
 TMethodCall.h:86
 TMethodCall.h:87
 TMethodCall.h:88
 TMethodCall.h:89
 TMethodCall.h:90
 TMethodCall.h:91
 TMethodCall.h:92
 TMethodCall.h:93
 TMethodCall.h:94
 TMethodCall.h:95
 TMethodCall.h:96
 TMethodCall.h:97
 TMethodCall.h:98
 TMethodCall.h:99
 TMethodCall.h:100
 TMethodCall.h:101
 TMethodCall.h:102
 TMethodCall.h:103
 TMethodCall.h:104
 TMethodCall.h:105
 TMethodCall.h:106
 TMethodCall.h:107
 TMethodCall.h:108
 TMethodCall.h:109
 TMethodCall.h:110
 TMethodCall.h:111
 TMethodCall.h:112
 TMethodCall.h:113
 TMethodCall.h:114
 TMethodCall.h:115
 TMethodCall.h:116
 TMethodCall.h:117
 TMethodCall.h:118
 TMethodCall.h:119
 TMethodCall.h:120
 TMethodCall.h:121
 TMethodCall.h:122
 TMethodCall.h:123
 TMethodCall.h:124
 TMethodCall.h:125
 TMethodCall.h:126
 TMethodCall.h:127
 TMethodCall.h:128
 TMethodCall.h:129
 TMethodCall.h:130
 TMethodCall.h:131
 TMethodCall.h:132
 TMethodCall.h:133
 TMethodCall.h:134
 TMethodCall.h:135
 TMethodCall.h:136
 TMethodCall.h:137
 TMethodCall.h:138
 TMethodCall.h:139
 TMethodCall.h:140
 TMethodCall.h:141
 TMethodCall.h:142
 TMethodCall.h:143
 TMethodCall.h:144
 TMethodCall.h:145
 TMethodCall.h:146