|
||||
File indexing completed on 2025-01-18 10:12:33
0001 // @(#)root/cont:$Id$ 0002 // Author: Philippe Canal 20/08/2003 0003 0004 /************************************************************************* 0005 * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers and al. * 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_TVirtualCollectionProxy 0013 #define ROOT_TVirtualCollectionProxy 0014 0015 ////////////////////////////////////////////////////////////////////////// 0016 // // 0017 // TVirtualCollectionProxy // 0018 // // 0019 // Virtual interface of a proxy object for a collection class // 0020 // In particular this is used to implement splitting, emulation, // 0021 // and TTreeFormula access to STL containers. // 0022 // // 0023 ////////////////////////////////////////////////////////////////////////// 0024 0025 #include "TClassRef.h" 0026 #include "TDataType.h" 0027 0028 // Macro indicating the version of the Collection Proxy interface followed 0029 // by this ROOT build (See also Reflex/Builder/CollectionProxy.h). 0030 #define ROOT_COLLECTIONPROXY_VERSION 3 0031 0032 class TClass; 0033 namespace TStreamerInfoActions { 0034 class TActionSequence; 0035 } 0036 0037 // clang-format off 0038 /** 0039 \class TVirtualCollectionProxy 0040 \brief Defines a common interface to inspect/change the contents of an object that represents a collection 0041 0042 Specifically, an object of a class that derives from TVirtualCollectionProxy relays accesses to any object that 0043 matches the proxied collection type. 0044 The interface provides two families of functions: (i) for direct manipulation, e.g. `Insert()` or `At()`; and 0045 (ii) iterator-based, e.g. `GetFunctionCreateIterators()` or `GetFunctionNext()`. 0046 TVirtualCollectionProxy objects are stateful; in particular, many functions require to set the object to operate 0047 on via `PushProxy()` / `PopProxy()`. The `TPushPop` RAII class is provided for convenience. 0048 A collection proxy for a given class can be permanently set using `TClass::CopyCollectionProxy()`. 0049 The `Generate()` function should be overridden in derived classes to return a clean object of the most-derived class. 0050 */ 0051 // clang-format on 0052 class TVirtualCollectionProxy { 0053 private: 0054 TVirtualCollectionProxy(const TVirtualCollectionProxy&) = delete; 0055 TVirtualCollectionProxy& operator=(const TVirtualCollectionProxy&) = delete; 0056 0057 protected: 0058 TClassRef fClass; 0059 UInt_t fProperties; 0060 friend class TClass; 0061 0062 public: 0063 enum EProperty { 0064 // No longer used 0065 // kIsInitialized = BIT(1), 0066 kIsAssociative = BIT(2), 0067 kIsEmulated = BIT(3), 0068 /// The collection contains directly or indirectly (via other collection) some pointers that need explicit 0069 /// deletion 0070 kNeedDelete = BIT(4), 0071 kCustomAlloc = BIT(5) ///< The collection has a custom allocator. 0072 }; 0073 0074 /// RAII helper class that ensures that `PushProxy()` / `PopProxy()` are called when entering / leaving a C++ context 0075 class TPushPop { 0076 public: 0077 TVirtualCollectionProxy *fProxy; 0078 inline TPushPop(TVirtualCollectionProxy *proxy, 0079 void *objectstart) : fProxy(proxy) { fProxy->PushProxy(objectstart); } 0080 inline ~TPushPop() { fProxy->PopProxy(); } 0081 private: 0082 TPushPop(const TPushPop&) = delete; 0083 TPushPop& operator=(const TPushPop&) = delete; 0084 }; 0085 0086 TVirtualCollectionProxy() : fClass(), fProperties(0) {} 0087 TVirtualCollectionProxy(TClass *cl) : fClass(cl), fProperties(0) {} 0088 virtual ~TVirtualCollectionProxy() {} 0089 0090 /// Returns a clean object of the actual class that derives from TVirtualCollectionProxy. The caller is responsible 0091 /// for deleting the returned object. 0092 virtual TVirtualCollectionProxy *Generate() const = 0; 0093 0094 /// Reset the information gathered from StreamerInfos and value's TClass. 0095 virtual Bool_t Reset() { return kTRUE; } 0096 0097 /// Return a pointer to the `TClass` representing the proxied _container_ class 0098 virtual TClass *GetCollectionClass() const { return fClass; } 0099 0100 /// Return the type of the proxied collection (see enumeration TClassEdit::ESTLType) 0101 virtual Int_t GetCollectionType() const = 0; 0102 0103 /// Return the offset between two consecutive in-memory values (which depends on the `sizeof()` and alignment of the 0104 /// value type). 0105 virtual ULong_t GetIncrement() const = 0; 0106 0107 /// Return miscallenous properties of the proxy (see TVirtualCollectionProxy::EProperty) 0108 virtual Int_t GetProperties() const { return fProperties; } 0109 0110 /// Construct a new container object and return its address 0111 virtual void *New() const { return !fClass.GetClass() ? nullptr : fClass->New(); } 0112 /// Construct a new container object at the address given by `arena` 0113 virtual void *New(void *arena) const { return !fClass.GetClass() ? nullptr : fClass->New(arena); } 0114 /// Construct a new container object and return its address 0115 virtual TClass::ObjectPtr NewObject() const 0116 { 0117 return !fClass.GetClass() ? TClass::ObjectPtr{} : fClass->NewObject(); 0118 } 0119 /// Construct a new container object at the address given by `arena` 0120 virtual TClass::ObjectPtr NewObject(void *arena) const 0121 { 0122 return !fClass.GetClass() ? TClass::ObjectPtr{} : fClass->NewObject(arena); 0123 } 0124 0125 /// Construct an array of `nElements` container objects and return the base address of the array 0126 virtual void *NewArray(Int_t nElements) const { return !fClass.GetClass() ? nullptr : fClass->NewArray(nElements); } 0127 /// Construct an array of `nElements` container objects at the address given by `arena` 0128 virtual void *NewArray(Int_t nElements, void *arena) const 0129 { 0130 return !fClass.GetClass() ? nullptr : fClass->NewArray(nElements, arena); 0131 } 0132 /// Construct an array of `nElements` container objects and return the base address of the array 0133 virtual TClass::ObjectPtr NewObjectArray(Int_t nElements) const 0134 { 0135 return !fClass.GetClass() ? TClass::ObjectPtr{} : fClass->NewObjectArray(nElements); 0136 } 0137 /// Construct an array of `nElements` container objects at the address given by `arena` 0138 virtual TClass::ObjectPtr NewObjectArray(Int_t nElements, void *arena) const 0139 { 0140 return !fClass.GetClass() ? TClass::ObjectPtr{} : fClass->NewObjectArray(nElements, arena); 0141 } 0142 0143 /// Execute the container destructor 0144 virtual void Destructor(void *p, Bool_t dtorOnly = kFALSE) const 0145 { 0146 TClass* cl = fClass.GetClass(); 0147 if (cl) cl->Destructor(p, dtorOnly); 0148 } 0149 0150 /// Execute the container array destructor 0151 virtual void DeleteArray(void *p, Bool_t dtorOnly = kFALSE) const 0152 { 0153 TClass* cl = fClass.GetClass(); 0154 if (cl) cl->DeleteArray(p, dtorOnly); 0155 } 0156 0157 /// Return the `sizeof()` of the collection object 0158 virtual UInt_t Sizeof() const = 0; 0159 0160 /// Set the address of the container being proxied and keep track of the previous one 0161 virtual void PushProxy(void *objectstart) = 0; 0162 0163 /// Reset the address of the container being proxied to the previous container 0164 virtual void PopProxy() = 0; 0165 0166 /// Return `true` if the content is of type 'pointer to' 0167 virtual Bool_t HasPointers() const = 0; 0168 0169 /// If the value type is a user-defined class, return a pointer to the `TClass` representing the 0170 /// value type of the container. 0171 virtual TClass *GetValueClass() const = 0; 0172 0173 /// If the value type is a fundamental data type, return its type (see enumeration EDataType). 0174 virtual EDataType GetType() const = 0; 0175 0176 /// Return the address of the value at index `idx` 0177 virtual void *At(UInt_t idx) = 0; 0178 0179 /// Clear the container 0180 virtual void Clear(const char *opt = "") = 0; 0181 0182 /// Return the current number of elements in the container 0183 virtual UInt_t Size() const = 0; 0184 0185 /// Allocates space for storing at least `n` elements. This function returns a pointer to the actual object on 0186 /// which insertions should take place. For associative collections, this function returns a pointer to a temporary 0187 /// buffer known as the staging area. If the insertion happened in a staging area (i.e. the returned pointer != 0188 /// proxied object), `Commit()` should be called on the value returned by this function. 0189 virtual void* Allocate(UInt_t n, Bool_t forceDelete) = 0; 0190 0191 /// Commits pending elements in a staging area (see Allocate() for more information). 0192 virtual void Commit(void*) = 0; 0193 0194 /// Insert elements into the proxied container. `data` is a C-style array of the value type of the given `size`. 0195 /// For associative containers, e.g. `std::map`, the data type should be `std::pair<Key_t, Value_t>`. 0196 virtual void Insert(const void *data, void *container, size_t size) = 0; 0197 0198 /// Return the address of the value at index `idx` 0199 char *operator[](UInt_t idx) const { return (char *)(const_cast<TVirtualCollectionProxy *>(this))->At(idx); } 0200 0201 // Functions related to member-wise actions 0202 virtual TStreamerInfoActions::TActionSequence *GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version) = 0; 0203 virtual TStreamerInfoActions::TActionSequence *GetReadMemberWiseActions(Int_t version) = 0; 0204 virtual TStreamerInfoActions::TActionSequence *GetWriteMemberWiseActions() = 0; 0205 0206 /// The size of a small buffer that can be allocated on the stack to store iterator-specific information 0207 static const Int_t fgIteratorArenaSize = 16; // greater than sizeof(void*) + sizeof(UInt_t) 0208 0209 /// `*begin_arena` and `*end_arena` should contain the location of a memory arena of size `fgIteratorArenaSize`. 0210 /// If iterator-specific information is of that size or less, the iterators will be constructed in place in the given 0211 /// locations. Otherwise, iterators will be allocated via `new` and their address returned by modifying the value 0212 /// of `*begin_arena` and `*end_arena`. 0213 /// As a special case, given that iterators for array-backed containers are just pointers, the required information 0214 /// will be directly stored in `*(begin|end)_arena`. 0215 typedef void (*CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy); 0216 0217 /// Return a pointer to a function that can create an iterator pair, where each iterator points to the begin and end 0218 /// of the collection, respectively (see CreateIterators_t). If `read == kTRUE`, data is to be read from disk, i.e. 0219 /// written to the in-memory collection. 0220 virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read = kTRUE) = 0; 0221 0222 /// Copy the iterator `source` into `dest`. `dest` should contain the location of a memory arena of size 0223 /// `fgIteratorArenaSize`. 0224 /// If iterator-specific information is of that size or less, the iterators will be constructed in place in the given 0225 /// locations. Otherwise, iterators will be allocated via `new` and their address returned by modifying the value 0226 /// of `*begin_arena` and `*end_arena`. The actual address of the iterator is returned in any case. 0227 typedef void* (*CopyIterator_t)(void *dest, const void *source); 0228 0229 /// Return a pointer to a function that can copy an iterator (see CopyIterator_t). If `read == kTRUE`, data is to be 0230 /// read from disk, i.e. written to the in-memory collection. 0231 virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read = kTRUE) = 0; 0232 0233 /// `iter` and `end` should be pointers to an iterator to be incremented and an iterator that points to the end of 0234 /// the collection, respectively. If `iter` has not reached the end of the collection, this function increments the 0235 /// iterator and returns a pointer to the element before the increment. Otherwise, `nullptr` is returned. 0236 typedef void* (*Next_t)(void *iter, const void *end); 0237 0238 /// Return a pointer to a function that can advance an iterator (see Next_t). If `read == kTRUE`, data is to be 0239 /// read from disk, i.e. written to the in-memory collection. 0240 virtual Next_t GetFunctionNext(Bool_t read = kTRUE) = 0; 0241 0242 /// If the size of the iterator is greater than `fgIteratorArenaSize`, call delete on the addresses; otherwise, just 0243 /// call the iterator's destructor. 0244 typedef void (*DeleteIterator_t)(void *iter); 0245 typedef void (*DeleteTwoIterators_t)(void *begin, void *end); 0246 0247 /// Return a pointer to a function that can delete an iterator (pair) (see DeleteIterator_t). If `read == kTRUE`, 0248 /// data is to be read from disk, i.e. written to the in-memory collection. 0249 virtual DeleteIterator_t GetFunctionDeleteIterator(Bool_t read = kTRUE) = 0; 0250 virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read = kTRUE) = 0; 0251 }; 0252 0253 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |