// @(#)root/metautils:$Id$
// Author: Victor Perev   10/04/2003
//         Philippe Canal 05/2004

/*************************************************************************
 * Copyright (C) 1995-2003, 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_TClassEdit
#define ROOT_TClassEdit

#include "RConfig.h"
#include "RConfigure.h"
#include <stdlib.h>
#ifdef R__WIN32
#ifndef UNDNAME_COMPLETE
#define UNDNAME_COMPLETE 0x0000
#endif
extern "C" {
   char *__unDName(char *demangled, const char *mangled, int out_len,
                   void * (* pAlloc )(size_t), void (* pFree )(void *),
                   unsigned short int flags);
}
#else
#include <cxxabi.h>
#endif
#include <string>
#include <vector>

#ifndef ROOT_ESTLType
#include "ESTLType.h"
#endif

#ifdef R__OLDHPACC
namespace std {
   using ::string;
   using ::vector;
}
#endif

#if defined(__CYGWIN__)
// std::to_string is missing on cygwin with gcc 4.8.2-2 and 4.8.3
#include <sstream>
namespace std {
  template <typename T>
  string to_string(T value) {
    ostringstream os;
    os << value;
    return os.str();
  }
}
#endif

namespace cling {
   class Interpreter;
}
namespace ROOT {
   namespace TMetaUtils {
      class TNormalizedCtxt;
   }
}

// TClassEdit is used to manipulate class and type names.
//
// This class does not dependent on any other ROOT facility
// so that it can be used by rootcint.

namespace TClassEdit {

   enum EModType {
      kNone             = 0,
      kDropTrailStar    = 1<<0,
      kDropDefaultAlloc = 1<<1,
      kDropAlloc        = 1<<2,
      kInnerClass       = 1<<3,
      kInnedMostClass   = 1<<4,
      kDropStlDefault   = 1<<5, /* implies kDropDefaultAlloc */
      kDropComparator   = 1<<6, /* if the class has a comparator, drops BOTH the comparator and the Allocator */
      kDropAllDefault   = 1<<7, /* Drop default template parameter even in non STL classes */
      kLong64           = 1<<8, /* replace all 'long long' with Long64_t. */
      kDropStd          = 1<<9, /* Drop any std:: */
      kKeepOuterConst   = 1<<10,/* Make sure to keep the const keyword even outside the template parameters */
      kResolveTypedef   = 1<<11 /* Strip all typedef except Double32_t and co. */
   };

   enum ESTLType {
      kNotSTL   = ROOT::kNotSTL,
      kVector   = ROOT::kSTLvector,
      kList     = ROOT::kSTLlist,
      kDeque    = ROOT::kSTLdeque,
      kMap      = ROOT::kSTLmap,
      kMultiMap = ROOT::kSTLmultimap,
      kSet      = ROOT::kSTLset,
      kMultiSet = ROOT::kSTLmultiset,
      kBitSet   = ROOT::kSTLbitset,
      kEnd      = ROOT::kSTLend
   };

   enum class EComplexType : short {
      kNone,
      kDouble,
      kFloat,
      kInt,
      kLong
   };

   EComplexType GetComplexType(const char*);

   class TInterpreterLookupHelper {
   public:
      TInterpreterLookupHelper() { }
      virtual ~TInterpreterLookupHelper() { }

      virtual bool ExistingTypeCheck(const std::string & /*tname*/,
                                     std::string & /*result*/) = 0;
      virtual void GetPartiallyDesugaredName(std::string & /*nameLong*/) = 0;
      virtual bool IsAlreadyPartiallyDesugaredName(const std::string & /*nondef*/,
                                                   const std::string & /*nameLong*/) = 0;
      virtual bool IsDeclaredScope(const std::string & /*base*/, bool & /*isInlined*/) = 0;
      virtual bool GetPartiallyDesugaredNameWithScopeHandling(const std::string & /*tname*/,
                                                              std::string & /*result*/) = 0;
   };

   struct TSplitType {

      const char *fName; // Original spelling of the name.
      std::vector<std::string> fElements;
      int fNestedLocation; // Stores the location of the tail (nested names) in nestedLoc (0 indicates no tail).

      TSplitType(const char *type2split, EModType mode = TClassEdit::kNone);

      int  IsSTLCont(int testAlloc=0) const;
      ROOT::ESTLType  IsInSTL() const;
      void ShortType(std::string &answer, int mode);

   private:
      TSplitType(const TSplitType&); // intentionally not implemented
      TSplitType &operator=(const TSplitType &); // intentionally not implemented
   };

   void        Init(TClassEdit::TInterpreterLookupHelper *helper);

   std::string CleanType (const char *typeDesc,int mode = 0,const char **tail=0);
   bool        IsDefAlloc(const char *alloc, const char *classname);
   bool        IsDefAlloc(const char *alloc, const char *keyclassname, const char *valueclassname);
   bool        IsDefComp (const char *comp , const char *classname);
   bool        IsInterpreterDetail(const char *type);
   bool        IsSTLBitset(const char *type);
   ROOT::ESTLType IsSTLCont (const char *type);
   int         IsSTLCont (const char *type,int testAlloc);
   bool        IsStdClass(const char *type);
   bool        IsVectorBool(const char *name);
   void        GetNormalizedName(std::string &norm_name,const char *name);
   std::string GetLong64_Name(const char *original);
   std::string GetLong64_Name(const std::string& original);
   int         GetSplit  (const char *type, std::vector<std::string> &output, int &nestedLoc, EModType mode = TClassEdit::kNone);
   ROOT::ESTLType STLKind   (const char *type, size_t len = 0);    //Kind of stl container
   int         STLArgs   (int kind);            //Min number of arguments without allocator
   std::string ResolveTypedef(const char *tname, bool resolveAll = false);
   std::string ShortType (const char *typeDesc, int mode);
   std::string InsertStd(const char *tname);
   const char* GetUnqualifiedName(const char*name);
   inline char* DemangleName(const char* mangled_name, int& errorCode)
   {
   // Demangle in a portable way the name.
   // IMPORTANT: The caller is responsible for freeing the returned const char*

   errorCode=0;
#ifdef R__WIN32
   char *demangled_name = __unDName(0, mangled_name, 0, malloc, free, UNDNAME_COMPLETE);
   if (!demangled_name) {
      errorCode = -1;
      return nullptr;
   }
#else
   char *demangled_name = abi::__cxa_demangle(mangled_name, 0, 0, &errorCode);
   if (!demangled_name || errorCode) {
      free(demangled_name);
      return nullptr;
   }
#endif
   return demangled_name;
   }
   char* DemangleTypeIdName(const std::type_info& ti, int& errorCode);
}

