00001 #ifndef DataFormats_Common_VectorHolder_h 00002 #define DataFormats_Common_VectorHolder_h 00003 #include "DataFormats/Common/interface/BaseVectorHolder.h" 00004 #include "DataFormats/Common/interface/Holder.h" 00005 00006 namespace edm { 00007 namespace reftobase { 00008 00009 class RefVectorHolderBase; 00010 00011 template <class T, class REFV> 00012 class VectorHolder : public BaseVectorHolder<T> { 00013 public: 00014 typedef BaseVectorHolder<T> base_type; 00015 typedef typename base_type::size_type size_type; 00016 typedef typename base_type::element_type element_type; 00017 typedef typename base_type::base_ref_type base_ref_type; 00018 typedef typename base_type::const_iterator const_iterator; 00019 typedef REFV ref_vector_type; 00020 00021 VectorHolder() {} 00022 explicit VectorHolder(const ref_vector_type& iRefVector) : refVector_(iRefVector) {} 00023 explicit VectorHolder(const ProductID& id) : refVector_(id) {} 00024 virtual ~VectorHolder() {} 00025 virtual base_type* clone() const { return new VectorHolder(*this); } 00026 virtual base_type* cloneEmpty() const { return new VectorHolder(refVector_.id()); } 00027 base_ref_type const at(size_type idx) const { return base_ref_type( refVector_.at( idx ) ); } 00028 bool empty() const { return refVector_.empty(); } 00029 size_type size() const { return refVector_.size(); } 00030 //size_type capacity() const { return refVector_.capacity(); } 00031 //void reserve(size_type n) { refVector_.reserve(n); } 00032 void clear() { refVector_.clear(); } 00033 ProductID id() const { return refVector_.id(); } 00034 EDProductGetter const* productGetter() const { return refVector_.productGetter(); } 00035 void swap(VectorHolder& other) { 00036 this->BaseVectorHolder<T>::swap(other); 00037 refVector_.swap(other.refVector_); 00038 } 00039 VectorHolder& operator=(VectorHolder const& rhs) { 00040 VectorHolder temp(rhs); 00041 this->swap(temp); 00042 return *this; 00043 } 00044 00045 const_iterator begin() const { 00046 return const_iterator( new const_iterator_imp_specific( refVector_.begin() ) ); 00047 } 00048 const_iterator end() const { 00049 return const_iterator( new const_iterator_imp_specific( refVector_.end() ) ); 00050 } 00051 virtual void push_back( const BaseHolder<T> * r ) { 00052 typedef Holder<T, typename REFV::value_type > holder_type; 00053 const holder_type * h = dynamic_cast<const holder_type *>( r ); 00054 if( h == 0 ) 00055 throw edm::Exception( edm::errors::InvalidReference ) 00056 << "In VectorHolder<T, REFV> trying to push_back wrong reference type"; 00057 refVector_.push_back( h->getRef() ); 00058 } 00059 virtual std::auto_ptr<RefVectorHolderBase> vectorHolder() const { 00060 return std::auto_ptr<RefVectorHolderBase>( new RefVectorHolder<REFV>( refVector_ ) ); 00061 } 00062 virtual const void * product() const { 00063 return refVector_.product(); 00064 } 00065 00068 virtual bool isAvailable() const { return refVector_.isAvailable(); } 00069 00070 private: 00071 typedef typename base_type::const_iterator_imp const_iterator_imp; 00072 00073 ref_vector_type refVector_; 00074 00075 // the following structure is public 00076 // to allow reflex dictionary to compile 00077 public: 00078 struct const_iterator_imp_specific : public const_iterator_imp { 00079 typedef ptrdiff_t difference_type; 00080 const_iterator_imp_specific() { } 00081 explicit const_iterator_imp_specific( const typename REFV::const_iterator & it ) : i ( it ) { } 00082 ~const_iterator_imp_specific() { } 00083 const_iterator_imp_specific * clone() const { return new const_iterator_imp_specific( i ); } 00084 void increase() { ++i; } 00085 void decrease() { --i; } 00086 void increase( difference_type d ) { i += d; } 00087 void decrease( difference_type d ) { i -= d; } 00088 bool equal_to( const const_iterator_imp * o ) const { return i == dc( o ); } 00089 bool less_than( const const_iterator_imp * o ) const { return i < dc( o ); } 00090 void assign( const const_iterator_imp * o ) { i = dc( o ); } 00091 base_ref_type deref() const { return base_ref_type( * i ); } 00092 difference_type difference( const const_iterator_imp * o ) const { return i - dc( o ); } 00093 private: 00094 const typename ref_vector_type::const_iterator & dc( const const_iterator_imp * o ) const { 00095 if ( o == 0 ) 00096 throw edm::Exception( edm::errors::InvalidReference ) 00097 << "In RefToBaseVector<T> trying to dereference a null pointer"; 00098 const const_iterator_imp_specific * oo = dynamic_cast<const const_iterator_imp_specific *>( o ); 00099 if ( oo == 0 ) 00100 throw edm::Exception( edm::errors::InvalidReference ) 00101 << "In RefToBaseVector<T> trying to cast iterator to wrong type "; 00102 return oo->i; 00103 } 00104 typename ref_vector_type::const_iterator i; 00105 }; 00106 }; 00107 00108 // Free swap function 00109 template <typename T, typename REFV> 00110 inline 00111 void 00112 swap(VectorHolder<T, REFV>& lhs, VectorHolder<T, REFV>& rhs) { 00113 lhs.swap(rhs); 00114 } 00115 } 00116 } 00117 00118 #endif