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