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