CMS 3D CMS Logo

CMSSW_4_4_3_patch1/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 (isInvalid()) i = it.i;
00063           else i->assign(it.i);
00064           return *this;
00065         }
00066         const_iterator& operator++() {
00067           throwInvalidReference(isInvalid(), "increment");
00068           i->increase();
00069           return *this;
00070         }
00071         const_iterator operator++(int) {
00072           throwInvalidReference(isInvalid(), "postincrement");
00073           const_iterator ci = *this;
00074           i->increase();
00075           return ci;
00076         }
00077         const_iterator& operator--() {
00078           throwInvalidReference(isInvalid(), "decrement");
00079           i->decrease();
00080           return *this;
00081         }
00082         const_iterator operator--(int) {
00083           throwInvalidReference(isInvalid(), "postdecrement");
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           throwInvalidReference(isInvalid() || o.isInvalid(), "compute difference with");
00091           return i->difference(o.i);
00092         }
00093         const_iterator operator+(difference_type n) const {
00094           throwInvalidReference(isInvalid(), "compute sum with");
00095           const_iterator_imp* ii = i->clone();
00096           ii->increase(n);
00097           return const_iterator(ii);
00098         }
00099         const_iterator operator-(difference_type n) const {
00100           throwInvalidReference(isInvalid(), "compute difference with");
00101           const_iterator_imp* ii = i->clone();
00102           ii->decrease(n);
00103           return const_iterator(ii);
00104         }
00105         bool operator<(const_iterator const& o) const {
00106           if (isInvalid() && o.isInvalid()) return false;
00107           throwInvalidReference(isInvalid() || o.isInvalid(), "compute < operator with");
00108           return i->less_than(o.i);
00109         }
00110         bool operator==(const_iterator const& ci) const {
00111           if (isInvalid() && ci.isInvalid()) return true;
00112           if (isInvalid() || ci.isInvalid()) return false;
00113           return i->equal_to(ci.i);
00114         }
00115         bool operator!=(const_iterator const& ci) const {
00116           if (isInvalid() && ci.isInvalid()) return false;
00117           if (isInvalid() || ci.isInvalid()) return true;
00118           return ! i->equal_to(ci.i);
00119         }
00120         value_type operator*() const {
00121           throwInvalidReference(isInvalid(), "dereference");
00122           return i->deref();
00123         }
00124         pointer operator->()const {
00125           return pointer(new value_type(operator*()));
00126         }
00127         const_iterator& operator+=(difference_type d) {
00128           throwInvalidReference(isInvalid(), "increment");
00129           i->increase(d);
00130           return *this;
00131         }
00132         const_iterator& operator-=(difference_type d) {
00133           throwInvalidReference(isInvalid(), "decrement");
00134           i->decrease(d);
00135           return *this;
00136         }
00137         bool isValid() const { return i != 0; }
00138         bool isInvalid() const { return i == 0; }
00139 
00140         void throwInvalidReference(bool iIsInvalid, char const* iWhy) const {
00141           if (iIsInvalid) {
00142             Exception::throwThis(errors::InvalidReference, "Trying to ", iWhy, " an invalid RefToBaseVector<T>::const_iterator");
00143           }
00144         }
00145 
00146       private:
00147         const_iterator_imp* i;
00148       };
00149 
00150       virtual const_iterator begin() const = 0;
00151       virtual const_iterator end() const = 0;
00152       virtual void push_back(BaseHolder<T> const*) = 0;
00153       virtual std::auto_ptr<RefVectorHolderBase> vectorHolder() const = 0;
00154       virtual void const* product() const = 0;
00155 
00158       virtual bool isAvailable() const = 0;
00159 
00160       //Used by ROOT storage
00161       CMS_CLASS_VERSION(3)
00162     };
00163 
00164     // Free swap function
00165     template<typename T>
00166     inline
00167     void
00168     swap(BaseVectorHolder<T>& lhs, BaseVectorHolder<T>& rhs) {
00169       lhs.swap(rhs);
00170     }
00171   }
00172 }
00173 
00174 #endif