Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:31

0001 #ifndef Fireworks_Core_FWItemRandomAccessor_h
0002 #define Fireworks_Core_FWItemRandomAccessor_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Core
0006 // Class  :     FWItemRandomAccessor
0007 //
0008 // Original Author:  Giulio Eulisse
0009 //         Created:  Thu Feb 18 15:19:44 EDT 2008
0010 //
0011 
0012 // system include files
0013 #include "FWCore/Reflection/interface/ObjectWithDict.h"
0014 
0015 // user include files
0016 #include "Fireworks/Core/interface/FWItemAccessorBase.h"
0017 #include "Fireworks/Core/interface/FWItemAccessorRegistry.h"
0018 
0019 // forward declarations
0020 
0021 /** Non templated part of the generic FWItemRandomAccessor<T>
0022     class. 
0023    
0024     Notice that the constructor is protected, so that it is
0025     impossible to instanciate this baseclass directly.
0026   */
0027 
0028 class FWItemRandomAccessorBase : public FWItemAccessorBase {
0029 public:
0030   ~FWItemRandomAccessorBase() override;
0031 
0032   const void *data() const override;
0033   const TClass *type() const override;
0034   const TClass *modelType() const override;
0035 
0036   bool isCollection() const override;
0037 
0038   void setData(const edm::ObjectWithDict &) override;
0039   void reset() override;
0040 
0041 protected:
0042   void *getDataPtr() const;
0043   FWItemRandomAccessorBase(const TClass *type, const std::type_info &modelTypeName);
0044   const TClass *m_type;
0045   const TClass *m_modelType;
0046   mutable void *m_data;
0047 
0048 public:
0049   FWItemRandomAccessorBase(const FWItemRandomAccessorBase &) = delete;  // stop default
0050 
0051   const FWItemRandomAccessorBase &operator=(const FWItemRandomAccessorBase &) = delete;  // stop default
0052 };
0053 
0054 /** A generic helper class which can be used to create
0055     a specialized FWItemAccessorBase plugin for
0056     all the classes that expose a std::vector like interface.
0057 
0058     The template argument T is the actual type of the
0059     container you want to have an accessor for and it must 
0060     satisty the following:
0061 
0062     - It must have a random access operator (i.e. operator[]()). 
0063     - It must have a size() method which returns the amount of
0064       objects contained in the collection.
0065     - It must contain a value_type typedef which indicates
0066       the type of the contained objects. If this is not the
0067       case, you must specify the extra template argument V.
0068 
0069     Notice that most of the work is actually done by the baseclass.
0070   */
0071 template <class C, class V = typename C::value_type>
0072 class FWItemRandomAccessor : public FWItemRandomAccessorBase {
0073   typedef C container_type;
0074   typedef V container_value_type;
0075 
0076 public:
0077   FWItemRandomAccessor(const TClass *iClass) : FWItemRandomAccessorBase(iClass, typeid(container_value_type)) {}
0078 
0079   REGISTER_FWITEMACCESSOR_METHODS();
0080 
0081   // ---------- const member functions ---------------------
0082   const void *modelData(int iIndex) const override {
0083     if (!getDataPtr())
0084       return nullptr;
0085     return &(reinterpret_cast<container_type *>(getDataPtr())->operator[](iIndex));
0086   }
0087 
0088   unsigned int size() const override {
0089     if (!getDataPtr())
0090       return 0;
0091     return reinterpret_cast<const container_type *>(getDataPtr())->size();
0092   }
0093 };
0094 
0095 /** Generic class for creating accessors for containers which 
0096     are implemented as a container of containers. This for example includes
0097     `DetSetVector` hence the name. Both the outer and the inner containers
0098     must follow the Random Access Container model and in particular
0099     must have a size() method. The outer collection must be iterable, while
0100     the inner collections must have an array subscript operator. 
0101   */
0102 template <class C, class COLL = typename C::value_type, class V = typename COLL::value_type>
0103 class FWItemDetSetAccessor : public FWItemRandomAccessorBase {
0104 public:
0105   typedef C container_type;
0106   typedef COLL collection_type;
0107   typedef V collection_value_type;
0108 
0109   FWItemDetSetAccessor(const TClass *iClass) : FWItemRandomAccessorBase(iClass, typeid(collection_value_type)) {}
0110 
0111   REGISTER_FWITEMACCESSOR_METHODS();
0112 
0113   const void *modelData(int iIndex) const override {
0114     if (!getDataPtr())
0115       return nullptr;
0116     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0117     size_t collectionOffset = 0;
0118     for (typename container_type::const_iterator ci = c->begin(), ce = c->end(); ci != ce; ++ci) {
0119       size_t i = iIndex - collectionOffset;
0120       if (i < ci->size())
0121         return &(ci->operator[](i));
0122       collectionOffset += ci->size();
0123     }
0124 
0125     return nullptr;
0126   }
0127 
0128   unsigned int size() const override {
0129     if (!getDataPtr())
0130       return 0;
0131     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0132     size_t finalSize = 0;
0133 
0134     for (typename container_type::const_iterator i = c->begin(), e = c->end(); i != e; ++i)
0135       finalSize += i->size();
0136 
0137     return finalSize;
0138   }
0139 };
0140 
0141 /** Specialized accessor for the new edmNew::DetSetVector classes.
0142   */
0143 template <class C, class COLL = typename C::value_type, class V = typename COLL::value_type>
0144 class FWItemNewDetSetAccessor : public FWItemRandomAccessorBase {
0145 public:
0146   typedef C container_type;
0147   typedef COLL collection_type;
0148   typedef V collection_value_type;
0149 
0150   FWItemNewDetSetAccessor(const TClass *iClass) : FWItemRandomAccessorBase(iClass, typeid(collection_value_type)) {}
0151 
0152   REGISTER_FWITEMACCESSOR_METHODS();
0153 
0154   const void *modelData(int iIndex) const override {
0155     if (!getDataPtr())
0156       return nullptr;
0157     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0158     if (iIndex < 0)
0159       return nullptr;
0160 
0161     return &(c->data().operator[](iIndex));
0162   }
0163 
0164   unsigned int size() const override {
0165     if (!getDataPtr())
0166       return 0;
0167     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0168     return c->dataSize();
0169   }
0170 };
0171 
0172 template <class C, class R = typename C::Range, class V = typename R::value_type>
0173 class FWItemRangeAccessor : public FWItemRandomAccessorBase {
0174 public:
0175   typedef C container_type;
0176   typedef R range_type;
0177   typedef V value_type;
0178 
0179   FWItemRangeAccessor(const TClass *iClass) : FWItemRandomAccessorBase(iClass, typeid(value_type)) {}
0180 
0181   REGISTER_FWITEMACCESSOR_METHODS();
0182 
0183   const void *modelData(int iIndex) const override {
0184     if (!getDataPtr())
0185       return nullptr;
0186     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0187     size_t collectionOffset = 0;
0188     for (typename container_type::const_iterator ci = c->begin(), ce = c->end(); ci != ce; ++ci) {
0189       size_t i = iIndex - collectionOffset;
0190       if (i < std::distance(ci->first, ci->second))
0191         return &(*(ci + i));
0192       collectionOffset += ci->size();
0193     }
0194 
0195     return nullptr;
0196   }
0197 
0198   unsigned int size() const override {
0199     if (!getDataPtr())
0200       return 0;
0201     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0202     size_t finalSize = 0;
0203 
0204     for (typename range_type::const_iterator ci = c->begin(), ce = c->end(); ci != ce; ++ci)
0205       finalSize += std::distance(ci->first, ci->second);
0206 
0207     return finalSize;
0208   }
0209 };
0210 
0211 template <class C, class V>
0212 class FWItemMuonDigiAccessor : public FWItemRandomAccessorBase {
0213 public:
0214   typedef C container_type;
0215   typedef V value_type;
0216 
0217   FWItemMuonDigiAccessor(const TClass *iClass) : FWItemRandomAccessorBase(iClass, typeid(value_type)) {}
0218 
0219   REGISTER_FWITEMACCESSOR_METHODS();
0220 
0221   const void *modelData(int iIndex) const override {
0222     if (!getDataPtr())
0223       return nullptr;
0224     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0225     size_t collectionOffset = 0;
0226 
0227     for (typename container_type::DigiRangeIterator ci = c->begin(), ce = c->end(); ci != ce; ++ci) {
0228       int i = iIndex - collectionOffset;
0229 
0230       typename container_type::DigiRangeIterator::value_type vt = *ci;
0231 
0232       if (i < std::distance(vt.second.first, vt.second.second))
0233         return &(*(vt.second.first + i));
0234       collectionOffset += std::distance(vt.second.first, vt.second.second);
0235     }
0236 
0237     return nullptr;
0238   }
0239 
0240   unsigned int size() const override {
0241     if (!getDataPtr())
0242       return 0;
0243     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0244     size_t finalSize = 0;
0245 
0246     for (typename container_type::DigiRangeIterator ci = c->begin(), ce = c->end(); ci != ce; ++ci) {
0247       typename container_type::DigiRangeIterator::value_type vt = *ci;
0248       finalSize += std::distance(vt.second.first, vt.second.second);
0249     }
0250 
0251     return finalSize;
0252   }
0253 };
0254 
0255 template <class C>
0256 class BXVectorAccessor : public FWItemRandomAccessorBase {
0257 public:
0258   typedef C container_type;
0259 
0260   BXVectorAccessor(const TClass *iClass) : FWItemRandomAccessorBase(iClass, typeid(typename C::value_type)) {}
0261 
0262   REGISTER_FWITEMACCESSOR_METHODS();
0263 
0264   const void *modelData(int iIndex) const override {
0265     if (!getDataPtr())
0266       return nullptr;
0267 
0268     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0269 
0270     return &(c->at(0, iIndex));
0271   }
0272 
0273   unsigned int size() const override {
0274     if (!getDataPtr())
0275       return 0;
0276 
0277     const container_type *c = reinterpret_cast<const container_type *>(getDataPtr());
0278 
0279     return c->size(0);
0280   }
0281 };
0282 
0283 #endif