Logo ROOT  
Reference Guide
TGenCollectionProxy.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_TGenCollectionProxy
12#define ROOT_TGenCollectionProxy
13
14#include "TBuffer.h"
15
17
19
20#include <atomic>
21#include <string>
22#include <map>
23#include <stdlib.h>
24
25class TObjArray;
27
30{
31
32 // Friend declaration
34
35public:
36
37#ifdef R__HPUX
38 typedef const std::type_info& Info_t;
39#else
40 typedef const std::type_info& Info_t;
41#endif
42
43 enum {
44 // Those 'bits' are used in conjunction with CINT's bit to store the 'type'
45 // info into one int
46 kBIT_ISSTRING = 0x20000000, // We can optimized a value operation when the content are strings
47 kBIT_ISTSTRING = 0x40000000
48 };
49
50 /** @class TGenCollectionProxy::Value TGenCollectionProxy.h TGenCollectionProxy.h
51 *
52 * Small helper to describe the Value_type or the key_type
53 * of an STL container.
54 *
55 * @author M.Frank
56 * @version 1.0
57 * @date 10/10/2004
58 */
59 struct Value {
60 ROOT::NewFunc_t fCtor; ///< Method cache for containee constructor
61 ROOT::DesFunc_t fDtor; ///< Method cache for containee destructor
62 ROOT::DelFunc_t fDelete; ///< Method cache for containee delete
63 UInt_t fCase; ///< type of data of Value_type
64 UInt_t fProperties; ///< Additional properties of the value type (kNeedDelete)
65 TClassRef fType; ///< TClass reference of Value_type in collection
66 EDataType fKind; ///< kind of ROOT-fundamental type
67 size_t fSize; ///< fSize of the contained object
68
69 // Default copy constructor has the correct implementation.
70
71 // Initializing constructor
72 Value(const std::string& info, Bool_t silent);
73 // Delete individual item from STL container
74 void DeleteItem(void* ptr);
75
77 };
78
79 /**@class StreamHelper
80 *
81 * Helper class to facilitate I/O
82 *
83 * @author M.Frank
84 * @version 1.0
85 * @date 10/10/2004
86 */
101 void* p_void;
102 void** pp_void;
103 char* kchar;
105 void* ptr() {
106 return *(&this->p_void);
107 }
108 std::string* str() {
109 return (std::string*)this;
110 }
111 const char* c_str() {
112 return ((std::string*)this)->c_str();
113 }
114 const char* c_pstr() {
115 return (*(std::string**)this)->c_str();
116 }
117 void set(void* p) {
118 *(&this->p_void) = p;
119 }
121 TString s;
122 s.Streamer(b);
123 ((std::string*)this)->assign(s.Data());
124 }
126 *((TString*)this) = "";
127 ((TString*)this)->Streamer(b);
128 return this;
129 }
131 TString s;
132 std::string* str2 = (std::string*)ptr();
133 if (!str2) str2 = new std::string();
134 s.Streamer(b);
135 *str2 = s;
136 set(str2);
137 }
139 const char* c;
140 if (ptr()) {
141 std::string* strptr = (*(std::string**)this);
142 c = (const char*)(strptr->c_str());
143 } else c = "";
144 TString(c).Streamer(b);
145 }
147 void* p = ptr();
148 if ( p ) {
149 if ( v->fDelete ) { // Compiled content: call Destructor
150 (*v->fDelete)(p);
151 }
152 else if ( v->fType ) { // Emulated content: call TClass::Delete
153 v->fType->Destructor(p);
154 }
155 else if ( v->fDtor ) {
156 (*v->fDtor)(p);
157 ::operator delete(p);
158 }
159 else {
160 ::operator delete(p);
161 }
162 }
163 set( b.ReadObjectAny(v->fType) );
164 }
165
167 TString* s = (TString*)ptr();
168 if ( vsn3 ) {
169 if ( !s ) s = new TString();
170 else s->Clear();
171 s->Streamer(b);
172 set(s);
173 return;
174 }
175 if ( s ) delete s;
176 set( b.ReadObjectAny(TString::Class()) );
177 }
179 b.WriteObjectAny(ptr(), TString::Class());
180 }
181 };
182
183 /** @class TGenCollectionProxy::Method TGenCollectionProxy.h TGenCollectionProxy.h
184 *
185 * Small helper to execute (compiler) generated function for the
186 * access to STL or other containers.
187 *
188 * @author M.Frank
189 * @version 1.0
190 * @date 10/10/2004
191 */
192 class Method {
193 public:
194 typedef void* (*Call_t)(void*);
196 Method() : call(0) { }
198 Method(const Method& m) : call(m.call) { }
199 Method &operator=(const Method& m) { call = m.call; return *this; }
200 void* invoke(void* obj) const { return (*call)(obj); }
201 };
202
203 /** @class TGenCollectionProxy::Method TGenCollectionProxy.h TGenCollectionProxy.h
204 *
205 * Small helper to execute (compiler) generated function for the
206 * access to STL or other containers.
207 *
208 * @author M.Frank
209 * @version 1.0
210 * @date 10/10/2004
211 */
212 class Method0 {
213 public:
214 typedef void* (*Call_t)();
216 Method0() : call(0) { }
218 Method0(const Method0& m) : call(m.call) { }
219 Method0 &operator=(const Method0& m) { call = m.call; return *this; }
220 void* invoke() const { return (*call)(); }
221 };
222
223 /** @class TGenCollectionProxy::TStaging
224 *
225 * Small helper to stage the content of an associative
226 * container when reading and before inserting it in the
227 * actual collection.
228 *
229 * @author Ph.Canal
230 * @version 1.0
231 * @date 20/08/2010
232 */
233 class TStaging {
234 void *fTarget; ///< Pointer to the collection we are staging for.
235 void *fContent; ///< Pointer to the content
236 size_t fReserved; ///< Amount of space already reserved.
237 size_t fSize; ///< Number of elements
238 size_t fSizeOf; ///< size of each elements
239
240 TStaging(const TStaging&); ///< Not implemented.
241 TStaging &operator=(const TStaging&); ///< Not implemented.
242
243 public:
244 TStaging(size_t size, size_t size_of) : fTarget(0), fContent(0), fReserved(0), fSize(size), fSizeOf(size_of)
245 {
246 // Usual constructor. Reserves the required number of elements.
249 }
250
252 // Usual destructor
254 }
255
256 void *GetContent() {
257 // Return the location of the array of content.
258 return fContent;
259 }
260 void *GetEnd() {
261 // Return the 'end' of the array of content.
262 return ((char*)fContent) + fSize*fSizeOf;
263 }
264 size_t GetSize() {
265 // Return the number of elements.
266 return fSize;
267 }
268 void *GetTarget() {
269 // Get the address of the collection we are staging for.
270 return fTarget;
271 }
272 void Resize(size_t nelement) {
273 if (fReserved < nelement) {
274 fReserved = nelement;
276 }
277 fSize = nelement;
278 }
279 void SetTarget(void *target) {
280 // Set the collection we are staging for.
281 fTarget = target;
282 }
283 };
284
285protected:
288 typedef std::vector<TStaging*> Staged_t; ///< Collection of pre-allocated staged array for associative containers.
289 typedef std::vector<EnvironBase_t*> Proxies_t;
290 mutable TObjArray *fReadMemberWise; ///< Array of bundle of TStreamerInfoActions to stream out (read)
291 mutable std::map<std::string, TObjArray*> *fConversionReadMemberWise; ///< Array of bundle of TStreamerInfoActions to stream out (read) derived from another class.
293 typedef void (*Sizing_t)(void *obj, size_t size);
294 typedef void* (*Feedfunc_t)(void *from, void *to, size_t size);
295 typedef void* (*Collectfunc_t)(void *from, void *to);
296 typedef void* (*ArrIterfunc_t)(void *from, size_t size);
297
298 std::string fName; ///< Name of the class being proxied.
299 Bool_t fPointers; ///< Flag to indicate if containee has pointers (key or value)
300 Method fClear; ///< Method cache for container accessors: clear container
301 Method fSize; ///< Container accessors: size of container
302 Sizing_t fResize; ///< Container accessors: resize container
303 Method fFirst; ///< Container accessors: generic iteration: first
304 Method fNext; ///< Container accessors: generic iteration: next
305 ArrIterfunc_t fConstruct; ///< Container accessors: block construct
306 Sizing_t fDestruct; ///< Container accessors: block destruct
307 Feedfunc_t fFeed; ///< Container accessors: block feed
308 Collectfunc_t fCollect; ///< Method to collect objects from container
309 Method0 fCreateEnv; ///< Method to allocate an Environment holder.
310 std::atomic<Value*> fValue; ///< Descriptor of the container value type
311 Value* fVal; ///< Descriptor of the Value_type
312 Value* fKey; ///< Descriptor of the key_type
313 EnvironBase_t*fEnv; ///< Address of the currently proxied object
314 int fValOffset; ///< Offset from key to value (in maps)
315 int fValDiff; ///< Offset between two consecutive value_types (memory layout).
316 Proxies_t fProxyList; ///< Stack of recursive proxies
317 Proxies_t fProxyKept; ///< Optimization: Keep proxies once they were created
318 Staged_t fStaged; ///< Optimization: Keep staged array once they were created
319 int fSTL_type; ///< STL container type
320 Info_t fTypeinfo; ///< Type information
321 TClass* fOnFileClass; ///< On file class
322
328
329 // Late initialization of collection proxy
331 // Some hack to avoid const-ness.
332 virtual TGenCollectionProxy* InitializeEx(Bool_t silent);
333 // Call to delete/destruct individual contained item.
334 virtual void DeleteItem(Bool_t force, void* ptr) const;
335 // Allow to check function pointers.
336 void CheckFunctions() const;
337
338private:
339 TGenCollectionProxy(); // not implemented on purpose.
340
341public:
342
343 // Virtual copy constructor.
344 virtual TVirtualCollectionProxy* Generate() const;
345
346 // Copy constructor.
348
349private:
350 // Assignment operator
352
353public:
354 // Initializing constructor
355 TGenCollectionProxy(Info_t typ, size_t iter_size);
357
358 // Standard destructor.
359 virtual ~TGenCollectionProxy();
360
361 // Return a pointer to the TClass representing the container.
362 virtual TClass *GetCollectionClass() const;
363
364 // Return the type of collection see TClassEdit::ESTLType
365 virtual Int_t GetCollectionType() const;
366
367 // Return the offset between two consecutive value_types (memory layout).
368 virtual ULong_t GetIncrement() const;
369
370 // Return the sizeof the collection object.
371 virtual UInt_t Sizeof() const;
372
373 // Push new proxy environment.
374 virtual void PushProxy(void *objstart);
375
376 // Pop old proxy environment.
377 virtual void PopProxy();
378
379 // Return true if the content is of type 'pointer to'.
380 virtual Bool_t HasPointers() const;
381
382 // Return a pointer to the TClass representing the content.
383 virtual TClass *GetValueClass() const;
384
385 // If the content is a simple numerical value, return its type (see TDataType).
386 virtual EDataType GetType() const;
387
388 // Return the address of the value at index 'idx'.
389 virtual void *At(UInt_t idx);
390
391 // Clear the container.
392 virtual void Clear(const char *opt = "");
393
394 // Resize the container.
395 virtual void Resize(UInt_t n, Bool_t force_delete);
396
397 // Return the current size of the container.
398 virtual UInt_t Size() const;
399
400 // Block allocation of containees.
401 virtual void* Allocate(UInt_t n, Bool_t forceDelete);
402
403 // Insert data into the container where data is a C-style array of the actual type contained in the collection
404 // of the given size. For associative container (map, etc.), the data type is the pair<key,value>.
405 virtual void Insert(const void *data, void *container, size_t size);
406
407 // Block commit of containees.
408 virtual void Commit(void* env);
409
410 // Streamer function.
411 virtual void Streamer(TBuffer &refBuffer);
412
413 // Streamer I/O overload.
414 virtual void Streamer(TBuffer &refBuffer, void *pObject, int siz);
415
416 // TClassStreamer I/O overload.
417 virtual void operator()(TBuffer &refBuffer, void *pObject);
418
419 // Routine to read the content of the buffer into 'obj'.
420 virtual void ReadBuffer(TBuffer &b, void *obj);
421 virtual void ReadBuffer(TBuffer &b, void *obj, const TClass *onfileClass);
422
423 virtual void SetOnFileClass( TClass* cl ) { fOnFileClass = cl; }
424 virtual TClass* GetOnFileClass() const { return fOnFileClass; }
425
426 // MemberWise actions
430
431 // Set of functions to iterate easily throught the collection
432
434 // typedef void (*CreateIterators_t)(void *collection, void **begin_arena, void **end_arena);
435 // begin_arena and end_arena should contain the location of a memory arena of size fgIteratorSize.
436 // If the collection iterator are of that size or less, the iterators will be constructed in place in those location (new with placement)
437 // Otherwise the iterators will be allocated via a regular new and their address returned by modifying the value of begin_arena and end_arena.
438
440 // typedef void* (*CopyIterator_t)(void **dest, const void *source);
441 // Copy the iterator source, into dest. dest should contain the location of a memory arena of size fgIteratorSize.
442 // If the collection iterator is of that size or less, the iterator will be constructed in place in this location (new with placement)
443 // Otherwise the iterator will be allocated via a regular new.
444 // The actual address of the iterator is returned in both case.
445
446 virtual Next_t GetFunctionNext(Bool_t read = kTRUE);
447 // typedef void* (*Next_t)(void *iter, const void *end);
448 // iter and end should be pointers to respectively an iterator to be incremented and the result of collection.end()
449 // If the iterator has not reached the end of the collection, 'Next' increment the iterator 'iter' and return 0 if
450 // the iterator reached the end.
451 // If the end was not reached, 'Next' returns the address of the content pointed to by the iterator before the
452 // incrementation ; if the collection contains pointers, 'Next' will return the value of the pointer.
453
456 // typedef void (*DeleteIterator_t)(void *iter);
457 // typedef void (*DeleteTwoIterators_t)(void *begin, void *end);
458 // If the size of the iterator is greater than fgIteratorArenaSize, call delete on the addresses,
459 // Otherwise just call the iterator's destructor.
460
461};
462
463template <typename T>
466 : TGenCollectionProxy(typeid(T::Cont_t),sizeof(T::Iter_t))
467 {
468 // Constructor.
469 fValDiff = sizeof(T::Value_t);
470 fValOffset = T::value_offset();
471 fSize.call = T::size;
472 fResize = T::resize;
473 fNext.call = T::next;
474 fFirst.call = T::first;
475 fClear.call = T::clear;
476 fConstruct = T::construct;
477 fDestruct = T::destruct;
478 fFeed = T::feed;
480 }
482};
483
484#endif
485
void Class()
Definition: Class.C:29
#define b(i)
Definition: RSha256.hxx:100
#define c(i)
Definition: RSha256.hxx:101
unsigned short UShort_t
Definition: RtypesCore.h:36
int Int_t
Definition: RtypesCore.h:41
unsigned char UChar_t
Definition: RtypesCore.h:34
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
short Short_t
Definition: RtypesCore.h:35
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
unsigned long long ULong64_t
Definition: RtypesCore.h:70
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
EDataType
Definition: TDataType.h:28
typedef void((*Func_t)())
#define realloc
Definition: civetweb.c:1538
#define free
Definition: civetweb.c:1539
#define malloc
Definition: civetweb.c:1536
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
TClassRef is used to implement a permanent reference to a TClass object.
Definition: TClassRef.h:29
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
TCollectionProxyFactory Interface to collection proxy and streamer generator.
Method0 & operator=(const Method0 &m)
Small helper to execute (compiler) generated function for the access to STL or other containers.
Method & operator=(const Method &m)
void * invoke(void *obj) const
Small helper to stage the content of an associative container when reading and before inserting it in...
size_t fSizeOf
size of each elements
TStaging & operator=(const TStaging &)
Not implemented.
size_t fSize
Number of elements.
TStaging(const TStaging &)
Not implemented.
void * fContent
Pointer to the content.
size_t fReserved
Amount of space already reserved.
void * fTarget
Pointer to the collection we are staging for.
TStaging(size_t size, size_t size_of)
Proxy around an arbitrary container, which implements basic functionality and iteration.
Method fFirst
Container accessors: generic iteration: first.
std::atomic< Value * > fValue
Descriptor of the container value type.
std::vector< EnvironBase_t * > Proxies_t
virtual ~TGenCollectionProxy()
Standard destructor.
std::vector< TStaging * > Staged_t
Collection of pre-allocated staged array for associative containers.
Bool_t fPointers
Flag to indicate if containee has pointers (key or value)
Method fNext
Container accessors: generic iteration: next.
virtual void Streamer(TBuffer &refBuffer)
Streamer Function.
virtual TStreamerInfoActions::TActionSequence * GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version)
Return the set of action necessary to stream in this collection member-wise coming from the old value...
TStreamerInfoActions::TActionSequence * fWriteMemberWise
void *(* Feedfunc_t)(void *from, void *to, size_t size)
virtual EDataType GetType() const
If the content is a simple numerical value, return its type (see TDataType)
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)
See typedef void (*DeleteTwoIterators_t)(void *begin, void *end); If the sizeof iterator is greater t...
ROOT::Detail::TCollectionProxyInfo::Environ< char[64]> Env_t
virtual UInt_t Size() const
Return the current size of the container.
virtual UInt_t Sizeof() const
Return the sizeof the collection object.
Info_t fTypeinfo
Type information.
int fValOffset
Offset from key to value (in maps)
EnvironBase_t * fEnv
Address of the currently proxied object.
virtual void PopProxy()
Remove the last object.
virtual TClass * GetCollectionClass() const
Return a pointer to the TClass representing the container.
DeleteIterator_t fFunctionDeleteIterator
Collectfunc_t fCollect
Method to collect objects from container.
virtual Bool_t HasPointers() const
Return true if the content is of type 'pointer to'.
virtual TClass * GetValueClass() const
Return a pointer to the TClass representing the content.
TGenCollectionProxy * Initialize(Bool_t silent) const
Proxy initializer.
virtual ULong_t GetIncrement() const
Return the offset between two consecutive value_types (memory layout).
virtual TGenCollectionProxy * InitializeEx(Bool_t silent)
Proxy initializer.
void *(* ArrIterfunc_t)(void *from, size_t size)
TGenCollectionProxy & operator=(const TGenCollectionProxy &)
virtual void PushProxy(void *objstart)
Add an object.
std::string fName
Name of the class being proxied.
int fSTL_type
STL container type.
CopyIterator_t fFunctionCopyIterator
Value * fKey
Descriptor of the key_type.
virtual TClass * GetOnFileClass() const
virtual void Insert(const void *data, void *container, size_t size)
Insert data into the container where data is a C-style array of the actual type contained in the coll...
virtual void Resize(UInt_t n, Bool_t force_delete)
Resize the container.
void(* Sizing_t)(void *obj, size_t size)
virtual TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Int_t version)
Return the set of action necessary to stream in this collection member-wise coming from the old value...
Proxies_t fProxyList
Stack of recursive proxies.
virtual void * Allocate(UInt_t n, Bool_t forceDelete)
Allocate the needed space.
Sizing_t fDestruct
Container accessors: block destruct.
Method0 fCreateEnv
Method to allocate an Environment holder.
virtual void Commit(void *env)
Commit the change.
Value * fVal
Descriptor of the Value_type.
virtual DeleteIterator_t GetFunctionDeleteIterator(Bool_t read=kTRUE)
See typedef void (*DeleteIterator_t)(void *iter); If the sizeof iterator is greater than fgIteratorAr...
virtual void operator()(TBuffer &refBuffer, void *pObject)
TClassStreamer IO overload.
virtual TStreamerInfoActions::TActionSequence * GetWriteMemberWiseActions()
Return the set of action necessary to stream out this collection member-wise.
TClass * fOnFileClass
On file class.
Sizing_t fResize
Container accessors: resize container.
ArrIterfunc_t fConstruct
Container accessors: block construct.
std::map< std::string, TObjArray * > * fConversionReadMemberWise
Array of bundle of TStreamerInfoActions to stream out (read) derived from another class.
void CheckFunctions() const
Check existence of function pointers.
DeleteTwoIterators_t fFunctionDeleteTwoIterators
virtual Int_t GetCollectionType() const
Return the type of collection see TClassEdit::ESTLType.
virtual void SetOnFileClass(TClass *cl)
virtual void * At(UInt_t idx)
Return the address of the value at index 'idx'.
CreateIterators_t fFunctionCreateIterators
virtual void Clear(const char *opt="")
Clear the emulated collection.
TObjArray * fReadMemberWise
Array of bundle of TStreamerInfoActions to stream out (read)
ROOT::Detail::TCollectionProxyInfo::EnvironBase EnvironBase_t
virtual void DeleteItem(Bool_t force, void *ptr) const
Call to delete/destruct individual item.
virtual TVirtualCollectionProxy * Generate() const
Virtual copy constructor.
Staged_t fStaged
Optimization: Keep staged array once they were created.
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)
See typedef void* (*Next_t)(void *iter, void *end); iter and end should be pointer to respectively an...
Method fSize
Container accessors: size of container.
virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read=kTRUE)
See typedef void (*CopyIterator_t)(void *&dest, const void *source); Copy the iterator source,...
Method fClear
Method cache for container accessors: clear container.
Feedfunc_t fFeed
Container accessors: block feed.
void *(* Collectfunc_t)(void *from, void *to)
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)
See typedef void (*CreateIterators_t)(void *collection, void *&begin_arena, void *&end_arena); begin_...
int fValDiff
Offset between two consecutive value_types (memory layout).
virtual void ReadBuffer(TBuffer &b, void *obj)
Proxies_t fProxyKept
Optimization: Keep proxies once they were created.
const std::type_info & Info_t
An array of TObjects.
Definition: TObjArray.h:37
Basic string class.
Definition: TString.h:131
void(* CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)
void *(* CopyIterator_t)(void *dest, const void *source)
void *(* Next_t)(void *iter, const void *end)
void(* DeleteTwoIterators_t)(void *begin, void *end)
void(* DeleteIterator_t)(void *iter)
const Int_t n
Definition: legend1.C:16
double T(double x)
Definition: ChebyshevPol.h:34
void(* DesFunc_t)(void *)
Definition: Rtypes.h:114
void(* DelFunc_t)(void *)
Definition: Rtypes.h:112
void *(* NewFunc_t)(void *)
Definition: Rtypes.h:110
static constexpr double s
Small helper to save proxy environment in the event of recursive calls.
Small helper to describe the Value_type or the key_type of an STL container.
UInt_t fCase
type of data of Value_type
TClassRef fType
TClass reference of Value_type in collection.
UInt_t fProperties
Additional properties of the value type (kNeedDelete)
Value(const std::string &info, Bool_t silent)
Constructor.
size_t fSize
fSize of the contained object
ROOT::DelFunc_t fDelete
Method cache for containee delete.
ROOT::DesFunc_t fDtor
Method cache for containee destructor.
ROOT::NewFunc_t fCtor
Method cache for containee constructor.
EDataType fKind
kind of ROOT-fundamental type
Bool_t IsValid()
Return true if the Value has been properly initialized.
auto * m
Definition: textangle.C:8
Helper class to facilitate I/O.
void read_tstring_pointer(Bool_t vsn3, TBuffer &b)
void read_any_object(Value *v, TBuffer &b)