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 (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
00161 CMS_CLASS_VERSION(3)
00162 };
00163
00164
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