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