CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/Common/interface/RefVectorHolderBase.h

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) {} // nothing to swap
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       // the following structure is public
00026       // to allow reflex dictionary to compile
00027       //    protected:
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     // Free swap function
00175     inline
00176     void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) {
00177       lhs.swap(rhs);
00178     }
00179 
00180   }
00181 }
00182 
00183 #endif