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&) {}
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
00028
00029
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
00177 inline
00178 void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) {
00179 lhs.swap(rhs);
00180 }
00181 }
00182 }
00183
00184 #endif