CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DataFormats/Common/interface/BaseVectorHolder.h

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       //virtual size_type capacity() const = 0;
00026       //virtual void reserve(size_type n) = 0;
00027       virtual void clear() = 0;
00028       virtual ProductID id() const = 0;
00029       virtual EDProductGetter const* productGetter() const = 0;
00030       void swap(BaseVectorHolder& other) {} // nothing to swap
00031 
00032       // the following structure is public 
00033       // to allow reflex dictionary to compile
00034       //    protected:
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     // Free swap function
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