CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DataFormats/Common/interface/RefVectorHolderBase.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_RefVectorHolderBase_h
00002 #define DataFormats_Common_RefVectorHolderBase_h
00003 
00004 #include "DataFormats/Common/interface/RefHolderBase.h"
00005 #include "FWCore/Utilities/interface/EDMException.h"
00006 
00007 #include "boost/shared_ptr.hpp"
00008 
00009 namespace edm {
00010   template<typename T> class RefToBase;
00011   namespace reftobase {
00012     class RefVectorHolderBase {
00013     public:
00014       virtual ~RefVectorHolderBase() {}
00015       typedef size_t size_type;
00016       typedef RefHolderBase value_type;
00017       void swap(RefVectorHolderBase&) {} // nothing to swap
00018       virtual bool empty() const = 0;
00019       virtual size_type size() const = 0;
00020       virtual void clear() = 0;
00021       virtual void reserve(size_type n) = 0;
00022       virtual ProductID id() const = 0;
00023       virtual EDProductGetter const* productGetter() const = 0;
00024       virtual RefVectorHolderBase* clone() const = 0;
00025       virtual RefVectorHolderBase* cloneEmpty() const = 0;
00026       virtual void push_back(RefHolderBase const* r) = 0;
00027       // the following structure is public
00028       // to allow reflex dictionary to compile
00029       //    protected:
00030       struct const_iterator_imp {
00031         typedef ptrdiff_t difference_type;
00032         const_iterator_imp() { }
00033         virtual ~const_iterator_imp() { }
00034         virtual const_iterator_imp* clone() const = 0;
00035         virtual void increase() = 0;
00036         virtual void decrease() = 0;
00037         virtual void increase(difference_type d) = 0;
00038         virtual void decrease(difference_type d) = 0;
00039         virtual bool equal_to(const_iterator_imp const*) const = 0;
00040         virtual bool less_than(const_iterator_imp const*) const = 0;
00041         virtual void assign(const_iterator_imp const*) = 0;
00042         virtual boost::shared_ptr<RefHolderBase> deref() const = 0;
00043         virtual difference_type difference(const_iterator_imp const*) const = 0;
00044       };
00045 
00046       struct const_iterator : public std::iterator <std::random_access_iterator_tag, void*>{
00047         typedef boost::shared_ptr<RefHolderBase> value_type;
00048         typedef std::ptrdiff_t difference_type;
00049         const_iterator() : i(0) { }
00050         const_iterator(const_iterator_imp* it) : i(it) { }
00051         const_iterator(const_iterator const& it) : i(it.isValid() ? it.i->clone() : 0) { }
00052         ~const_iterator() { delete i; }
00053         const_iterator& operator=(const_iterator const& it) {
00054           if(isInvalid()) i = it.i;
00055           else i->assign(it.i);
00056           return *this;
00057         }
00058         const_iterator& operator++() {
00059           if(isInvalid())
00060             Exception::throwThis(errors::InvalidReference,
00061               "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
00062           i->increase();
00063           return *this;
00064         }
00065         const_iterator operator++(int) {
00066           if(isInvalid())
00067             Exception::throwThis(errors::InvalidReference,
00068               "Trying to postincrement an inavlid RefToBaseVector<T>::const_iterator\n");
00069           const_iterator ci = *this;
00070           i->increase();
00071           return ci;
00072         }
00073         const_iterator& operator--() {
00074           if(isInvalid())
00075             Exception::throwThis(errors::InvalidReference,
00076               "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
00077           i->decrease();
00078           return *this;
00079         }
00080         const_iterator operator--(int) {
00081           if(isInvalid())
00082             Exception::throwThis(errors::InvalidReference,
00083               "Trying to postdecrement an inavlid RefToBaseVector<T>::const_iterator\n");
00084           const_iterator ci = *this;
00085           i->decrease();
00086           return ci;
00087         }
00088         difference_type operator-(const_iterator const& o) const {
00089           if(isInvalid() && o.isInvalid()) return 0;
00090           if(isInvalid() || o.isInvalid())
00091             Exception::throwThis(errors::InvalidReference,
00092               "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
00093           return i->difference(o.i);
00094         }
00095         const_iterator operator+(difference_type n) const {
00096           if(isInvalid())
00097             Exception::throwThis(errors::InvalidReference,
00098               "Trying to compute sum with an inavlid RefToBaseVector<T>::const_iterator\n");
00099           const_iterator_imp* ii = i->clone();
00100           ii->increase(n);
00101           return const_iterator(ii);
00102         }
00103         const_iterator operator-(difference_type n) const {
00104           if(isInvalid())
00105             Exception::throwThis(errors::InvalidReference,
00106               "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
00107           const_iterator_imp* ii = i->clone();
00108           ii->decrease(n);
00109           return const_iterator(ii);
00110         }
00111         bool operator<(const_iterator const& o) const {
00112           if(isInvalid() && o.isInvalid()) return false;
00113           if(isInvalid() || o.isInvalid())
00114             Exception::throwThis(errors::InvalidReference,
00115               "Trying to compute < operator with an inavlid RefToBaseVector<T>::const_iterator\n");
00116           return i->less_than(o.i);
00117         }
00118         bool operator==(const const_iterator& ci) const {
00119           if(isInvalid() && ci.isInvalid()) return true;
00120           if(isInvalid() || ci.isInvalid()) return false;
00121           return i->equal_to(ci.i);
00122         }
00123         bool operator!=(const const_iterator& ci) const {
00124           if(isInvalid() && ci.isInvalid()) return false;
00125           if(isInvalid() || ci.isInvalid()) return true;
00126           return ! i->equal_to(ci.i);
00127         }
00128         value_type operator*() const {
00129           if(isInvalid())
00130             Exception::throwThis(errors::InvalidReference,
00131               "Trying to dereference an inavlid RefToBaseVector<T>::const_iterator\n");
00132           return i->deref();
00133         }
00134         const_iterator& operator-=(difference_type d) {
00135           if(isInvalid())
00136             Exception::throwThis(errors::InvalidReference,
00137               "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
00138           i->decrease(d);
00139           return *this;
00140         }
00141         const_iterator& operator+=(difference_type d) {
00142           if(isInvalid())
00143             Exception::throwThis(errors::InvalidReference,
00144               "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
00145           i->increase(d);
00146           return *this;
00147         }
00148         bool isValid() const { return i != 0; }
00149         bool isInvalid() const { return i == 0; }
00150 
00151       private:
00152         const_iterator_imp* i;
00153       };
00154 
00155       virtual const_iterator begin() const = 0;
00156       virtual const_iterator end() const = 0;
00157       template<typename T> RefToBase<T> getRef(size_t idx) const;
00158       virtual void const* product() const = 0;
00159       virtual void reallyFillView(void const*, ProductID const&, std::vector<void const*>&) = 0;
00160       virtual size_t keyForIndex(size_t idx) const = 0;
00161 
00164       virtual bool isAvailable() const = 0;
00165 
00166     private:
00167       virtual boost::shared_ptr<reftobase::RefHolderBase> refBase(size_t idx) const = 0;
00168     };
00169 
00170     template<typename T>
00171     RefToBase<T> RefVectorHolderBase::getRef(size_t idx) const {
00172       boost::shared_ptr<reftobase::RefHolderBase> rb = refBase(idx);
00173       return RefToBase<T>(rb);
00174     }
00175 
00176     // Free swap function
00177     inline
00178     void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) {
00179       lhs.swap(rhs);
00180     }
00181   }
00182 }
00183 
00184 #endif