// @(#)root/cont:$Id$
// Author: Philippe Canal 20/08/2003

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

#ifndef ROOT_TVirtualCollectionProxy
#define ROOT_TVirtualCollectionProxy

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TVirtualCollectionProxy                                              //
//                                                                      //
// Virtual interface of a proxy object for a collection class           //
// In particular this is used to implement splitting, emulation,        //
// and TTreeFormula access to STL containers.                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif
#include "TClassRef.h"
#include "TDataType.h"

// Macro indicating the version of the Collection Proxy interface followed
// by this ROOT build (See also Reflex/Builder/CollectionProxy.h).

#define ROOT_COLLECTIONPROXY_VERSION 3

class TClass;
namespace TStreamerInfoActions {
   class TActionSequence;
}

class TVirtualCollectionProxy {
private:
   TVirtualCollectionProxy(const TVirtualCollectionProxy&); // Not implemented
   TVirtualCollectionProxy& operator=(const TVirtualCollectionProxy&); // Not implemented

protected:
   TClassRef fClass;
   UInt_t    fProperties;
   virtual void UpdateValueClass(const TClass *oldcl, TClass *newcl) = 0;
   friend class TClass;

public:
   enum EProperty {
      // No longer used
      // kIsInitialized = BIT(1),
      kIsAssociative = BIT(2),
      kIsEmulated    = BIT(3),
      kNeedDelete    = BIT(4)   // Flag to indicate that this collection that contains directly or indirectly (only via other collection) some pointers that will need explicit deletions.
   };

   class TPushPop {
      // Helper class that insures that push and pop are done when entering
      // and leaving a C++ context (even in the presence of exceptions)
   public:
      TVirtualCollectionProxy *fProxy;
      inline TPushPop(TVirtualCollectionProxy *proxy,
         void *objectstart) : fProxy(proxy) { fProxy->PushProxy(objectstart); }
      inline ~TPushPop() { fProxy->PopProxy(); }
   private:
      TPushPop(const TPushPop&); // Not implemented
      TPushPop& operator=(const TPushPop&); // Not implemented
   };

   TVirtualCollectionProxy() : fClass(), fProperties(0) {};
   TVirtualCollectionProxy(TClass *cl) : fClass(cl), fProperties(0) {};

   virtual TVirtualCollectionProxy* Generate() const = 0; // Returns an object of the actual CollectionProxy class
   virtual ~TVirtualCollectionProxy() {};

   virtual TClass   *GetCollectionClass() const { return fClass; }
   // Return a pointer to the TClass representing the container

   virtual Int_t     GetCollectionType() const = 0;
   // Return the type of collection see TClassEdit::ESTLType

   virtual ULong_t   GetIncrement() const = 0;
   // Return the offset between two consecutive value_types (memory layout).

   virtual Int_t     GetProperties() const { return fProperties; }
   // Return miscallenous properties of the proxy see TVirtualCollectionProxy::EProperty

   virtual void     *New() const {
      // Return a new container object
      return fClass.GetClass()==0 ? 0 : fClass->New();
   }
   virtual void     *New(void *arena) const {
      // Execute the container constructor
      return fClass.GetClass()==0 ? 0 : fClass->New(arena);
   }

   virtual void     *NewArray(Int_t nElements) const {
      // Return a new container object
      return fClass.GetClass()==0 ? 0 : fClass->NewArray(nElements);
   }
   virtual void     *NewArray(Int_t nElements, void *arena) const {
      // Execute the container constructor
      return fClass.GetClass()==0 ? 0 : fClass->NewArray(nElements, arena);
   }

   virtual void      Destructor(void *p, Bool_t dtorOnly = kFALSE) const {
      // Execute the container destructor
      TClass* cl = fClass.GetClass();
      if (cl) cl->Destructor(p, dtorOnly);
   }

   virtual void      DeleteArray(void *p, Bool_t dtorOnly = kFALSE) const {
      // Execute the container array destructor
      TClass* cl = fClass.GetClass();
      if (cl) cl->DeleteArray(p, dtorOnly);
   }

   virtual UInt_t    Sizeof() const = 0;
   // Return the sizeof the collection object.

   virtual void      PushProxy(void *objectstart) = 0;
   // Set the address of the container being proxied and keep track of the previous one.

   virtual void      PopProxy() = 0;
   // Reset the address of the container being proxied to the previous container

   virtual Bool_t    HasPointers() const = 0;
   // Return true if the content is of type 'pointer to'

   virtual TClass   *GetValueClass() const = 0;
   // Return a pointer to the TClass representing the content.

   virtual EDataType GetType() const = 0;
   // If the content is a simple numerical value, return its type (see TDataType)

   virtual void     *At(UInt_t idx) = 0;
   // Return the address of the value at index 'idx'

   virtual void      Clear(const char *opt = "") = 0;
   // Clear the container

   virtual UInt_t    Size() const = 0;
   // Return the current size of the container

   virtual void*     Allocate(UInt_t n, Bool_t forceDelete) = 0;

   virtual void      Commit(void*) = 0;

   virtual void      Insert(const void *data, void *container, size_t size) = 0;
   // Insert data into the container where data is a C-style array of the actual type contained in the collection
   // of the given size.   For associative container (map, etc.), the data type is the pair<key,value>.

           char     *operator[](UInt_t idx) const { return (char*)(const_cast<TVirtualCollectionProxy*>(this))->At(idx); }

   // MemberWise actions
   virtual TStreamerInfoActions::TActionSequence *GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version) = 0;
   virtual TStreamerInfoActions::TActionSequence *GetReadMemberWiseActions(Int_t version) = 0;
   virtual TStreamerInfoActions::TActionSequence *GetWriteMemberWiseActions() = 0;

   // Set of functions to iterate easily throught the collection
   static const Int_t fgIteratorArenaSize = 16; // greater than sizeof(void*) + sizeof(UInt_t)

   typedef void (*CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy);
   virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read = kTRUE) = 0;
   // begin_arena and end_arena should contain the location of a memory arena of size fgIteratorSize.
   // If the collection iterator are of that size or less, the iterators will be constructed in place in those location (new with placement)
   // Otherwise the iterators will be allocated via a regular new and their address returned by modifying the value of begin_arena and end_arena.

   typedef void* (*CopyIterator_t)(void *dest, const void *source);
   virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read = kTRUE) = 0;
   // Copy the iterator source, into dest.   dest should contain the location of a memory arena of size fgIteratorSize.
   // If the collection iterator is of that size or less, the iterator will be constructed in place in this location (new with placement)
   // Otherwise the iterator will be allocated via a regular new.
   // The actual address of the iterator is returned in both case.

   typedef void* (*Next_t)(void *iter, const void *end);
   virtual Next_t GetFunctionNext(Bool_t read = kTRUE) = 0;
   // iter and end should be pointers to respectively an iterator to be incremented and the result of collection.end()
   // If the iterator has not reached the end of the collection, 'Next' increment the iterator 'iter' and return 0 if
   // the iterator reached the end.
   // If the end was not reached, 'Next' returns the address of the content pointed to by the iterator before the
   // incrementation ; if the collection contains pointers, 'Next' will return the value of the pointer.

   typedef void (*DeleteIterator_t)(void *iter);
   typedef void (*DeleteTwoIterators_t)(void *begin, void *end);

   virtual DeleteIterator_t GetFunctionDeleteIterator(Bool_t read = kTRUE) = 0;
   virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read = kTRUE) = 0;
   // If the size of the iterator is greater than fgIteratorArenaSize, call delete on the addresses,
   // Otherwise just call the iterator's destructor.

};

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