CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/DataFormats/Common/interface/BaseVectorHolder.h

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