Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/root/TGenCollectionProxy.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // @(#)root/io:$Id$
0002 // Author: Markus Frank  28/10/04
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
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 #ifndef ROOT_TGenCollectionProxy
0012 #define ROOT_TGenCollectionProxy
0013 
0014 #include "TBuffer.h"
0015 
0016 #include "TVirtualCollectionProxy.h"
0017 
0018 #include "TCollectionProxyInfo.h"
0019 
0020 #include <atomic>
0021 #include <string>
0022 #include <map>
0023 #include <cstdlib>
0024 #include <vector>
0025 
0026 class TObjArray;
0027 class TCollectionProxyFactory;
0028 
0029 class TGenCollectionProxy
0030    : public TVirtualCollectionProxy
0031 {
0032 
0033    // Friend declaration
0034    friend class TCollectionProxyFactory;
0035 
0036 public:
0037 
0038 #ifdef R__HPUX
0039    typedef const std::type_info&      Info_t;
0040 #else
0041    typedef const std::type_info& Info_t;
0042 #endif
0043 
0044    enum {
0045       // Those 'bits' are used in conjunction with CINT's bit to store the 'type'
0046       // info into one int
0047       kBIT_ISSTRING   = 0x20000000,  // We can optimized a value operation when the content are strings
0048       kBIT_ISTSTRING  = 0x40000000
0049    };
0050 
0051    /** @class TGenCollectionProxy::Value TGenCollectionProxy.h TGenCollectionProxy.h
0052     *
0053     * Small helper to describe the Value_type or the key_type
0054     * of an STL container.
0055     *
0056     * @author  M.Frank
0057     * @version 1.0
0058     * @date    10/10/2004
0059     */
0060    struct Value  {
0061       ROOT::NewFunc_t fCtor;       ///< Method cache for containee constructor
0062       ROOT::DesFunc_t fDtor;       ///< Method cache for containee destructor
0063       ROOT::DelFunc_t fDelete;     ///< Method cache for containee delete
0064       UInt_t          fCase;       ///< type of data of Value_type
0065       UInt_t          fProperties; ///< Additional properties of the value type (kNeedDelete)
0066       TClassRef       fType;       ///< TClass reference of Value_type in collection
0067       EDataType       fKind;       ///< kind of ROOT-fundamental type
0068       size_t          fSize;       ///< fSize of the contained object
0069 
0070       // Default copy constructor has the correct implementation.
0071 
0072       // Initializing constructor
0073       Value(const std::string& info, Bool_t silent, size_t hint_pair_offset = 0, size_t hint_pair_size = 0);
0074       // Delete individual item from STL container
0075       void DeleteItem(void* ptr);
0076 
0077       Bool_t IsValid();
0078    };
0079 
0080    /**@class StreamHelper
0081     *
0082     * Helper class to facilitate I/O
0083     *
0084     * @author  M.Frank
0085     * @version 1.0
0086     * @date    10/10/2004
0087     */
0088    union StreamHelper  {
0089       Bool_t       boolean;
0090       Char_t       s_char;
0091       Short_t      s_short;
0092       Int_t        s_int;
0093       Long_t       s_long;
0094       Long64_t     s_longlong;
0095       Float_t      flt;
0096       Double_t     dbl;
0097       UChar_t      u_char;
0098       UShort_t     u_short;
0099       UInt_t       u_int;
0100       ULong_t      u_long;
0101       ULong64_t    u_longlong;
0102       void*        p_void;
0103       void**       pp_void;
0104       char*        kchar;
0105       TString*     tstr;
0106       void* ptr()  {
0107          return *(&this->p_void);
0108       }
0109       std::string* str()  {
0110          return (std::string*)this;
0111       }
0112       const char* c_str()  {
0113          return ((std::string*)this)->c_str();
0114       }
0115       const char* c_pstr()  {
0116          return (*(std::string**)this)->c_str();
0117       }
0118       void set(void* p)  {
0119          *(&this->p_void) = p;
0120       }
0121       void read_std_string(TBuffer& b) {
0122          TString s;
0123          s.Streamer(b);
0124          ((std::string*)this)->assign(s.Data());
0125       }
0126       void* read_tstring(TBuffer& b)  {
0127          *((TString*)this) = "";
0128          ((TString*)this)->Streamer(b);
0129          return this;
0130       }
0131       void read_std_string_pointer(TBuffer& b) {
0132          TString s;
0133          std::string* str2 = (std::string*)ptr();
0134          if (!str2) str2 = new std::string();
0135          s.Streamer(b);
0136          *str2 = s;
0137          set(str2);
0138       }
0139       void write_std_string_pointer(TBuffer& b)  {
0140          const char* c;
0141          if (ptr()) {
0142             std::string* strptr = (*(std::string**)this);
0143             c = (const char*)(strptr->c_str());
0144          } else c = "";
0145          TString(c).Streamer(b);
0146       }
0147       void read_any_object(Value* v, TBuffer& b)  {
0148          void* p = ptr();
0149          if ( p )  {
0150             if ( v->fDelete )  {    // Compiled content: call Destructor
0151                (*v->fDelete)(p);
0152             }
0153             else if ( v->fType )  { // Emulated content: call TClass::Delete
0154                v->fType->Destructor(p);
0155             }
0156             else if ( v->fDtor )  {
0157                (*v->fDtor)(p);
0158                ::operator delete(p);
0159             }
0160             else  {
0161                ::operator delete(p);
0162             }
0163          }
0164          set( b.ReadObjectAny(v->fType) );
0165       }
0166 
0167       void read_tstring_pointer(Bool_t vsn3, TBuffer& b)  {
0168          TString* s = (TString*)ptr();
0169          if ( vsn3 )  {
0170             if ( !s ) s = new TString();
0171             else s->Clear();
0172             s->Streamer(b);
0173             set(s);
0174             return;
0175          }
0176          if ( s ) delete s;
0177          set( b.ReadObjectAny(TString::Class()) );
0178       }
0179       void write_tstring_pointer(TBuffer& b)  {
0180          b.WriteObjectAny(ptr(), TString::Class());
0181       }
0182    };
0183 
0184    /** @class TGenCollectionProxy::Method TGenCollectionProxy.h TGenCollectionProxy.h
0185     *
0186     * Small helper to execute (compiler) generated function for the
0187     * access to STL or other containers.
0188     *
0189     * @author  M.Frank
0190     * @version 1.0
0191     * @date    10/10/2004
0192     */
0193    class Method  {
0194    public:
0195       typedef void* (*Call_t)(void*);
0196       Call_t call;
0197       Method() : call(nullptr)                 {      }
0198       Method(Call_t c) : call(c)               {      }
0199       Method(const Method& m) : call(m.call)   {      }
0200       Method &operator=(const Method& m) { call = m.call; return *this; }
0201       void* invoke(void* obj) const { return (*call)(obj); }
0202    };
0203 
0204    /** @class TGenCollectionProxy::Method TGenCollectionProxy.h TGenCollectionProxy.h
0205     *
0206     * Small helper to execute (compiler) generated function for the
0207     * access to STL or other containers.
0208     *
0209     * @author  M.Frank
0210     * @version 1.0
0211     * @date    10/10/2004
0212     */
0213    class Method0  {
0214    public:
0215       typedef void* (*Call_t)();
0216       Call_t call;
0217       Method0() : call(nullptr)                  {      }
0218       Method0(Call_t c) : call(c)                {      }
0219       Method0(const Method0& m) : call(m.call)   {      }
0220       Method0 &operator=(const Method0& m) { call = m.call; return *this; }
0221       void* invoke() const { return (*call)(); }
0222    };
0223 
0224    /** @class TGenCollectionProxy::TStaging
0225     *
0226     * Small helper to stage the content of an associative
0227     * container when reading and before inserting it in the
0228     * actual collection.
0229     *
0230     * @author  Ph.Canal
0231     * @version 1.0
0232     * @date    20/08/2010
0233     */
0234    class TStaging  {
0235       void   *fTarget;   ///< Pointer to the collection we are staging for.
0236       void   *fContent;  ///< Pointer to the content
0237       size_t  fReserved; ///< Amount of space already reserved.
0238       size_t  fSize;     ///< Number of elements
0239       size_t  fSizeOf;   ///< size of each elements
0240 
0241       TStaging(const TStaging&);            ///< Not implemented.
0242       TStaging &operator=(const TStaging&); ///< Not implemented.
0243 
0244    public:
0245       TStaging(size_t size, size_t size_of) : fTarget(nullptr), fContent(nullptr), fReserved(0), fSize(size), fSizeOf(size_of)
0246       {
0247          // Usual constructor.  Reserves the required number of elements.
0248          fReserved = fSize;
0249          fContent = ::malloc(fReserved * fSizeOf);
0250       }
0251 
0252       ~TStaging() {
0253          // Usual destructor
0254          ::free(fContent);
0255       }
0256 
0257       void   *GetContent() {
0258          // Return the location of the array of content.
0259          return fContent;
0260       }
0261       void   *GetEnd() {
0262          // Return the 'end' of the array of content.
0263          return ((char*)fContent) + fSize*fSizeOf;
0264       }
0265       size_t  GetSize() {
0266          // Return the number of elements.
0267          return fSize;
0268       }
0269       void   *GetTarget() {
0270          // Get the address of the collection we are staging for.
0271          return fTarget;
0272       }
0273       void    Resize(size_t nelement) {
0274          if (fReserved < nelement) {
0275             fReserved = nelement;
0276             fContent = ::realloc(fContent,fReserved * fSizeOf);
0277          }
0278          fSize = nelement;
0279       }
0280       void SetTarget(void *target) {
0281          // Set the collection we are staging for.
0282          fTarget = target;
0283       }
0284    };
0285 
0286 protected:
0287    typedef ROOT::Detail::TCollectionProxyInfo::Environ<char[64]> Env_t;
0288    typedef ROOT::Detail::TCollectionProxyInfo::EnvironBase EnvironBase_t;
0289    typedef std::vector<TStaging*>          Staged_t;  ///< Collection of pre-allocated staged array for associative containers.
0290    typedef std::vector<EnvironBase_t*>     Proxies_t;
0291    mutable TObjArray *fReadMemberWise;                                   ///< Array of bundle of TStreamerInfoActions to stream out (read)
0292    mutable std::map<std::string, TObjArray*> *fConversionReadMemberWise; ///< Array of bundle of TStreamerInfoActions to stream out (read) derived from another class.
0293    mutable TStreamerInfoActions::TActionSequence *fWriteMemberWise;
0294    typedef void (*Sizing_t)(void *obj, size_t size);
0295    typedef void* (*Feedfunc_t)(void *from, void *to, size_t size);
0296    typedef void* (*Collectfunc_t)(void *from, void *to);
0297    typedef void* (*ArrIterfunc_t)(void *from, size_t size);
0298 
0299    std::string   fName;      ///< Name of the class being proxied.
0300    Bool_t        fPointers;  ///< Flag to indicate if containee has pointers (key or value)
0301    Method        fClear;     ///< Method cache for container accessors: clear container
0302    Method        fSize;      ///< Container accessors: size of container
0303    Sizing_t      fResize;    ///< Container accessors: resize container
0304    Method        fFirst;     ///< Container accessors: generic iteration: first
0305    Method        fNext;      ///< Container accessors: generic iteration: next
0306    ArrIterfunc_t fConstruct; ///< Container accessors: block construct
0307    Sizing_t      fDestruct;  ///< Container accessors: block destruct
0308    Feedfunc_t    fFeed;      ///< Container accessors: block feed
0309    Collectfunc_t fCollect;   ///< Method to collect objects from container
0310    Method0       fCreateEnv; ///< Method to allocate an Environment holder.
0311    std::atomic<Value*> fValue;     ///< Descriptor of the container value type
0312    Value*        fVal;       ///< Descriptor of the Value_type
0313    Value*        fKey;       ///< Descriptor of the key_type
0314    EnvironBase_t*fEnv;       ///< Address of the currently proxied object
0315    int           fValOffset; ///< Offset from key to value (in maps)
0316    int           fValDiff;   ///< Offset between two consecutive value_types (memory layout).
0317    Proxies_t     fProxyList; ///< Stack of recursive proxies
0318    Proxies_t     fProxyKept; ///< Optimization: Keep proxies once they were created
0319    Staged_t      fStaged;    ///< Optimization: Keep staged array once they were created
0320    int           fSTL_type;  ///< STL container type
0321    Info_t        fTypeinfo;  ///< Type information
0322    TClass*       fOnFileClass; ///< On file class
0323 
0324    CreateIterators_t    fFunctionCreateIterators;
0325    CopyIterator_t       fFunctionCopyIterator;
0326    Next_t               fFunctionNextIterator;
0327    DeleteIterator_t     fFunctionDeleteIterator;
0328    DeleteTwoIterators_t fFunctionDeleteTwoIterators;
0329 
0330    // Late initialization of collection proxy
0331    TGenCollectionProxy* Initialize(Bool_t silent) const;
0332    // Some hack to avoid const-ness.
0333    virtual TGenCollectionProxy* InitializeEx(Bool_t silent);
0334    // Call to delete/destruct individual contained item.
0335    virtual void DeleteItem(Bool_t force, void* ptr) const;
0336    // Allow to check function pointers.
0337    void CheckFunctions()  const;
0338 
0339 private:
0340    TGenCollectionProxy(); // not implemented on purpose.
0341 
0342 public:
0343 
0344    // Virtual copy constructor.
0345    TVirtualCollectionProxy* Generate() const override;
0346 
0347    // Copy constructor.
0348    TGenCollectionProxy(const TGenCollectionProxy& copy);
0349 
0350 private:
0351    // Assignment operator
0352    TGenCollectionProxy &operator=(const TGenCollectionProxy&); // Not Implemented
0353 
0354 public:
0355    // Initializing constructor
0356    TGenCollectionProxy(Info_t typ, size_t iter_size);
0357    TGenCollectionProxy(const ROOT::Detail::TCollectionProxyInfo &info, TClass *cl);
0358 
0359    // Standard destructor.
0360    ~TGenCollectionProxy() override;
0361 
0362    // Reset the info gathered from StreamerInfos and value's TClass.
0363    Bool_t Reset() override;
0364 
0365    // Return a pointer to the TClass representing the container.
0366    TClass *GetCollectionClass() const override;
0367 
0368    // Return the type of collection see TClassEdit::ESTLType
0369    Int_t   GetCollectionType() const override;
0370 
0371    // Return the offset between two consecutive value_types (memory layout).
0372    ULong_t   GetIncrement() const override;
0373 
0374    // Return the sizeof the collection object.
0375    UInt_t Sizeof() const override;
0376 
0377    // Push new proxy environment.
0378    void PushProxy(void *objstart) override;
0379 
0380    // Pop old proxy environment.
0381    void PopProxy() override;
0382 
0383    // Return true if the content is of type 'pointer to'.
0384    Bool_t HasPointers() const override;
0385 
0386    // Return a pointer to the TClass representing the content.
0387    TClass *GetValueClass() const override;
0388 
0389    // If the content is a simple numerical value, return its type (see TDataType).
0390    EDataType GetType() const override;
0391 
0392    // Return the address of the value at index 'idx'.
0393    void *At(UInt_t idx) override;
0394 
0395    // Clear the container.
0396    void Clear(const char *opt = "") override;
0397 
0398    // Resize the container.
0399    virtual void Resize(UInt_t n, Bool_t force_delete);
0400 
0401    // Return the current size of the container.
0402    UInt_t Size() const override;
0403 
0404    // Block allocation of containees.
0405    void* Allocate(UInt_t n, Bool_t forceDelete) override;
0406 
0407    // Insert data into the container where data is a C-style array of the actual type contained in the collection
0408    // of the given size.   For associative container (map, etc.), the data type is the pair<key,value>.
0409    void  Insert(const void *data, void *container, size_t size) override;
0410 
0411    // Block commit of containees.
0412    void Commit(void* env) override;
0413 
0414    // Streamer function.
0415    virtual void Streamer(TBuffer &refBuffer);
0416 
0417    // Streamer I/O overload.
0418    virtual void Streamer(TBuffer &refBuffer, void *pObject, int siz);
0419 
0420    // TClassStreamer I/O overload.
0421    virtual void operator()(TBuffer &refBuffer, void *pObject);
0422 
0423    // Routine to read the content of the buffer into 'obj'.
0424    virtual void ReadBuffer(TBuffer &b, void *obj);
0425    virtual void ReadBuffer(TBuffer &b, void *obj, const TClass *onfileClass);
0426 
0427    virtual void SetOnFileClass( TClass* cl ) { fOnFileClass = cl; }
0428    virtual TClass* GetOnFileClass() const { return fOnFileClass; }
0429 
0430    // MemberWise actions
0431    TStreamerInfoActions::TActionSequence *GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version) override;
0432    TStreamerInfoActions::TActionSequence *GetReadMemberWiseActions(Int_t version) override;
0433    TStreamerInfoActions::TActionSequence *GetWriteMemberWiseActions() override;
0434 
0435    // Set of functions to iterate easily through the collection
0436 
0437    CreateIterators_t GetFunctionCreateIterators(Bool_t read = kTRUE) override;
0438    // typedef void (*CreateIterators_t)(void *collection, void **begin_arena, void **end_arena);
0439    // begin_arena and end_arena should contain the location of a memory arena of size fgIteratorSize.
0440    // If the collection iterator are of that size or less, the iterators will be constructed in place in those location (new with placement)
0441    // Otherwise the iterators will be allocated via a regular new and their address returned by modifying the value of begin_arena and end_arena.
0442 
0443    CopyIterator_t GetFunctionCopyIterator(Bool_t read = kTRUE) override;
0444    // typedef void* (*CopyIterator_t)(void **dest, const void *source);
0445    // Copy the iterator source, into dest.   dest should contain the location of a memory arena of size fgIteratorSize.
0446    // If the collection iterator is of that size or less, the iterator will be constructed in place in this location (new with placement)
0447    // Otherwise the iterator will be allocated via a regular new.
0448    // The actual address of the iterator is returned in both case.
0449 
0450    Next_t GetFunctionNext(Bool_t read = kTRUE) override;
0451    // typedef void* (*Next_t)(void *iter, const void *end);
0452    // iter and end should be pointers to respectively an iterator to be incremented and the result of collection.end()
0453    // If the iterator has not reached the end of the collection, 'Next' increment the iterator 'iter' and return 0 if
0454    // the iterator reached the end.
0455    // If the end was not reached, 'Next' returns the address of the content pointed to by the iterator before the
0456    // incrementation ; if the collection contains pointers, 'Next' will return the value of the pointer.
0457 
0458    DeleteIterator_t GetFunctionDeleteIterator(Bool_t read = kTRUE) override;
0459    DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read = kTRUE) override;
0460    // typedef void (*DeleteIterator_t)(void *iter);
0461    // typedef void (*DeleteTwoIterators_t)(void *begin, void *end);
0462    // If the size of the iterator is greater than fgIteratorArenaSize, call delete on the addresses,
0463    // Otherwise just call the iterator's destructor.
0464 
0465 };
0466 
0467 template <typename T>
0468 struct AnyCollectionProxy : public TGenCollectionProxy  {
0469    AnyCollectionProxy()
0470       : TGenCollectionProxy(typeid(T::Cont_t),sizeof(T::Iter_t))
0471    {
0472       // Constructor.
0473       fValDiff        = sizeof(T::Value_t);
0474       fValOffset      = T::value_offset();
0475       fSize.call      = T::size;
0476       fResize         = T::resize;
0477       fNext.call      = T::next;
0478       fFirst.call     = T::first;
0479       fClear.call     = T::clear;
0480       fConstruct      = T::construct;
0481       fDestruct       = T::destruct;
0482       fFeed           = T::feed;
0483       CheckFunctions();
0484    }
0485    ~AnyCollectionProxy() override {  }
0486 };
0487 
0488 #endif
0489