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"
16
17#include <type_traits>
18#include <vector>
19
21
22 // Friend declaration
23 friend class TCollectionProxy;
24
25public:
26 /// Storage type whose alignment matches \a Align bytes.
27 /// Used to instantiate std::vector specializations with guaranteed buffer alignment.
28 template <std::size_t Align>
30 char data[Align] = {};
31 };
32
33 // Convenience vector aliases for each supported alignment.
34 using Cont1_t = std::vector<AlignedStorage< 1>>;
35 using Cont2_t = std::vector<AlignedStorage< 2>>;
36 using Cont4_t = std::vector<AlignedStorage< 4>>;
37 using Cont8_t = std::vector<AlignedStorage< 8>>;
38 using Cont16_t = std::vector<AlignedStorage< 16>>;
39 using Cont32_t = std::vector<AlignedStorage< 32>>;
40 using Cont64_t = std::vector<AlignedStorage< 64>>;
41 using Cont128_t = std::vector<AlignedStorage< 128>>;
42 using Cont256_t = std::vector<AlignedStorage< 256>>;
43 using Cont512_t = std::vector<AlignedStorage< 512>>;
44 using Cont1024_t = std::vector<AlignedStorage<1024>>;
45 using Cont2048_t = std::vector<AlignedStorage<2048>>;
46 using Cont4096_t = std::vector<AlignedStorage<4096>>;
47
48 // Canonical container type (used for sizeof/typeid; actual alignment is
49 // selected at runtime via the alignment switch in each method).
50 using Cont_t = std::vector<char>;
51 using PCont_t = Cont_t *;
52
53 /// Invoke \a fn(typed_ptr, elemSize) where typed_ptr is the container
54 /// pointer cast to the correct AlignedStorage<N>* for the value class
55 /// alignment. \a fn receives the element size (N) as a second argument
56 /// so it can convert byte counts to element counts.
57 template <typename F>
58 void WithCont(void *obj, F &&fn) const
59 {
60 auto *vcl = GetValueClass();
61 std::size_t align = alignof(std::max_align_t);
62 if (!fKey && (fVal->fCase & kIsPointer)) {
63 // If the collection contains pointers, we need to use the alignment of a pointer, not of the value class.
64 align = alignof(void*);
65 } else if (vcl) {
66 assert(ROOT::Internal::IsValidAlignment(vcl->GetClassAlignment()));
67 align = vcl->GetClassAlignment();
68 } else {
69 switch( int(fVal->fKind) ) {
70 case kChar_t:
71 case kUChar_t: align = alignof(char); break;
72 case kShort_t:
73 case kUShort_t: align = alignof(short); break;
74 case kInt_t:
75 case kUInt_t: align = alignof(int); break;
76 case kLong_t:
77 case kULong_t: align = alignof(long); break;
78 case kLong64_t:
79 case kULong64_t:align = alignof(long long); break;
80 case kFloat16_t:
81 case kFloat_t: align = alignof(float); break;
82 case kDouble32_t:
83 case kDouble_t: align = alignof(double); break;
84 default:
85 Fatal("TEmulatedCollectionProxy::WithCont", "Unsupported value type %d for value class %s", fVal->fKind,
86 vcl ? vcl->GetName() : "<unknown>");
87 }
88 }
89 switch (align) {
90 // When adding new cases here, also update the static_assert in TClingUtils.cxx
91 // to explicitly allow the new alignment and to update the error message accordingly.
92 case 4096: fn(reinterpret_cast<Cont4096_t*>(obj), std::size_t(4096)); break;
93 case 2048: fn(reinterpret_cast<Cont2048_t*>(obj), std::size_t(2048)); break;
94 case 1024: fn(reinterpret_cast<Cont1024_t*>(obj), std::size_t(1024)); break;
95 case 512: fn(reinterpret_cast<Cont512_t *>(obj), std::size_t( 512)); break;
96 case 256: fn(reinterpret_cast<Cont256_t *>(obj), std::size_t( 256)); break;
97 case 128: fn(reinterpret_cast<Cont128_t *>(obj), std::size_t( 128)); break;
98 case 64: fn(reinterpret_cast<Cont64_t *>(obj), std::size_t( 64)); break;
99 case 32: fn(reinterpret_cast<Cont32_t *>(obj), std::size_t( 32)); break;
100 case 16: fn(reinterpret_cast<Cont16_t *>(obj), std::size_t( 16)); break;
101 case 8: fn(reinterpret_cast<Cont8_t *>(obj), std::size_t( 8)); break;
102 case 4: fn(reinterpret_cast<Cont4_t *>(obj), std::size_t( 4)); break;
103 case 2: fn(reinterpret_cast<Cont2_t *>(obj), std::size_t( 2)); break;
104 case 1: fn(reinterpret_cast<Cont1_t *>(obj), std::size_t( 1)); break;
105 default:
106 Fatal("TEmulatedCollectionProxy::WithCont", "Unsupported alignment %zu for value class %s",
107 align, vcl ? vcl->GetName() : "<unknown>");
108 }
109 }
110protected:
111
112 // Some hack to avoid const-ness
113 TGenCollectionProxy* InitializeEx(Bool_t silent) override;
114
115 // Object input streamer
116 void ReadItems(int nElements, TBuffer &b);
117
118 // Object output streamer
119 void WriteItems(int nElements, TBuffer &b);
120
121 // Shrink the container
122 void Shrink(UInt_t nCurr, UInt_t left, Bool_t force);
123
124 // Expand the container
125 void Expand(UInt_t nCurr, UInt_t left);
126
127private:
129
130public:
131 // Virtual copy constructor
132 TVirtualCollectionProxy* Generate() const override;
133
134 // Copy constructor
136
137 // Initializing constructor
139
140 // Standard destructor
141 ~TEmulatedCollectionProxy() override;
142
143 // Virtual constructor
144 void *New() const override
145 {
146 void *mem = ::operator new(sizeof(Cont_t));
147 WithCont(mem, [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
148 return mem;
149 }
150
151 // Virtual in-place constructor
152 void *New(void *memory) const override
153 {
154 WithCont(memory, [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
155 return memory;
156 }
157
158 // Virtual constructor
159 TClass::ObjectPtr NewObject() const override { return {New(), nullptr}; }
160
161 // Virtual in-place constructor
162 TClass::ObjectPtr NewObject(void *memory) const override { return {New(memory), nullptr}; }
163
164 // Virtual array constructor
165 void *NewArray(Int_t nElements) const override
166 {
167 void *arr = ::operator new(nElements * sizeof(Cont_t));
168 for (Int_t i = 0; i < nElements; ++i)
169 WithCont(static_cast<char *>(arr) + i * sizeof(Cont_t),
170 [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
171 return arr;
172 }
173
174 // Virtual in-place array constructor
175 void *NewArray(Int_t nElements, void *memory) const override
176 {
177 for (Int_t i = 0; i < nElements; ++i)
178 WithCont(static_cast<char *>(memory) + i * sizeof(Cont_t),
179 [](auto *c, std::size_t) { new (c) std::decay_t<decltype(*c)>(); });
180 return memory;
181 }
182
183 // Virtual array constructor
184 TClass::ObjectPtr NewObjectArray(Int_t nElements) const override { return {NewArray(nElements), nullptr}; }
185
186 // Virtual in-place array constructor
188 {
189 return {NewArray(nElements, memory), nullptr};
190 }
191
192 // Virtual destructor
193 void Destructor(void* p, Bool_t dtorOnly = kFALSE) const override;
194
195 // Virtual array destructor
196 void DeleteArray(void* p, Bool_t dtorOnly = kFALSE) const override;
197
198 // TVirtualCollectionProxy overload: Return the sizeof the collection object.
199 UInt_t Sizeof() const override { return sizeof(Cont_t); }
200
201 // Return the address of the value at index 'idx'
202 void *At(UInt_t idx) override;
203
204 // Clear the container
205 void Clear(const char *opt = "") override;
206
207 // Resize the container
208 void Resize(UInt_t n, Bool_t force_delete) override;
209
210 // Return the current size of the container
211 UInt_t Size() const override;
212
213 // Block allocation of containees
214 void* Allocate(UInt_t n, Bool_t forceDelete) override;
215
216 // Block commit of containees
217 void Commit(void* env) override;
218
219 // Insert data into the container where data is a C-style array of the actual type contained in the collection
220 // of the given size. For associative container (map, etc.), the data type is the pair<key,value>.
221 void Insert(const void *data, void *container, size_t size) override;
222
223 // Read portion of the streamer
224 void ReadBuffer(TBuffer &buff, void *pObj) override;
225 void ReadBuffer(TBuffer &buff, void *pObj, const TClass *onfile) override;
226
227 // Streamer for I/O handling
228 void Streamer(TBuffer &refBuffer) override;
229
230 // Streamer I/O overload
231 void Streamer(TBuffer &buff, void *pObj, int siz) override
232 {
234 }
235
236 // Check validity of the proxy itself
237 Bool_t IsValid() const;
238};
239
240
242inline void PrintWriteStlWithoutProxyMsg(const char *where, const char *clName, const char *BranchName)
243{
244 const char *writeStlWithoutProxyMsg =
245 "The class requested (%s) for the branch \"%s\" "
246 "is an instance of an stl collection and does not have a compiled CollectionProxy. "
247 "Please generate the dictionary for this collection (%s) to avoid writing corrupted data.";
248 // This error message is repeated several times in the code. We write it once.
250}
251
252inline bool HasEmulatedProxy(TClass *cl){
253 return cl && cl->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy *>(cl->GetCollectionProxy());
254}
255} // namespace ROOT::Internal::TEmulatedProxyHelpers
256
257
258#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
void ReadBuffer(char *&buffer) override
void Streamer(TBuffer &) override
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 &)
std::vector< AlignedStorage< 512 > > Cont512_t
std::vector< AlignedStorage< 2048 > > Cont2048_t
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< AlignedStorage< 4096 > > Cont4096_t
std::vector< AlignedStorage< 8 > > Cont8_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< AlignedStorage< 256 > > Cont256_t
std::vector< AlignedStorage< 1 > > Cont1_t
std::vector< AlignedStorage< 1024 > > Cont1024_t
TClass::ObjectPtr NewObject() const override
Construct a new container object and return its address.
std::vector< AlignedStorage< 64 > > Cont64_t
std::vector< AlignedStorage< 128 > > Cont128_t
std::vector< AlignedStorage< 2 > > Cont2_t
void * New() const override
Construct a new container object and return its address.
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
std::vector< AlignedStorage< 16 > > Cont16_t
void Streamer(TBuffer &buff, void *pObj, int siz) override
Streamer I/O overload.
std::vector< AlignedStorage< 4 > > Cont4_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< AlignedStorage< 32 > > Cont32_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
UInt_t Sizeof() const override
Return the sizeof() of the collection object.
Proxy around an arbitrary container, which implements basic functionality and iteration.
virtual void Streamer(TBuffer &refBuffer)
Streamer Function.
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.
Storage type whose alignment matches Align bytes.