| 17 | |
| 18 | template <typename Histogram> |
| 19 | class iterator_over |
| 20 | : public iterator_facade<iterator_over<Histogram>, typename Histogram::element_type, |
| 21 | random_access_traversal_tag, |
| 22 | typename Histogram::const_reference> { |
| 23 | public: |
| 24 | iterator_over(const Histogram& h, std::size_t idx) : histogram_(h), idx_(idx) {} |
| 25 | |
| 26 | iterator_over(const iterator_over& o) : histogram_(o.histogram_), idx_(o.idx_) {} |
| 27 | |
| 28 | iterator_over& operator=(const iterator_over& o) { |
| 29 | histogram_ = o.histogram_; |
| 30 | idx_ = o.idx_; |
| 31 | cache_.reset(); |
| 32 | } |
| 33 | |
| 34 | std::size_t dim() const noexcept { return histogram_.dim(); } |
| 35 | |
| 36 | int idx(std::size_t dim = 0) const noexcept { |
| 37 | if (!cache_) { cache_.set(histogram_); } |
| 38 | cache_.set_idx(idx_); |
| 39 | return cache_.get(dim); |
| 40 | } |
| 41 | |
| 42 | auto bin() const -> decltype(std::declval<Histogram&>().axis()[0]) { |
| 43 | return histogram_.axis()[idx()]; |
| 44 | } |
| 45 | |
| 46 | template <std::size_t I> |
| 47 | auto bin(mp11::mp_size_t<I>) const |
| 48 | -> decltype(std::declval<Histogram&>().axis(mp11::mp_size_t<I>())[0]) { |
| 49 | return histogram_.axis(mp11::mp_size_t<I>())[idx(I)]; |
| 50 | } |
| 51 | |
| 52 | template <typename T = Histogram> // use SFINAE for this method |
| 53 | auto bin(std::size_t dim) const -> decltype(std::declval<T&>().axis(dim)[0]) { |
| 54 | return histogram_.axis(dim)[idx(dim)]; |
| 55 | } |
| 56 | |
| 57 | private: |
| 58 | bool equal(const iterator_over& rhs) const noexcept { |
| 59 | return &histogram_ == &rhs.histogram_ && idx_ == rhs.idx_; |
| 60 | } |
| 61 | |
| 62 | void increment() noexcept { ++idx_; } |
| 63 | void decrement() noexcept { --idx_; } |
| 64 | |
| 65 | void advance(int n) noexcept { idx_ += n; } |
| 66 | |
| 67 | typename Histogram::const_reference dereference() const noexcept { |
| 68 | return histogram_.storage_[idx_]; |
| 69 | } |
| 70 | |
| 71 | const Histogram& histogram_; |
| 72 | std::size_t idx_; |
| 73 | mutable detail::index_cache cache_; |
| 74 | friend class ::boost::iterator_core_access; |
| 75 | }; |
| 76 | |