Go to the documentation of this file.00001 #ifndef DataFormats_Common_RefVectorHolderBase_h
00002 #define DataFormats_Common_RefVectorHolderBase_h
00003 #include "DataFormats/Common/interface/RefHolderBase.h"
00004 #include "FWCore/Utilities/interface/EDMException.h"
00005 #include "boost/shared_ptr.hpp"
00006
00007 namespace edm {
00008 template <typename T> class RefToBase;
00009 namespace reftobase {
00010 class RefVectorHolderBase {
00011 public:
00012 virtual ~RefVectorHolderBase() {}
00013 typedef size_t size_type;
00014 typedef RefHolderBase value_type;
00015 void swap(RefVectorHolderBase& other) {}
00016 virtual bool empty() const = 0;
00017 virtual size_type size() const = 0;
00018 virtual void clear() = 0;
00019 virtual void reserve( size_type n ) = 0;
00020 virtual ProductID id() const = 0;
00021 virtual EDProductGetter const* productGetter() const = 0;
00022 virtual RefVectorHolderBase * clone() const = 0;
00023 virtual RefVectorHolderBase * cloneEmpty() const = 0;
00024 virtual void push_back( const RefHolderBase * r ) = 0;
00025
00026
00027
00028 struct const_iterator_imp {
00029 typedef ptrdiff_t difference_type;
00030 const_iterator_imp() { }
00031 virtual ~const_iterator_imp() { }
00032 virtual const_iterator_imp * clone() const = 0;
00033 virtual void increase() = 0;
00034 virtual void decrease() = 0;
00035 virtual void increase( difference_type d ) = 0;
00036 virtual void decrease( difference_type d ) = 0;
00037 virtual bool equal_to( const const_iterator_imp * ) const = 0;
00038 virtual bool less_than( const const_iterator_imp * ) const = 0;
00039 virtual void assign( const const_iterator_imp * ) = 0;
00040 virtual boost::shared_ptr<RefHolderBase> deref() const = 0;
00041 virtual difference_type difference( const const_iterator_imp * ) const = 0;
00042 };
00043
00044 struct const_iterator : public std::iterator <std::random_access_iterator_tag, void *>{
00045 typedef boost::shared_ptr<RefHolderBase> value_type;
00046 typedef std::ptrdiff_t difference_type;
00047 const_iterator() : i( 0 ) { }
00048 const_iterator( const_iterator_imp * it ) : i( it ) { }
00049 const_iterator( const const_iterator & it ) : i( it.isValid() ? it.i->clone() : 0 ) { }
00050 ~const_iterator() { delete i; }
00051 const_iterator & operator=( const const_iterator & it ) {
00052 if ( isInvalid() ) i = it.i;
00053 else i->assign( it.i );
00054 return *this;
00055 }
00056 const_iterator& operator++() {
00057 if ( isInvalid() )
00058 Exception::throwThis(errors::InvalidReference,
00059 "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
00060 i->increase();
00061 return *this;
00062 }
00063 const_iterator operator++( int ) {
00064 if ( isInvalid() )
00065 Exception::throwThis(errors::InvalidReference,
00066 "Trying to postincrement an inavlid RefToBaseVector<T>::const_iterator\n");
00067 const_iterator ci = *this;
00068 i->increase();
00069 return ci;
00070 }
00071 const_iterator& operator--() {
00072 if ( isInvalid() )
00073 Exception::throwThis(errors::InvalidReference,
00074 "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
00075 i->decrease();
00076 return *this;
00077 }
00078 const_iterator operator--( int ) {
00079 if ( isInvalid() )
00080 Exception::throwThis(errors::InvalidReference,
00081 "Trying to postdecrement an inavlid RefToBaseVector<T>::const_iterator\n");
00082 const_iterator ci = *this;
00083 i->decrease();
00084 return ci;
00085 }
00086 difference_type operator-( const const_iterator & o ) const {
00087 if ( isInvalid() && o.isInvalid() ) return 0;
00088 if ( isInvalid() || o.isInvalid() )
00089 Exception::throwThis(errors::InvalidReference,
00090 "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
00091 return i->difference( o.i );
00092 }
00093 const_iterator operator+( difference_type n ) const {
00094 if ( isInvalid() )
00095 Exception::throwThis(errors::InvalidReference,
00096 "Trying to compute sum with an inavlid RefToBaseVector<T>::const_iterator\n");
00097 const_iterator_imp * ii = i->clone();
00098 ii->increase( n );
00099 return const_iterator( ii );
00100 }
00101 const_iterator operator-( difference_type n ) const {
00102 if ( isInvalid() )
00103 Exception::throwThis(errors::InvalidReference,
00104 "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
00105 const_iterator_imp * ii = i->clone();
00106 ii->decrease( n );
00107 return const_iterator( ii );
00108 }
00109 bool operator<( const const_iterator & o ) const {
00110 if ( isInvalid() && o.isInvalid() ) return false;
00111 if ( isInvalid() || o.isInvalid() )
00112 Exception::throwThis(errors::InvalidReference,
00113 "Trying to compute < operator with an inavlid RefToBaseVector<T>::const_iterator\n");
00114 return i->less_than( o.i );
00115 }
00116 bool operator==( const const_iterator& ci ) const {
00117 if ( isInvalid() && ci.isInvalid() ) return true;
00118 if ( isInvalid() || ci.isInvalid() ) return false;
00119 return i->equal_to( ci.i );
00120 }
00121 bool operator!=( const const_iterator& ci ) const {
00122 if ( isInvalid() && ci.isInvalid() ) return false;
00123 if ( isInvalid() || ci.isInvalid() ) return true;
00124 return ! i->equal_to( ci.i );
00125 }
00126 value_type operator * () const {
00127 if ( isInvalid() )
00128 Exception::throwThis(errors::InvalidReference,
00129 "Trying to dereference an inavlid RefToBaseVector<T>::const_iterator\n");
00130 return i->deref();
00131 }
00132 const_iterator & operator -=( difference_type d ) {
00133 if ( isInvalid() )
00134 Exception::throwThis(errors::InvalidReference,
00135 "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
00136 i->decrease( d );
00137 return *this;
00138 }
00139 const_iterator & operator +=( difference_type d ) {
00140 if ( isInvalid() )
00141 Exception::throwThis(errors::InvalidReference,
00142 "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
00143 i->increase( d );
00144 return *this;
00145 }
00146 bool isValid() const { return i != 0; }
00147 bool isInvalid() const { return i == 0; }
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 template <class T> RefToBase<T> getRef( size_t idx ) const;
00156 virtual const void * product() const = 0;
00157 virtual void reallyFillView( const void *, const ProductID &, std::vector<void const*> & ) = 0;
00158 virtual size_t keyForIndex(size_t idx) const = 0;
00159
00162 virtual bool isAvailable() const = 0;
00163
00164 private:
00165 virtual boost::shared_ptr<reftobase::RefHolderBase> refBase(size_t idx) const = 0;
00166 };
00167
00168 template <class T>
00169 RefToBase<T> RefVectorHolderBase::getRef( size_t idx ) const {
00170 boost::shared_ptr<reftobase::RefHolderBase> rb = refBase(idx);
00171 return RefToBase<T>( rb );
00172 }
00173
00174
00175 inline
00176 void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) {
00177 lhs.swap(rhs);
00178 }
00179
00180 }
00181 }
00182
00183 #endif