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
00027
00028 virtual void clear() = 0;
00029 virtual ProductID id() const = 0;
00030 virtual EDProductGetter const* productGetter() const = 0;
00031 void swap(BaseVectorHolder&) {}
00032
00033
00034
00035
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
00164 CMS_CLASS_VERSION(3)
00165 };
00166
00167
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