Coverage Report

Created: 2026-05-30 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cppitertools/cppitertools/cycle.hpp
Line
Count
Source
1
#ifndef ITER_CYCLE_H_
2
#define ITER_CYCLE_H_
3
4
#include "internal/iterator_wrapper.hpp"
5
#include "internal/iterbase.hpp"
6
7
#include <initializer_list>
8
#include <iterator>
9
#include <utility>
10
11
namespace iter {
12
  namespace impl {
13
    template <typename Container>
14
    class Cycler;
15
16
    using CycleFn = IterToolFn<Cycler>;
17
  }
18
  inline constexpr impl::CycleFn cycle{};
19
}
20
21
template <typename Container>
22
class iter::impl::Cycler {
23
 private:
24
  friend CycleFn;
25
26
  Container container_;
27
28
  Cycler(Container&& container)
29
593
      : container_(std::forward<Container>(container)) {}
30
31
 public:
32
  Cycler(Cycler&&) = default;
33
  template <typename ContainerT>
34
  class Iterator {
35
   private:
36
    template <typename>
37
    friend class Iterator;
38
    IteratorWrapper<ContainerT> sub_iter_;
39
    IteratorWrapper<ContainerT> sub_begin_;
40
    IteratorWrapper<ContainerT> sub_end_;
41
42
   public:
43
    using iterator_category = std::input_iterator_tag;
44
    using value_type = iterator_traits_deref<ContainerT>;
45
    using difference_type = std::ptrdiff_t;
46
    using pointer = value_type*;
47
    using reference = value_type&;
48
49
    Iterator(IteratorWrapper<ContainerT>&& sub_iter,
50
        IteratorWrapper<ContainerT>&& sub_end)
51
1.18k
        : sub_iter_{sub_iter},
52
1.18k
          sub_begin_{sub_iter},
53
1.18k
          sub_end_{std::move(sub_end)} {}
54
55
890k
    iterator_deref<ContainerT> operator*() {
56
890k
      return *sub_iter_;
57
890k
    }
58
59
    iterator_arrow<ContainerT> operator->() {
60
      return apply_arrow(sub_iter_);
61
    }
62
63
889k
    Iterator& operator++() {
64
889k
      ++sub_iter_;
65
      // reset to beginning upon reaching the sub_end_
66
889k
      if (!(sub_iter_ != sub_end_)) {
67
265k
        sub_iter_ = sub_begin_;
68
265k
      }
69
889k
      return *this;
70
889k
    }
71
72
    Iterator operator++(int) {
73
      auto ret = *this;
74
      ++*this;
75
      return ret;
76
    }
77
78
    template <typename T>
79
890k
    bool operator!=(const Iterator<T>& other) const {
80
890k
      return sub_iter_ != other.sub_iter_;
81
890k
    }
82
83
    template <typename T>
84
    bool operator==(const Iterator<T>& other) const {
85
      return !(*this != other);
86
    }
87
  };
88
89
593
  Iterator<Container> begin() {
90
593
    return {get_begin(container_), get_end(container_)};
91
593
  }
92
93
593
  Iterator<Container> end() {
94
593
    return {get_end(container_), get_end(container_)};
95
593
  }
96
97
  Iterator<AsConst<Container>> begin() const {
98
    return {get_begin(std::as_const(container_)),
99
        get_end(std::as_const(container_))};
100
  }
101
102
  Iterator<AsConst<Container>> end() const {
103
    return {get_end(std::as_const(container_)),
104
        get_end(std::as_const(container_))};
105
  }
106
};
107
108
#endif