// @(#)root/meta:$Id$
// Author: Philippe Canal November 2013.

/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Dictionary for function template                                     //
// This class describes one single function template.                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TFunctionTemplate.h"
#include "TInterpreter.h"
#include "TClass.h"
#include "TROOT.h"

ClassImp(TFunctionTemplate)

//______________________________________________________________________________
TFunctionTemplate::TFunctionTemplate(FuncTempInfo_t *info, TClass *cl) : TDictionary(),
   fInfo(info), fClass(cl)
{
   // Default TFunctionTemplate ctor.

   if (fInfo) {
      gCling->FuncTempInfo_Name(fInfo,fName);
      gCling->FuncTempInfo_Title(fInfo,fTitle);
   }
}

//______________________________________________________________________________
TFunctionTemplate::TFunctionTemplate(const TFunctionTemplate &orig) : TDictionary(orig)
{
   // Copy operator.

   if (orig.fInfo) {
      fInfo = gCling->FuncTempInfo_FactoryCopy(orig.fInfo);
   } else
      fInfo = 0;
   fClass = orig.fClass;
}

//______________________________________________________________________________
TFunctionTemplate& TFunctionTemplate::operator=(const TFunctionTemplate &rhs)
{
   // Assignment operator.

   if (this != &rhs) {
      gCling->FuncTempInfo_Delete(fInfo);
      if (rhs.fInfo) {
         fInfo = gCling->FuncTempInfo_FactoryCopy(rhs.fInfo);
         gCling->FuncTempInfo_Name(fInfo,fName);
         gCling->FuncTempInfo_Title(fInfo,fTitle);
      } else
         fInfo = 0;
   }
   return *this;
}

//______________________________________________________________________________
TFunctionTemplate::~TFunctionTemplate()
{
   // TFunctionTemplate dtor deletes adopted CINT FuncTempInfo.

   gCling->FuncTempInfo_Delete(fInfo);
}

//______________________________________________________________________________
TObject *TFunctionTemplate::Clone(const char *newname) const
{
   // Clone method.

   TNamed *newobj = new TFunctionTemplate(*this);
   if (newname && strlen(newname)) newobj->SetName(newname);
   return newobj;
}

//______________________________________________________________________________
Bool_t TFunctionTemplate::IsValid()
{
   // Return true if this function template object is pointing to a currently
   // loaded function.  If a function is unloaded after the TFunction
   // is created, the TFunction will be set to be invalid.

   // Register the transaction when checking the validity of the object.
   if (!fInfo && UpdateInterpreterStateMarker()) {
      // Only for global functions. For data member functions TMethod does it.
      DeclId_t newId = gInterpreter->GetFunction(0, fName);
      if (newId) {
         FuncTempInfo_t *info = gInterpreter->FuncTempInfo_Factory(newId);
         Update(info);
      }
      return newId != 0;
   }
   return fInfo != 0;
}

//______________________________________________________________________________
UInt_t TFunctionTemplate::GetTemplateNargs() const
{
   // Number of function arguments.

   return fInfo ? gCling->FuncTempInfo_TemplateNargs(fInfo) : 0;
}

//______________________________________________________________________________
UInt_t TFunctionTemplate::GetTemplateMinReqArgs() const
{
   // Number of function optional (default) arguments.

   // FIXME: when unload this is an over-estimate.
   return fInfo ? gCling->FuncTempInfo_TemplateMinReqArgs(fInfo) : 0;
}

//______________________________________________________________________________
Long_t TFunctionTemplate::Property() const
{
   // Get property description word. For meaning of bits see EProperty.

   return fInfo ? gCling->FuncTempInfo_Property(fInfo) : 0;
}

//______________________________________________________________________________
TDictionary::DeclId_t TFunctionTemplate::GetDeclId() const
{
   return gInterpreter->GetDeclId(fInfo);
}

//______________________________________________________________________________
Bool_t TFunctionTemplate::Update(FuncTempInfo_t *info)
{
   // Update the TFunctionTemplate to reflect the new info.
   //
   // This can be used to implement unloading (info == 0) and then reloading
   // (info being the 'new' decl address).

   if (info == 0) {
      if (fInfo) gCling->FuncTempInfo_Delete(fInfo);
      fInfo = 0;
      return kTRUE;
   } else {
      if (fInfo) gCling->FuncTempInfo_Delete(fInfo);
      fInfo = info;
      gCling->FuncTempInfo_Title(fInfo,fTitle);
      return kTRUE;
   }
}

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