Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:38:44

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 {
0021   public:
0022     using iterator_category = std::random_access_iterator_tag;
0023     using value_type = Ref<C, T, F>;
0024     using const_reference = Ref<C, T, F> const;  // Otherwise boost::iterator_reference assumes '*it' returns 'Ref &'
0025     using reference = const_reference;  // This to prevent compilation of code that tries to modify the RefVector
0026                                         // through this iterator
0027     using pointer = Ref<C, T, F> const*;
0028     using key_type = typename value_type::key_type;
0029 
0030     using iterator = RefVectorIterator<C, T, F>;
0031     using difference = std::ptrdiff_t;
0032     using difference_type = difference;
0033     using keyIter = typename std::vector<key_type>::const_iterator;
0034     using MemberIter = typename std::vector<void const*>::const_iterator;
0035 
0036     RefVectorIterator() : refVector_(nullptr), nestedRefVector_(nullptr), iter_(0) {}
0037 
0038     explicit RefVectorIterator(RefVector<C, T, F> const* refVector, typename RefVector<C, T, F>::size_type iter)
0039         : refVector_(refVector), nestedRefVector_(nullptr), iter_(iter) {}
0040 
0041     explicit RefVectorIterator(
0042         RefVector<RefVector<C, T, F>, T, typename refhelper::FindTrait<RefVector<C, T, F>, T>::value> const* refVector,
0043         typename RefVector<C, T, F>::size_type iter)
0044         : refVector_(nullptr), nestedRefVector_(refVector), iter_(iter) {}
0045 
0046     reference operator*() const {
0047       if (refVector_)
0048         return (*refVector_)[iter_];
0049       return (*nestedRefVector_)[iter_];
0050     }
0051     reference operator[](difference n) const {
0052       typename RefVector<C, T, F>::size_type j = iter_ + n;
0053       if (refVector_)
0054         return (*refVector_)[j];
0055       return (*nestedRefVector_)[j];
0056     }
0057 
0058     class RefProxy {
0059     public:
0060       RefProxy(value_type const& ref) : ref_(ref) {}
0061       value_type const* operator->() const { return &ref_; }
0062 
0063     private:
0064       value_type ref_;
0065     };
0066 
0067     RefProxy operator->() const {
0068       if (refVector_)
0069         return RefProxy(value_type((*refVector_)[iter_]));
0070       return RefProxy(value_type((*nestedRefVector_)[iter_]));
0071     }
0072     iterator& operator++() {
0073       ++iter_;
0074       return *this;
0075     }
0076     iterator& operator--() {
0077       --iter_;
0078       return *this;
0079     }
0080     iterator& operator+=(difference n) {
0081       iter_ += n;
0082       return *this;
0083     }
0084     iterator& operator-=(difference n) {
0085       iter_ -= n;
0086       return *this;
0087     }
0088 
0089     iterator operator++(int) {
0090       iterator it(*this);
0091       ++iter_;
0092       return it;
0093     }
0094     iterator operator--(int) {
0095       iterator it(*this);
0096       --iter_;
0097       return it;
0098     }
0099     iterator operator+(difference n) const {
0100       iterator it(*this);
0101       it.iter_ += n;
0102       return it;
0103     }
0104     iterator operator-(difference n) const {
0105       iterator it(*this);
0106       it.iter_ -= n;
0107       return it;
0108     }
0109 
0110     difference operator-(iterator const& rhs) const { return this->iter_ - rhs.iter_; }
0111 
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     bool operator>(iterator const& rhs) const { return this->iter_ > rhs.iter_; }
0116     bool operator<=(iterator const& rhs) const { return this->iter_ <= rhs.iter_; }
0117     bool operator>=(iterator const& rhs) const { return this->iter_ >= rhs.iter_; }
0118 
0119     key_type key() const {
0120       if (refVector_)
0121         return (*refVector_)[iter_].key();
0122       return (*nestedRefVector_)[iter_].key();
0123     }
0124 
0125   private:
0126     RefVector<C, T, F> const* refVector_;
0127     RefVector<RefVector<C, T, F>, T, typename refhelper::FindTrait<RefVector<C, T, F>, T>::value> const*
0128         nestedRefVector_;
0129     typename RefVector<C, T, F>::size_type iter_;
0130   };
0131 
0132   template <typename C, typename T, typename F>
0133   inline RefVectorIterator<C, T, F> operator+(typename RefVectorIterator<C, T, F>::difference n,
0134                                               RefVectorIterator<C, T, F> const& iter) {
0135     return iter + n;
0136   }
0137 }  // namespace edm
0138 #endif