Blender  V3.3
BLI_index_range.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
41 #include <algorithm>
42 #include <atomic>
43 #include <cmath>
44 #include <iostream>
45 
46 #include "BLI_utildefines.h"
47 
48 namespace blender {
49 
50 template<typename T> class Span;
51 
52 class IndexRange {
53  private:
54  int64_t start_ = 0;
55  int64_t size_ = 0;
56 
57  public:
58  constexpr IndexRange() = default;
59 
60  constexpr explicit IndexRange(int64_t size) : start_(0), size_(size)
61  {
62  BLI_assert(size >= 0);
63  }
64 
65  constexpr IndexRange(int64_t start, int64_t size) : start_(start), size_(size)
66  {
67  BLI_assert(start >= 0);
68  BLI_assert(size >= 0);
69  }
70 
71  class Iterator {
72  public:
73  using iterator_category = std::forward_iterator_tag;
75  using pointer = const int64_t *;
76  using reference = const int64_t &;
77  using difference_type = std::ptrdiff_t;
78 
79  private:
80  int64_t current_;
81 
82  public:
83  constexpr explicit Iterator(int64_t current) : current_(current)
84  {
85  }
86 
87  constexpr Iterator &operator++()
88  {
89  current_++;
90  return *this;
91  }
92 
93  constexpr Iterator operator++(int) const
94  {
95  Iterator copied_iterator = *this;
96  ++copied_iterator;
97  return copied_iterator;
98  }
99 
100  constexpr friend bool operator!=(const Iterator &a, const Iterator &b)
101  {
102  return a.current_ != b.current_;
103  }
104 
105  constexpr friend bool operator==(const Iterator &a, const Iterator &b)
106  {
107  return a.current_ == b.current_;
108  }
109 
110  constexpr int64_t operator*() const
111  {
112  return current_;
113  }
114  };
115 
116  constexpr Iterator begin() const
117  {
118  return Iterator(start_);
119  }
120 
121  constexpr Iterator end() const
122  {
123  return Iterator(start_ + size_);
124  }
125 
129  constexpr int64_t operator[](int64_t index) const
130  {
131  BLI_assert(index >= 0);
132  BLI_assert(index < this->size());
133  return start_ + index;
134  }
135 
139  constexpr friend bool operator==(IndexRange a, IndexRange b)
140  {
141  return (a.size_ == b.size_) && (a.start_ == b.start_ || a.size_ == 0);
142  }
143 
147  constexpr int64_t size() const
148  {
149  return size_;
150  }
151 
155  constexpr bool is_empty() const
156  {
157  return size_ == 0;
158  }
159 
163  constexpr IndexRange after(int64_t n) const
164  {
165  BLI_assert(n >= 0);
166  return IndexRange(start_ + size_, n);
167  }
168 
172  constexpr IndexRange before(int64_t n) const
173  {
174  BLI_assert(n >= 0);
175  return IndexRange(start_ - n, n);
176  }
177 
182  constexpr int64_t first() const
183  {
184  BLI_assert(this->size() > 0);
185  return start_;
186  }
187 
192  constexpr int64_t last(const int64_t n = 0) const
193  {
194  BLI_assert(n >= 0);
195  BLI_assert(n < size_);
196  BLI_assert(this->size() > 0);
197  return start_ + size_ - 1 - n;
198  }
199 
204  constexpr int64_t one_before_start() const
205  {
206  BLI_assert(start_ > 0);
207  return start_ - 1;
208  }
209 
213  constexpr int64_t one_after_last() const
214  {
215  return start_ + size_;
216  }
217 
221  constexpr int64_t start() const
222  {
223  return start_;
224  }
225 
229  constexpr bool contains(int64_t value) const
230  {
231  return value >= start_ && value < start_ + size_;
232  }
233 
238  {
239  BLI_assert(start >= 0);
240  BLI_assert(size >= 0);
241  int64_t new_start = start_ + start;
242  BLI_assert(new_start + size <= start_ + size_ || size == 0);
243  return IndexRange(new_start, size);
244  }
245  constexpr IndexRange slice(IndexRange range) const
246  {
247  return this->slice(range.start(), range.size());
248  }
249 
254  constexpr IndexRange drop_front(int64_t n) const
255  {
256  BLI_assert(n >= 0);
257  const int64_t new_size = std::max<int64_t>(0, size_ - n);
258  return IndexRange(start_ + n, new_size);
259  }
260 
265  constexpr IndexRange drop_back(int64_t n) const
266  {
267  BLI_assert(n >= 0);
268  const int64_t new_size = std::max<int64_t>(0, size_ - n);
269  return IndexRange(start_, new_size);
270  }
271 
276  constexpr IndexRange take_front(int64_t n) const
277  {
278  BLI_assert(n >= 0);
279  const int64_t new_size = std::min<int64_t>(size_, n);
280  return IndexRange(start_, new_size);
281  }
282 
287  constexpr IndexRange take_back(int64_t n) const
288  {
289  BLI_assert(n >= 0);
290  const int64_t new_size = std::min<int64_t>(size_, n);
291  return IndexRange(start_ + size_ - new_size, new_size);
292  }
293 
298  constexpr IndexRange shift(int64_t n) const
299  {
300  return IndexRange(start_ + n, size_);
301  }
302 
306  Span<int64_t> as_span() const;
307 
308  friend std::ostream &operator<<(std::ostream &stream, IndexRange range)
309  {
310  stream << "[" << range.start() << ", " << range.one_after_last() << ")";
311  return stream;
312  }
313 
314  private:
315  static std::atomic<int64_t> s_current_array_size;
316  static std::atomic<int64_t *> s_current_array;
317 
318  Span<int64_t> as_span_internal() const;
319 };
320 
321 } // namespace blender
#define BLI_assert(a)
Definition: BLI_assert.h:46
constexpr friend bool operator!=(const Iterator &a, const Iterator &b)
constexpr Iterator(int64_t current)
std::forward_iterator_tag iterator_category
constexpr int64_t operator*() const
constexpr friend bool operator==(const Iterator &a, const Iterator &b)
constexpr Iterator operator++(int) const
constexpr Iterator & operator++()
constexpr int64_t one_before_start() const
constexpr int64_t first() const
constexpr int64_t one_after_last() const
constexpr IndexRange slice(IndexRange range) const
constexpr friend bool operator==(IndexRange a, IndexRange b)
constexpr int64_t operator[](int64_t index) const
constexpr IndexRange shift(int64_t n) const
Span< int64_t > as_span() const
Definition: BLI_span.hh:726
constexpr Iterator end() const
constexpr IndexRange drop_back(int64_t n) const
friend std::ostream & operator<<(std::ostream &stream, IndexRange range)
constexpr int64_t last(const int64_t n=0) const
constexpr IndexRange(int64_t start, int64_t size)
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr IndexRange()=default
constexpr IndexRange after(int64_t n) const
constexpr int64_t start() const
constexpr IndexRange before(int64_t n) const
constexpr IndexRange take_back(int64_t n) const
constexpr Iterator begin() const
constexpr IndexRange(int64_t size)
constexpr IndexRange slice(int64_t start, int64_t size) const
constexpr bool contains(int64_t value) const
constexpr IndexRange take_front(int64_t n) const
constexpr IndexRange drop_front(int64_t n) const
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
__int64 int64_t
Definition: stdint.h:89