// @(#)root/cont:$Name: $:$Id: TGenCollectionProxy.h,v 1.9 2005/08/30 02:45:05 pcanal Exp $
// Author: Markus Frank 28/10/04
/*************************************************************************
* Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TGenCollectionProxy
#define ROOT_TGenCollectionProxy
//////////////////////////////////////////////////////////////////////////
// //
// TGenCollectionProxy
//
// Proxy around an arbitrary container, which implements basic
// functionality and iteration.
//
// In particular this is used to implement splitting and abstract
// element access of any container. Access to compiled code is necessary
// to implement the abstract iteration sequence and functionality like
// size(), clear(), resize(). resize() may be a void operation.
//
//////////////////////////////////////////////////////////////////////////
#include "TVirtualCollectionProxy.h"
#include "TCollectionProxy.h"
#include <typeinfo>
#include <string>
class TGenCollectionProxy
: public TVirtualCollectionProxy,
public TCollectionProxy
{
/// Friend declaration
friend class TCollectionProxy;
public:
enum {
// Those 'bits' are used in conjunction with CINT's bit to store the 'type'
// info into one int
R__BIT_ISSTRING = 0x20000000, // We can optimized a value operation when the content are strings
R__BIT_ISTSTRING = 0x40000000,
kBOOL_t = 21
};
/** @class TGenCollectionProxy::Value TGenCollectionProxy.h TGenCollectionProxy.h
*
* Small helper to describe the Value_type or the key_type
* of an STL container.
*
* @author M.Frank
* @version 1.0
* @date 10/10/2004
*/
struct Value {
ROOT::NewFunc_t fCtor; // Method cache for containee constructor
ROOT::DesFunc_t fDtor; // Method cache for containee destructor
ROOT::DelFunc_t fDelete; // Method cache for containee delete
unsigned int fCase; // type of data of Value_type
TClassRef fType; // TClass reference of Value_type in collection
EDataType fKind; // kind of ROOT-fundamental type
size_t fSize; // fSize of the contained object
/// Copy constructor
Value(const Value& inside);
/// Initializing constructor
Value(const std::string& info);
/// Delete individual item from STL container
void DeleteItem(void* ptr);
};
/**@class StreamHelper
*
* Helper class to facilitate I/O
*
* @author M.Frank
* @version 1.0
* @date 10/10/2004
*/
union StreamHelper {
Bool_t boolean;
Char_t s_char;
Short_t s_short;
Int_t s_int;
Long_t s_long;
Long64_t s_longlong;
Float_t flt;
Double_t dbl;
UChar_t u_char;
UShort_t u_short;
UInt_t u_int;
ULong_t u_long;
ULong64_t u_longlong;
void* p_void;
void** pp_void;
char* kchar;
TString* tstr;
void* ptr() {
return *(&this->p_void);
}
std::string* str() {
return (std::string*)this;
}
const char* c_str() {
return ((std::string*)this)->c_str();
}
const char* c_pstr() {
return (*(std::string**)this)->c_str();
}
void set(void* p) {
*(&this->p_void) = p;
}
void read_std_string(TBuffer& b) {
TString s;
s.Streamer(b);
((std::string*)this)->assign(s.Data());
}
void* read_tstring(TBuffer& b) {
*((TString*)this) = "";
((TString*)this)->Streamer(b);
return this;
}
void read_std_string_pointer(TBuffer& b) {
TString s;
std::string* str = (std::string*)ptr();
if (!str) str = new std::string();
s.Streamer(b);
*str = s;
set(str);
}
void write_std_string_pointer(TBuffer& b) {
const char* c;
if (ptr()) {
std::string* strptr = (*(std::string**)this);
c = (const char*)(strptr->c_str());
} else c = "";
TString(c).Streamer(b);
}
void read_any_object(Value* v, TBuffer& b) {
void* p = ptr();
if ( p ) {
if ( v->fDelete ) { // Compiled content: call Destructor
(*v->fDelete)(p);
}
else if ( v->fType ) { // Emulated content: call TClass::Delete
v->fType->Destructor(p);
}
else if ( v->fDtor ) {
(*v->fDtor)(p);
::operator delete(p);
}
else {
::operator delete(p);
}
}
set( b.ReadObjectAny(v->fType) );
}
void read_tstring_pointer(Bool_t vsn3, TBuffer& b) {
TString* s = (TString*)ptr();
if ( vsn3 ) {
if ( !s ) s = new TString();
s->Replace(0, s->Length(), 0, 0);
s->Streamer(b);
set(s);
return;
}
if ( s ) delete s;
set( b.ReadObjectAny(TString::Class()) );
}
void write_tstring_pointer(TBuffer& b) {
b.WriteObjectAny(ptr(), TString::Class());
}
};
/** @class TGenCollectionProxy::Method TGenCollectionProxy.h TGenCollectionProxy.h
*
* Small helper to execute (compiler) generated function for the
* access to STL or other containers.
*
* @author M.Frank
* @version 1.0
* @date 10/10/2004
*/
struct Method {
typedef void* (*Call_t)(void*);
Call_t call;
Method() : call(0) { }
Method(Call_t c) : call(c) { }
Method(const Method& m) : call(m.call) { }
void* invoke(void* obj) const { return (*call)(obj); }
};
protected:
typedef ROOT::Environ<char[64]> Env_t;
typedef std::vector<Env_t*> Proxies_t;
std::string fName; // Name of the class being proxied.
Bool_t fPointers; // Flag to indicate if containee has pointers (key or value)
Method fClear; // Method cache for container accessors: clear container
Method fSize; // Container accessors: size of container
Method fResize; // Container accessors: resize container
Method fFirst; // Container accessors: generic iteration: first
Method fNext; // Container accessors: generic iteration: next
Method fConstruct; // Container accessors: block construct
Method fDestruct; // Container accessors: block destruct
Method fFeed; // Container accessors: block feed
Method fCollect; // Method to collect objects from container
Value* fValue; // Descriptor of the container value type
Value* fVal; // Descriptor of the Value_type
Value* fKey; // Descriptor of the key_type
Env_t* fEnv; // Address of the currently proxied object
int fValOffset; // Offset from key to value (in maps)
int fValDiff; // Offset between two consecutive value_types (memory layout).
Proxies_t fProxyList; // Stack of recursive proxies
Proxies_t fProxyKept; // Optimization: Keep proxies once they were created
int fSTL_type; // STL container type
Info_t fTypeinfo; // Type information
/// Late initialization of collection proxy
TGenCollectionProxy* Initialize() const;
/// Some hack to avoid const-ness
virtual TGenCollectionProxy* InitializeEx();
/// Call to delete/destruct individual contained item
virtual void DeleteItem(Bool_t force, void* ptr) const;
/// Allow to check function pointers
void CheckFunctions() const;
public:
/// Virtual copy constructor
virtual TVirtualCollectionProxy* Generate() const;
/// Copy constructor
TGenCollectionProxy(const TGenCollectionProxy& copy);
/// Initializing constructor
TGenCollectionProxy(Info_t typ, size_t iter_size);
/// Standard destructor
virtual ~TGenCollectionProxy();
/// Return a pointer to the TClass representing the container
virtual TClass *GetCollectionClass();
/// Return the sizeof the collection object.
virtual UInt_t Sizeof() const;
/// Push new proxy environment
virtual void PushProxy(void *objstart);
/// Pop old proxy environment
virtual void PopProxy();
/// Return true if the content is of type 'pointer to'
virtual Bool_t HasPointers() const;
/// Return a pointer to the TClass representing the content.
virtual TClass *GetValueClass();
/// Set pointer to the TClass representing the content.
virtual void SetValueClass(TClass *newcl);
/// If the content is a simple numerical value, return its type (see TDataType)
virtual EDataType GetType();
/// Return the address of the value at index 'idx'
virtual void *At(UInt_t idx);
/// Clear the container
virtual void Clear(const char *opt = "");
/// Resize the container
virtual void Resize(UInt_t n, Bool_t force_delete);
/// Return the current size of the container
virtual UInt_t Size() const;
/// Block allocation of containees
virtual void* Allocate(UInt_t n, Bool_t forceDelete);
/// Block commit of containees
virtual void Commit(void* env);
/// Streamer function
virtual void Streamer(TBuffer &refBuffer);
/// Streamer I/O overload
virtual void Streamer(TBuffer &refBuffer, void *pObject, int siz);
/// TClassStreamer I/O overload
virtual void operator()(TBuffer &refBuffer, void *pObject);
};
template <typename T>
struct AnyCollectionProxy : public TGenCollectionProxy {
AnyCollectionProxy()
: TGenCollectionProxy(typeid(T::Cont_t),sizeof(T::Iter_t))
{
fValDiff = sizeof(T::Value_t);
fValOffset = T::value_offset();
fSize.call = T::size;
fResize.call = T::resize;
fNext.call = T::next;
fFirst.call = T::first;
fClear.call = T::clear;
fConstruct.call = T::construct;
fDestruct.call = T::destruct;
fFeed.call = T::feed;
CheckFunctions();
}
virtual ~AnyCollectionProxy() { }
};
#endif
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.