CMS 3D CMS Logo

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 "Reflex/Type.h"
00006 #include "boost/shared_ptr.hpp"
00007 
00008 namespace edm {
00009   template <typename T> class RefToBase;
00010   namespace reftobase {
00011     class RefVectorHolderBase {
00012     public:
00013       virtual ~RefVectorHolderBase() {}
00014       typedef size_t size_type;
00015       typedef RefHolderBase value_type;
00016       void swap(RefVectorHolderBase& other) {} // nothing to swap
00017       virtual bool empty() const = 0;
00018       virtual size_type size() const = 0;
00019       virtual void clear() = 0;
00020       virtual void reserve( size_type n ) = 0;
00021       virtual ProductID id() const = 0;
00022       virtual EDProductGetter const* productGetter() const = 0;
00023       virtual RefVectorHolderBase * clone() const = 0;
00024       virtual RefVectorHolderBase * cloneEmpty() const = 0;
00025       virtual void push_back( const RefHolderBase * r ) = 0;
00026       // the following structure is public 
00027       // to allow reflex dictionary to compile
00028       //    protected:
00029       struct const_iterator_imp {
00030         typedef ptrdiff_t difference_type;
00031         const_iterator_imp() { } 
00032         virtual ~const_iterator_imp() { }
00033         virtual const_iterator_imp * clone() const = 0;
00034         virtual void increase() = 0;
00035         virtual void decrease() = 0;
00036         virtual void increase( difference_type d ) = 0;
00037         virtual void decrease( difference_type d ) = 0;
00038         virtual bool equal_to( const const_iterator_imp * ) const = 0;
00039         virtual bool less_than( const const_iterator_imp * ) const = 0;
00040         virtual void assign( const const_iterator_imp * ) = 0;
00041         virtual boost::shared_ptr<RefHolderBase> deref() const = 0;
00042         virtual difference_type difference( const const_iterator_imp * ) const = 0;
00043       };
00044 
00045       struct const_iterator : public std::iterator <std::random_access_iterator_tag, void *>{
00046         typedef boost::shared_ptr<RefHolderBase> value_type;
00047         typedef std::ptrdiff_t difference_type;
00048         const_iterator() : i( 0 ) { }
00049         const_iterator( const_iterator_imp * it ) : i( it ) { }
00050         const_iterator( const const_iterator & it ) : i( it.isValid() ? it.i->clone() : 0 ) { }
00051         ~const_iterator() { delete i; }
00052         const_iterator & operator=( const const_iterator & it ) { 
00053           if ( isInvalid() ) i = it.i;
00054           else i->assign( it.i ); 
00055           return *this; 
00056         }
00057         const_iterator& operator++() { 
00058           if ( isInvalid() )
00059             throw edm::Exception( edm::errors::InvalidReference ) 
00060               << "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n";
00061           i->increase(); 
00062           return *this; 
00063         }
00064         const_iterator operator++( int ) { 
00065           if ( isInvalid() )
00066             throw edm::Exception( edm::errors::InvalidReference ) 
00067               << "Trying to postincrement an inavlid RefToBaseVector<T>::const_iterator\n";
00068           const_iterator ci = *this; 
00069           i->increase(); 
00070           return ci; 
00071         }
00072         const_iterator& operator--() { 
00073           if ( isInvalid() )
00074             throw edm::Exception( edm::errors::InvalidReference ) 
00075               << "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n";
00076           i->decrease(); 
00077           return *this; 
00078         }
00079         const_iterator operator--( int ) { 
00080           if ( isInvalid() )
00081             throw edm::Exception( edm::errors::InvalidReference ) 
00082               << "Trying to postdecrement an inavlid RefToBaseVector<T>::const_iterator\n";
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           if ( isInvalid() || o.isInvalid() )
00090             throw edm::Exception( edm::errors::InvalidReference ) 
00091               << "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n";
00092           return i->difference( o.i ); 
00093         }
00094         const_iterator operator+( difference_type n ) const { 
00095           if ( isInvalid() )
00096             throw edm::Exception( edm::errors::InvalidReference ) 
00097               << "Trying to compute sum with an inavlid RefToBaseVector<T>::const_iterator\n";
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           if ( isInvalid() )
00104             throw edm::Exception( edm::errors::InvalidReference ) 
00105               << "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n";
00106           const_iterator_imp * ii = i->clone();
00107           ii->decrease( n );
00108           return const_iterator( ii ); 
00109         }
00110         bool operator<( const const_iterator & o ) const { 
00111           if ( isInvalid() && o.isInvalid() ) return false;
00112           if ( isInvalid() || o.isInvalid() )
00113             throw edm::Exception( edm::errors::InvalidReference ) 
00114               << "Trying to compute < operator with an inavlid RefToBaseVector<T>::const_iterator\n";
00115           return i->less_than( o.i ); 
00116         }
00117         bool operator==( const const_iterator& ci ) const { 
00118           if ( isInvalid() && ci.isInvalid() ) return true;
00119           if ( isInvalid() || ci.isInvalid() ) return false;
00120           return i->equal_to( ci.i ); 
00121         }
00122         bool operator!=( const const_iterator& ci ) const { 
00123           if ( isInvalid() && ci.isInvalid() ) return false;
00124           if ( isInvalid() || ci.isInvalid() ) return true;
00125           return ! i->equal_to( ci.i ); 
00126         }
00127         value_type operator * () const { 
00128           if ( isInvalid() )
00129             throw edm::Exception( edm::errors::InvalidReference ) 
00130               << "Trying to dereference an inavlid RefToBaseVector<T>::const_iterator\n";
00131           return i->deref(); 
00132         }
00133         const_iterator & operator -=( difference_type d ) { 
00134           if ( isInvalid() )
00135             throw edm::Exception( edm::errors::InvalidReference ) 
00136               << "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n";
00137           i->decrease( d ); 
00138           return *this; 
00139         }
00140         const_iterator & operator +=( difference_type d ) { 
00141           if ( isInvalid() )
00142             throw edm::Exception( edm::errors::InvalidReference ) 
00143               << "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n";
00144           i->increase( d ); 
00145           return *this; 
00146         }
00147         bool isValid() const { return i != 0; }
00148         bool isInvalid() const { return i == 0; }
00149 
00150       private:
00151         const_iterator_imp * i;
00152       };
00153 
00154       virtual const_iterator begin() const = 0;
00155       virtual const_iterator end() const = 0;
00156       template <class T> RefToBase<T> getRef( size_t idx ) const;
00157       virtual const void * product() const = 0;
00158       virtual void reallyFillView( const void *, const ProductID &, std::vector<void 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

Generated on Tue Jun 9 17:30:19 2009 for CMSSW by  doxygen 1.5.4