Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:49:26

0001 #ifndef DataFormats_Common_RefVectorIterator_h
0002 #define DataFormats_Common_RefVectorIterator_h
0003 
0004 /*----------------------------------------------------------------------
0005   
0006 RefVectorIterator: An iterator for a RefVector
0007 Note: this is actually a *const_iterator*
0008 
0009 
0010 ----------------------------------------------------------------------*/
0011 
0012 #include <memory>
0013 #include "DataFormats/Common/interface/Ref.h"
0014 #include "DataFormats/Common/interface/RefTraits.h"
0015 #include "DataFormats/Common/interface/RefVector.h"
0016 
0017 namespace edm {
0018 
0019   template <typename C, typename T = typename Ref<C>::value_type, typename F = typename Ref<C>::finder_type>
0020   class RefVectorIterator : public std::iterator<std::random_access_iterator_tag, Ref<C, T, F> > {
0021   public:
0022     typedef Ref<C, T, F> value_type;
0023     typedef Ref<C, T, F> const const_reference;  // Otherwise boost::iterator_reference assumes '*it' returns 'Ref &'
0024     typedef const_reference reference;  // This to prevent compilation of code that tries to modify the RefVector
0025                                         // through this iterator
0026     typedef typename value_type::key_type key_type;
0027 
0028     typedef RefVectorIterator<C, T, F> iterator;
0029     typedef std::ptrdiff_t difference;
0030     typedef typename std::vector<key_type>::const_iterator keyIter;
0031     typedef typename std::vector<void const*>::const_iterator MemberIter;
0032 
0033     RefVectorIterator() : refVector_(nullptr), nestedRefVector_(nullptr), iter_(0) {}
0034 
0035     explicit RefVectorIterator(RefVector<C, T, F> const* refVector, typename RefVector<C, T, F>::size_type iter)
0036         : refVector_(refVector), nestedRefVector_(nullptr), iter_(iter) {}
0037 
0038     explicit RefVectorIterator(
0039         RefVector<RefVector<C, T, F>, T, typename refhelper::FindTrait<RefVector<C, T, F>, T>::value> const* refVector,
0040         typename RefVector<C, T, F>::size_type iter)
0041         : refVector_(nullptr), nestedRefVector_(refVector), iter_(iter) {}
0042 
0043     reference operator*() const {
0044       if (refVector_)
0045         return (*refVector_)[iter_];
0046       return (*nestedRefVector_)[iter_];
0047     }
0048     reference operator[](difference n) const {
0049       typename RefVector<C, T, F>::size_type j = iter_ + n;
0050       if (refVector_)
0051         return (*refVector_)[j];
0052       return (*nestedRefVector_)[j];
0053     }
0054 
0055     class RefProxy {
0056     public:
0057       RefProxy(value_type const& ref) : ref_(ref) {}
0058       value_type const* operator->() const { return &ref_; }
0059 
0060     private:
0061       value_type ref_;
0062     };
0063 
0064     RefProxy operator->() const {
0065       if (refVector_)
0066         return RefProxy(value_type((*refVector_)[iter_]));
0067       return RefProxy(value_type((*nestedRefVector_)[iter_]));
0068     }
0069     iterator& operator++() {
0070       ++iter_;
0071       return *this;
0072     }
0073     iterator& operator--() {
0074       --iter_;
0075       return *this;
0076     }
0077     iterator& operator+=(difference n) {
0078       iter_ += n;
0079       return *this;
0080     }
0081     iterator& operator-=(difference n) {
0082       iter_ -= n;
0083       return *this;
0084     }
0085 
0086     iterator operator++(int) {
0087       iterator it(*this);
0088       ++iter_;
0089       return it;
0090     }
0091     iterator operator--(int) {
0092       iterator it(*this);
0093       --iter_;
0094       return it;
0095     }
0096     iterator operator+(difference n) const {
0097       iterator it(*this);
0098       it.iter_ += n;
0099       return it;
0100     }
0101     iterator operator-(difference n) const {
0102       iterator it(*this);
0103       it.iter_ -= n;
0104       return it;
0105     }
0106 
0107     difference operator-(iterator const& rhs) const { return this->iter_ - rhs.iter_; }
0108 
0109     bool operator==(iterator const& rhs) const { return this->iter_ == rhs.iter_; }
0110     bool operator!=(iterator const& rhs) const { return this->iter_ != rhs.iter_; }
0111     bool operator<(iterator const& rhs) const { return this->iter_ < rhs.iter_; }
0112     bool operator>(iterator const& rhs) const { return this->iter_ > rhs.iter_; }
0113     bool operator<=(iterator const& rhs) const { return this->iter_ <= rhs.iter_; }
0114     bool operator>=(iterator const& rhs) const { return this->iter_ >= rhs.iter_; }
0115 
0116     key_type key() const {
0117       if (refVector_)
0118         return (*refVector_)[iter_].key();
0119       return (*nestedRefVector_)[iter_].key();
0120     }
0121 
0122   private:
0123     RefVector<C, T, F> const* refVector_;
0124     RefVector<RefVector<C, T, F>, T, typename refhelper::FindTrait<RefVector<C, T, F>, T>::value> const*
0125         nestedRefVector_;
0126     typename RefVector<C, T, F>::size_type iter_;
0127   };
0128 
0129   template <typename C, typename T, typename F>
0130   inline RefVectorIterator<C, T, F> operator+(typename RefVectorIterator<C, T, F>::difference n,
0131                                               RefVectorIterator<C, T, F> const& iter) {
0132     return iter + n;
0133   }
0134 }  // namespace edm
0135 #endif