#endif
 TClassEdit.h:1
 TClassEdit.h:2
 TClassEdit.h:3
 TClassEdit.h:4
 TClassEdit.h:5
 TClassEdit.h:6
 TClassEdit.h:7
 TClassEdit.h:8
 TClassEdit.h:9
 TClassEdit.h:10
 TClassEdit.h:11
 TClassEdit.h:12
 TClassEdit.h:13
 TClassEdit.h:14
 TClassEdit.h:15
 TClassEdit.h:16
 TClassEdit.h:17
 TClassEdit.h:18
 TClassEdit.h:19
 TClassEdit.h:20
 TClassEdit.h:21
 TClassEdit.h:22
 TClassEdit.h:23
 TClassEdit.h:24
 TClassEdit.h:25
 TClassEdit.h:26
 TClassEdit.h:27
 TClassEdit.h:28
 TClassEdit.h:29
 TClassEdit.h:30
 TClassEdit.h:31
 TClassEdit.h:32
 TClassEdit.h:33
 TClassEdit.h:34
 TClassEdit.h:35
 TClassEdit.h:36
 TClassEdit.h:37
 TClassEdit.h:38
 TClassEdit.h:39
 TClassEdit.h:40
 TClassEdit.h:41
 TClassEdit.h:42
 TClassEdit.h:43
 TClassEdit.h:44
 TClassEdit.h:45
 TClassEdit.h:46
 TClassEdit.h:47
 TClassEdit.h:48
 TClassEdit.h:49
 TClassEdit.h:50
 TClassEdit.h:51
 TClassEdit.h:52
 TClassEdit.h:53
 TClassEdit.h:54
 TClassEdit.h:55
 TClassEdit.h:56
 TClassEdit.h:57
 TClassEdit.h:58
 TClassEdit.h:59
 TClassEdit.h:60
 TClassEdit.h:61
 TClassEdit.h:62
 TClassEdit.h:63
 TClassEdit.h:64
 TClassEdit.h:65
 TClassEdit.h:66
 TClassEdit.h:67
 TClassEdit.h:68
 TClassEdit.h:69
 TClassEdit.h:70
 TClassEdit.h:71
 TClassEdit.h:72
 TClassEdit.h:73
 TClassEdit.h:74
 TClassEdit.h:75
 TClassEdit.h:76
 TClassEdit.h:77
 TClassEdit.h:78
 TClassEdit.h:79
 TClassEdit.h:80
 TClassEdit.h:81
 TClassEdit.h:82
 TClassEdit.h:83
 TClassEdit.h:84
 TClassEdit.h:85
 TClassEdit.h:86
 TClassEdit.h:87
 TClassEdit.h:88
 TClassEdit.h:89
 TClassEdit.h:90
 TClassEdit.h:91
 TClassEdit.h:92
 TClassEdit.h:93
 TClassEdit.h:94
 TClassEdit.h:95
 TClassEdit.h:96
 TClassEdit.h:97
 TClassEdit.h:98
 TClassEdit.h:99
 TClassEdit.h:100
 TClassEdit.h:101
 TClassEdit.h:102
 TClassEdit.h:103
 TClassEdit.h:104
 TClassEdit.h:105
 TClassEdit.h:106
 TClassEdit.h:107
 TClassEdit.h:108
 TClassEdit.h:109
 TClassEdit.h:110
 TClassEdit.h:111
 TClassEdit.h:112
 TClassEdit.h:113
 TClassEdit.h:114
 TClassEdit.h:115
 TClassEdit.h:116
 TClassEdit.h:117
 TClassEdit.h:118
 TClassEdit.h:119
 TClassEdit.h:120
 TClassEdit.h:121
 TClassEdit.h:122
 TClassEdit.h:123
 TClassEdit.h:124
 TClassEdit.h:125
 TClassEdit.h:126
 TClassEdit.h:127
 TClassEdit.h:128
 TClassEdit.h:129
 TClassEdit.h:130
 TClassEdit.h:131
 TClassEdit.h:132
 TClassEdit.h:133
 TClassEdit.h:134
 TClassEdit.h:135
 TClassEdit.h:136
 TClassEdit.h:137
 TClassEdit.h:138
 TClassEdit.h:139
 TClassEdit.h:140
 TClassEdit.h:141
 TClassEdit.h:142
 TClassEdit.h:143
 TClassEdit.h:144
 TClassEdit.h:145
 TClassEdit.h:146
 TClassEdit.h:147
 TClassEdit.h:148
 TClassEdit.h:149
 TClassEdit.h:150
 TClassEdit.h:151
 TClassEdit.h:152
 TClassEdit.h:153
 TClassEdit.h:154
 TClassEdit.h:155
 TClassEdit.h:156
 TClassEdit.h:157
 TClassEdit.h:158
 TClassEdit.h:159
 TClassEdit.h:160
 TClassEdit.h:161
 TClassEdit.h:162
 TClassEdit.h:163
 TClassEdit.h:164
 TClassEdit.h:165
 TClassEdit.h:166
 TClassEdit.h:167
 TClassEdit.h:168
 TClassEdit.h:169
 TClassEdit.h:170
 TClassEdit.h:171
 TClassEdit.h:172
 TClassEdit.h:173
 TClassEdit.h:174
 TClassEdit.h:175
 TClassEdit.h:176
 TClassEdit.h:177
 TClassEdit.h:178
 TClassEdit.h:179
 TClassEdit.h:180
 TClassEdit.h:181
 TClassEdit.h:182
 TClassEdit.h:183
 TClassEdit.h:184
 TClassEdit.h:185
 TClassEdit.h:186
 TClassEdit.h:187
 TClassEdit.h:188
 TClassEdit.h:189
 TClassEdit.h:190
 TClassEdit.h:191