Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TEmulatedCollectionProxy.h
Go to the documentation of this file.
1// @(#)root/io:$Id$
2// Author: Markus Frank 28/10/04
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11#ifndef ROOT_TEmulatedCollectionProxy
12#define ROOT_TEmulatedCollectionProxy
13
14#include "TGenCollectionProxy.h"
15#include "ROOT/BitUtils.hxx"
16
17#include <type_traits>
18#include <vector>
19
21
22 // Friend declaration
23 friend class TCollectionProxy;
24
25public:
26 // Convenience vector aliases for each supported alignment.
27 // clang-format off
28 using Cont1_t = std::vector<ROOT::Internal::RAlignedStorage< 1>>;
29 using Cont2_t = std::vector<ROOT::Internal::RAlignedStorage< 2>>;
30 using Cont4_t = std::vector<ROOT::Internal::RAlignedStorage< 4>>;
31 using Cont8_t = std::vector<ROOT::Internal::RAlignedStorage< 8>>;
32 using Cont16_t = std::vector<ROOT::Internal::RAlignedStorage< 16>>;
33 using Cont32_t = std::vector<ROOT::Internal::RAlignedStorage< 32>>;
34 using Cont64_t = std::vector<ROOT::Internal::RAlignedStorage< 64>>;
35 using Cont128_t = std::vector<ROOT::Internal::RAlignedStorage< 128>>;
36 using Cont256_t = std::vector<ROOT::Internal::RAlignedStorage< 256>>;
37 using Cont512_t = std::vector<ROOT::Internal::RAlignedStorage< 512>>;
38 using Cont1024_t = std::vector<ROOT::Internal::RAlignedStorage<1024>>;
39 using Cont2048_t = std::vector<ROOT::Internal::RAlignedStorage<2048>>;
40 using Cont4096_t = std::vector<ROOT::Internal::RAlignedStorage<4096>>;
41 // clang-format on
42
43 // Canonical container type (used for sizeof/typeid; actual alignment is
44 // selected at runtime via the alignment switch in each method).
45 using Cont_t = std::vector<char>;
46 using PCont_t = Cont_t *;
47
48 /// Invoke \a fn(typed_ptr, elemSize) where typed_ptr is the container
49 /// pointer cast to the correct AlignedStorage<N>* for the value class
50 /// alignment. \a fn receives the element size (N) as a second argument
51 /// so it can convert byte counts to element counts.
52 template <typename F>
53 void WithCont(void *obj, F &&fn) const
54 {
55 auto *vcl = GetValueClass();
56 std::size_t align = alignof(std::max_align_t);
57 if (!fKey && (fVal->fCase & kIsPointer)) {
58 // If the collection contains pointers, we need to use the alignment of a pointer, not of the value class.
59 align = alignof(void*);
60 } else if (vcl) {
61 assert(ROOT::Internal::IsValidAlignment(vcl->GetClassAlignment()));
62 align = vcl->GetClassAlignment();
63 } else {
64 switch( int(fVal->fKind) ) {
65 case kChar_t:
66 case kUChar_t: align = alignof(char); break;
67 case kShort_t:
68 case kUShort_t: align = alignof(short); break;
69 case kInt_t:
70 case kUInt_t: align = alignof(int); break;
71 case kLong_t:
72 case kULong_t: align = alignof(long); break;
73 case kLong64_t:
74 case kULong64_t:align = alignof(long long); break;
75 case kFloat16_t:
76 case kFloat_t: align = alignof(float); break;
77 case kDouble32_t:
78 case kDouble_t: align = alignof(double); break;
79 default:
80 Fatal("TEmulatedCollectionProxy::WithCont", "Unsupported value type %d for value class %s", fVal->fKind,
81 vcl ? vcl->GetName() : "<unknown>");
82 }
83 }
84 switch (align) {
85 // When adding new cases here, also update the static_assert in TClingUtils.cxx
86 // to explicitly allow the new alignment and to update the error message accordingly.
87 case 4096: fn(reinterpret_cast<Cont4096_t*>(obj), std::size_t(4096)); break;
88 case 2048: fn(reinterpret_cast<Cont2048_t*>(obj), std::size_t(2048)); break;
89 case 1024: fn(reinterpret_cast<Cont1024_t*>(obj), std::size_t(1024)); break;
90 case 512: fn(reinterpret_cast<Cont512_t *>(obj), std::size_t( 512)); break;
91 case 256: fn(reinterpret_cast<Cont256_t *>(obj), std::size_t( 256)); break;
92 case 128: fn(reinterpret_cast<Cont128_t *>(obj), std::size_t( 128)); break;
93 case 64: fn(reinterpret_cast<Cont64_t *>(obj), std::size_t( 64)); break;
94 case 32: fn(reinterpret_cast<Cont32_t *>(obj), std::size_t( 32)); break;
95 case 16: fn(reinterpret_cast<Cont16_t *>(obj), std::size_t( 16)); break;
96 case 8: fn(reinterpret_cast<Cont8_t *>(obj), std::size_t( 8)); break;
97 case 4: fn(reinterpret_cast<Cont4_t *>(obj), std::size_t( 4)); break;
98 case 2: fn(reinterpret_cast<Cont2_t *>(obj), std::size_t( 2)); break;
99 case 1: fn(reinterpret_cast<Cont1_t *>(obj), std::size_t( 1)); break;
100 default:
101 Fatal("TEmulatedCollectionProxy::WithCont", "Unsupported alignment %zu for value class %s",
102 align, vcl ? vcl->GetName() : "<unknown>");
103 }
104 }
105protected:
106
107 // Some hack to avoid const-ness
109
110 // Object input streamer
111 void ReadItems(int nElements, TBuffer &b);
112
113 // Object output streamer
114 void WriteItems(int nElements, TBuffer &b);
115
116 // Shrink the container
117 void Shrink(UInt_t nCurr, UInt_t left, Bool_t force);
118
119 // Expand the container
120 void Expand(UInt_t nCurr, UInt_t left);
121
122private:
124
125public:
126 // Virtual copy constructor
127 TVirtualCollectionProxy* Generate() const override;
128
129 // Copy constructor
131
132 // Initializing constructor
134
135 // Standard destructor
136 ~TEmulatedCollectionProxy() override;
137
138 // Virtual constructor
139 void *New() const override
140 {
141 void *mem = ::operator new(sizeof(Cont_t));
142 WithCont(mem, [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
143 return mem;
144 }
145
146 // Virtual in-place constructor
147 void *New(void *memory) const override
148 {
149 WithCont(memory, [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
150 return memory;
151 }
152
153 // Virtual constructor
154 TClass::ObjectPtr NewObject() const override { return {New(), nullptr}; }
155
156 // Virtual in-place constructor
157 TClass::ObjectPtr NewObject(void *memory) const override { return {New(memory), nullptr}; }
158
159 // Virtual array constructor
160 void *NewArray(Int_t nElements) const override
161 {
162 void *arr = ::operator new(nElements * sizeof(Cont_t));
163 for (Int_t i = 0; i < nElements; ++i)
164 WithCont(static_cast<char *>(arr) + i * sizeof(Cont_t),
165 [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
166 return arr;
167 }
168
169 // Virtual in-place array constructor
170 void *NewArray(Int_t nElements, void *memory) const override
171 {
172 for (Int_t i = 0; i < nElements; ++i)
173 WithCont(static_cast<char *>(memory) + i * sizeof(Cont_t),
174 [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
175 return memory;
176 }
177
178 // Virtual array constructor
179 TClass::ObjectPtr NewObjectArray(Int_t nElements) const override { return {NewArray(nElements), nullptr}; }
180
181 // Virtual in-place array constructor
183 {
184 return {NewArray(nElements, memory), nullptr};
185 }
186
187 // Virtual destructor
188 void Destructor(void* p, Bool_t dtorOnly = kFALSE) const override;
189
190 // Virtual array destructor
191 void DeleteArray(void* p, Bool_t dtorOnly = kFALSE) const override;
192
193 // TVirtualCollectionProxy overload: Return the sizeof the collection object.
194 UInt_t Sizeof() const override { return sizeof(Cont_t); }
195
196 // Return the address of the value at index 'idx'
197 void *At(UInt_t idx) override;
198
199 // Clear the container
200 void Clear(const char *opt = "") override;
201
202 // Resize the container
203 void Resize(UInt_t n, Bool_t force_delete) override;
204
205 // Return the current size of the container
206 UInt_t Size() const override;
207
208 // Block allocation of containees
209 void* Allocate(UInt_t n, Bool_t forceDelete) override;
210
211 // Block commit of containees
212 void Commit(void* env) override;
213
214 // Insert data into the container where data is a C-style array of the actual type contained in the collection
215 // of the given size. For associative container (map, etc.), the data type is the pair<key,value>.
216 void Insert(const void *data, void *container, size_t size) override;
217
218 // Read portion of the streamer
219 void ReadBuffer(TBuffer &buff, void *pObj) override;
220 void ReadBuffer(TBuffer &buff, void *pObj, const TClass *onfile) override;
221
222 // Streamer for I/O handling
223 void Streamer(TBuffer &refBuffer) override;
224
225 // Streamer I/O overload
226 void Streamer(TBuffer &buff, void *pObj, int siz) override
227 {
229 }
230
231 // Check validity of the proxy itself
232 Bool_t IsValid() const;
233};
234
235
237inline void PrintWriteStlWithoutProxyMsg(const char *where, const char *clName, const char *BranchName)
238{
239 const char *writeStlWithoutProxyMsg =
240 "The class requested (%s) for the branch \"%s\" "
241 "is an instance of an stl collection and does not have a compiled CollectionProxy. "
242 "Please generate the dictionary for this collection (%s) to avoid writing corrupted data.";
243 // This error message is repeated several times in the code. We write it once.
245}
246
247inline bool HasEmulatedProxy(TClass *cl){
248 return cl && cl->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy *>(cl->GetCollectionProxy());
249}
250} // namespace ROOT::Internal::TEmulatedProxyHelpers
251
252
253#endif
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ kFloat_t
Definition TDataType.h:31
@ kULong64_t
Definition TDataType.h:32
@ kInt_t
Definition TDataType.h:30
@ kLong_t
Definition TDataType.h:30
@ kDouble32_t
Definition TDataType.h:31
@ kShort_t
Definition TDataType.h:29
@ kULong_t
Definition TDataType.h:30
@ kLong64_t
Definition TDataType.h:32
@ kUShort_t
Definition TDataType.h:29
@ kDouble_t
Definition TDataType.h:31
@ kChar_t
Definition TDataType.h:29
@ kUChar_t
Definition TDataType.h:29
@ kUInt_t
Definition TDataType.h:30
@ kFloat16_t
Definition TDataType.h:33
@ kIsPointer
Definition TDictionary.h:78
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:267
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Buffer base class used for serializing objects.
Definition TBuffer.h:43
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2918
Streamer around an arbitrary STL like container, which implements basic container functionality.
TEmulatedCollectionProxy & operator=(const TEmulatedCollectionProxy &)
UInt_t Size() const override
Return the current number of elements in the container.
void Insert(const void *data, void *container, size_t size) override
Insert data into the container where data is a C-style array of the actual type contained in the coll...
TGenCollectionProxy * InitializeEx(Bool_t silent) override
Proxy initializer.
void * Allocate(UInt_t n, Bool_t forceDelete) override
Allocates space for storing at least n elements.
TClass::ObjectPtr NewObjectArray(Int_t nElements) const override
Construct an array of nElements container objects and return the base address of the array.
std::vector< ROOT::Internal::RAlignedStorage< 2048 > > Cont2048_t
void * NewArray(Int_t nElements) const override
Construct an array of nElements container objects and return the base address of the array.
std::vector< ROOT::Internal::RAlignedStorage< 128 > > Cont128_t
void Expand(UInt_t nCurr, UInt_t left)
std::vector< ROOT::Internal::RAlignedStorage< 64 > > Cont64_t
TClass::ObjectPtr NewObject() const override
Construct a new container object and return its address.
std::vector< ROOT::Internal::RAlignedStorage< 256 > > Cont256_t
void * New() const override
Construct a new container object and return its address.
void WriteItems(int nElements, TBuffer &b)
void * New(void *memory) const override
Construct a new container object at the address given by arena
TClass::ObjectPtr NewObject(void *memory) const override
Construct a new container object at the address given by arena
TVirtualCollectionProxy * Generate() const override
Returns a clean object of the actual class that derives from TVirtualCollectionProxy.
std::vector< ROOT::Internal::RAlignedStorage< 1 > > Cont1_t
void Commit(void *env) override
Commits pending elements in a staging area (see Allocate() for more information).
std::vector< ROOT::Internal::RAlignedStorage< 1024 > > Cont1024_t
std::vector< ROOT::Internal::RAlignedStorage< 4 > > Cont4_t
std::vector< ROOT::Internal::RAlignedStorage< 32 > > Cont32_t
void Streamer(TBuffer &buff, void *pObj, int siz) override
Streamer I/O overload.
std::vector< ROOT::Internal::RAlignedStorage< 16 > > Cont16_t
void Clear(const char *opt="") override
Clear the container.
std::vector< ROOT::Internal::RAlignedStorage< 8 > > Cont8_t
void * NewArray(Int_t nElements, void *memory) const override
Construct an array of nElements container objects at the address given by arena
std::vector< ROOT::Internal::RAlignedStorage< 4096 > > Cont4096_t
void Shrink(UInt_t nCurr, UInt_t left, Bool_t force)
std::vector< ROOT::Internal::RAlignedStorage< 512 > > Cont512_t
void * At(UInt_t idx) override
Return the address of the value at index idx
void ReadItems(int nElements, TBuffer &b)
std::vector< ROOT::Internal::RAlignedStorage< 2 > > Cont2_t
void WithCont(void *obj, F &&fn) const
Invoke fn(typed_ptr, elemSize) where typed_ptr is the container pointer cast to the correct AlignedSt...
TClass::ObjectPtr NewObjectArray(Int_t nElements, void *memory) const override
Construct an array of nElements container objects at the address given by arena
void Destructor(void *p, Bool_t dtorOnly=kFALSE) const override
Execute the container destructor.
void ReadBuffer(TBuffer &buff, void *pObj) override
void Streamer(TBuffer &refBuffer) override
Streamer Function.
void DeleteArray(void *p, Bool_t dtorOnly=kFALSE) const override
Execute the container array destructor.
TEmulatedCollectionProxy(const TEmulatedCollectionProxy &copy)
UInt_t Sizeof() const override
Return the sizeof() of the collection object.
void Resize(UInt_t n, Bool_t force_delete) override
Resize the container.
Proxy around an arbitrary container, which implements basic functionality and iteration.
virtual void Streamer(TBuffer &refBuffer)
Streamer Function.
TClass * GetValueClass() const override
Return a pointer to the TClass representing the content.
Value * fKey
Descriptor of the key_type.
Value * fVal
Descriptor of the Value_type.
Defines a common interface to inspect/change the contents of an object that represents a collection.
const Int_t n
Definition legend1.C:16
void PrintWriteStlWithoutProxyMsg(const char *where, const char *clName, const char *BranchName)
constexpr bool IsValidAlignment(std::size_t align) noexcept
Return true if align is a valid C++ alignment value: strictly positive and a power of two.
Definition BitUtils.hxx:36
UInt_t fCase
type of data of Value_type
EDataType fKind
kind of ROOT-fundamental type