Spicy
node-range.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <memory>
6 #include <set>
7 #include <vector>
8 
9 #include <hilti/ast/forward.h>
10 
11 namespace hilti::node {
12 
16 template<typename T>
17 using Set = NodeVector<T>;
18 
24 template<typename T>
26  using BaseIterator = Nodes::const_iterator;
27 
28 public:
29  using value_type = T*;
30  using difference_type = BaseIterator::difference_type;
31  using pointer = BaseIterator::pointer;
32  using reference = BaseIterator::reference;
33  using iterator_category = BaseIterator::iterator_category;
34 
35  explicit RangeIterator(BaseIterator i) : _iter(i) {}
36  RangeIterator(const RangeIterator& other) = default;
37  RangeIterator(RangeIterator&& other) noexcept = default;
38  RangeIterator() {}
39  ~RangeIterator() = default;
40 
41  const auto& node() const { return *_iter; }
42 
43  RangeIterator& operator=(const RangeIterator& other) = default;
44  RangeIterator& operator=(RangeIterator&& other) noexcept = default;
45  T* operator*() const { return _value(); }
46  // T operator->() const { return &value(); }
47  bool operator==(const RangeIterator& other) const { return _iter == other._iter; }
48  bool operator!=(const RangeIterator& other) const { return ! (*this == other); }
49 
50  auto operator++(int) {
51  auto x = RangeIterator(_iter);
52  ++_iter;
53  return x;
54  }
55 
56  auto& operator++() {
57  ++_iter;
58  return *this;
59  }
60 
61  auto& operator+=(difference_type i) {
62  _iter += i;
63  return *this;
64  }
65 
66  auto& operator-=(difference_type i) {
67  _iter -= i;
68  return *this;
69  }
70 
71  difference_type operator-(const RangeIterator& other) const { return _iter - other._iter; }
72  auto operator-(difference_type i) const { return RangeIterator(_iter - i); }
73  auto operator+(difference_type i) const { return RangeIterator(_iter + i); }
74 
75 private:
76  T* _value() const {
77  if ( *_iter )
78  return static_cast<T*>(*_iter);
79  else
80  return nullptr;
81  }
82 
83  BaseIterator _iter;
84 };
85 
91 template<typename T>
92 class Range {
93 public:
94  using iterator = RangeIterator<T>;
96  using value_type = typename iterator::value_type;
97 
98  explicit Range() {}
99  Range(typename NodeVector<T>::const_iterator begin, typename NodeVector<T>::const_iterator end)
100  : _begin(begin), _end(end) {}
101 
102  explicit Range(const NodeVector<T>& nodes) : Range(nodes.begin(), nodes.end()) {}
103 
104  Range(Nodes::const_iterator begin, Nodes::const_iterator end) : _begin(begin), _end(end) {}
105 
106  Range(const Range& other) = default;
107  Range(Range&& other) noexcept = default;
108  ~Range() = default;
109 
110  auto begin() const { return const_iterator(_begin); }
111  auto end() const { return const_iterator(_end); }
112  size_t size() const { return static_cast<size_t>(_end - _begin); }
113  T* front() const { return *_begin; }
114  bool empty() const { return _begin == _end; }
115 
116  operator NodeVector<T>() const {
117  NodeVector<T> x;
118  x.reserve(size());
119  for ( auto i = _begin; i != _end; i++ )
120  x.push_back(*i);
121 
122  return x;
123  }
124 
125  T* operator[](size_t i) const {
126  assert(static_cast<typename RangeIterator<T>::difference_type>(i) < std::distance(_begin, _end));
127  return *(_begin + i);
128  }
129 
130  bool operator==(const Range& other) const {
131  if ( this == &other )
132  return true;
133 
134  if ( size() != other.size() )
135  return false;
136 
137  auto x = _begin;
138  auto y = other._begin;
139  while ( x != _end ) {
140  if ( ! (*x++ == *y++) )
141  return false;
142  }
143 
144  return true;
145  }
146 
147  Range& operator=(const Range& other) = default;
148  Range& operator=(Range&& other) noexcept = default;
149 
150 private:
151  RangeIterator<T> _begin;
152  RangeIterator<T> _end;
153 };
154 
155 } // namespace hilti::node
Definition: node-range.h:92
Definition: node-range.h:25