Blender V4.3
BLI_index_range.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
40#include <algorithm>
41#include <iosfwd>
42
43#include "BLI_assert.h"
45
46namespace blender {
47
48template<typename T> class Span;
49
51 private:
52 int64_t start_ = 0;
53 int64_t size_ = 0;
54
55 public:
56 constexpr IndexRange() = default;
57
58 constexpr explicit IndexRange(int64_t size) : start_(0), size_(size)
59 {
60 BLI_assert(size >= 0);
61 }
62
63 constexpr IndexRange(const int64_t start, const int64_t size) : start_(start), size_(size)
64 {
65 BLI_assert(start >= 0);
66 BLI_assert(size >= 0);
67 }
68
69 constexpr static IndexRange from_begin_size(const int64_t begin, const int64_t size)
70 {
71 return IndexRange(begin, size);
72 }
73
74 constexpr static IndexRange from_begin_end(const int64_t begin, const int64_t end)
75 {
76 return IndexRange(begin, end - begin);
77 }
78
80 {
81 return IndexRange(begin, last - begin + 1);
82 }
83
84 constexpr static IndexRange from_end_size(const int64_t end, const int64_t size)
85 {
86 return IndexRange(end - size, size);
87 }
88
89 constexpr static IndexRange from_single(const int64_t index)
90 {
91 return IndexRange(index, 1);
92 }
93
95 public:
97 using pointer = const int64_t *;
99
100 private:
101 int64_t current_;
102
103 public:
104 constexpr explicit Iterator(int64_t current) : current_(current) {}
105
106 constexpr int64_t operator*() const
107 {
108 return current_;
109 }
110
111 const int64_t &iter_prop() const
112 {
113 return current_;
114 }
115 };
116
117 constexpr Iterator begin() const
118 {
119 return Iterator(start_);
120 }
121
122 constexpr Iterator end() const
123 {
124 return Iterator(start_ + size_);
125 }
126
130 constexpr int64_t operator[](int64_t index) const
131 {
132 BLI_assert(index >= 0);
133 BLI_assert(index < this->size());
134 return start_ + index;
135 }
136
140 constexpr friend bool operator==(IndexRange a, IndexRange b)
141 {
142 return (a.size_ == b.size_) && (a.start_ == b.start_ || a.size_ == 0);
143 }
144 constexpr friend bool operator!=(IndexRange a, IndexRange b)
145 {
146 return !(a == b);
147 }
148
152 constexpr int64_t size() const
153 {
154 return size_;
155 }
156
157 constexpr IndexRange index_range() const
158 {
159 return IndexRange(size_);
160 }
161
165 constexpr bool is_empty() const
166 {
167 return size_ == 0;
168 }
169
173 constexpr IndexRange with_new_end(const int64_t new_end) const
174 {
175 return IndexRange::from_begin_end(start_, new_end);
176 }
177
181 constexpr IndexRange after(int64_t n) const
182 {
183 BLI_assert(n >= 0);
184 return IndexRange(start_ + size_, n);
185 }
186
190 constexpr IndexRange before(int64_t n) const
191 {
192 BLI_assert(n >= 0);
193 return IndexRange(start_ - n, n);
194 }
195
200 constexpr int64_t first() const
201 {
202 BLI_assert(this->size() > 0);
203 return start_;
204 }
205
210 constexpr int64_t last(const int64_t n = 0) const
211 {
212 BLI_assert(n >= 0);
213 BLI_assert(n < size_);
214 BLI_assert(this->size() > 0);
215 return start_ + size_ - 1 - n;
216 }
217
222 constexpr int64_t one_before_start() const
223 {
224 BLI_assert(start_ > 0);
225 return start_ - 1;
226 }
227
231 constexpr int64_t one_after_last() const
232 {
233 return start_ + size_;
234 }
235
239 constexpr int64_t start() const
240 {
241 return start_;
242 }
243
247 constexpr bool contains(int64_t value) const
248 {
249 return value >= start_ && value < start_ + size_;
250 }
251
255 constexpr bool contains(const IndexRange range) const
256 {
257 if (range.is_empty()) {
258 return true;
259 }
260 if (range.start_ < start_) {
261 return false;
262 }
263 if (range.start_ + range.size_ > start_ + size_) {
264 return false;
265 }
266 return true;
267 }
268
272 constexpr IndexRange slice(int64_t start, int64_t size) const
273 {
274 BLI_assert(start >= 0);
275 BLI_assert(size >= 0);
276 int64_t new_start = start_ + start;
277 BLI_assert(new_start + size <= start_ + size_ || size == 0);
278 return IndexRange(new_start, size);
279 }
280 constexpr IndexRange slice(IndexRange range) const
281 {
282 return this->slice(range.start(), range.size());
283 }
284
290 constexpr IndexRange intersect(IndexRange other) const
291 {
292 const int64_t old_end = start_ + size_;
293 const int64_t new_start = std::min(old_end, std::max(start_, other.start_));
294 const int64_t new_end = std::max(new_start, std::min(old_end, other.start_ + other.size_));
295 return IndexRange(new_start, new_end - new_start);
296 }
297
302 constexpr IndexRange drop_front(int64_t n) const
303 {
304 BLI_assert(n >= 0);
305 const int64_t new_size = std::max<int64_t>(0, size_ - n);
306 return IndexRange(start_ + n, new_size);
307 }
308
313 constexpr IndexRange drop_back(int64_t n) const
314 {
315 BLI_assert(n >= 0);
316 const int64_t new_size = std::max<int64_t>(0, size_ - n);
317 return IndexRange(start_, new_size);
318 }
319
324 constexpr IndexRange take_front(int64_t n) const
325 {
326 BLI_assert(n >= 0);
327 const int64_t new_size = std::min<int64_t>(size_, n);
328 return IndexRange(start_, new_size);
329 }
330
335 constexpr IndexRange take_back(int64_t n) const
336 {
337 BLI_assert(n >= 0);
338 const int64_t new_size = std::min<int64_t>(size_, n);
339 return IndexRange(start_ + size_ - new_size, new_size);
340 }
341
346 constexpr IndexRange shift(int64_t n) const
347 {
348 return IndexRange(start_ + n, size_);
349 }
350
351 friend std::ostream &operator<<(std::ostream &stream, IndexRange range);
352};
353
359
368
369} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:50
constexpr Iterator(int64_t current)
const int64_t & iter_prop() const
constexpr int64_t operator*() const
constexpr int64_t one_before_start() const
constexpr int64_t first() const
constexpr friend bool operator!=(IndexRange a, IndexRange b)
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
constexpr Iterator end() const
constexpr IndexRange intersect(IndexRange other) const
constexpr IndexRange drop_back(int64_t n) const
constexpr IndexRange(const int64_t start, const int64_t size)
static constexpr IndexRange from_end_size(const int64_t end, const int64_t size)
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool is_empty() const
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
constexpr IndexRange with_new_end(const int64_t new_end) const
constexpr IndexRange()=default
static constexpr IndexRange from_begin_size(const int64_t begin, const int64_t size)
constexpr IndexRange after(int64_t n) const
constexpr int64_t start() const
constexpr bool contains(const IndexRange range) const
constexpr IndexRange before(int64_t n) const
constexpr IndexRange take_back(int64_t n) const
friend std::ostream & operator<<(std::ostream &stream, IndexRange range)
constexpr Iterator begin() const
static constexpr IndexRange from_single(const int64_t index)
constexpr IndexRange(int64_t size)
constexpr IndexRange slice(int64_t start, int64_t size) const
constexpr bool contains(int64_t value) const
constexpr IndexRange index_range() const
constexpr IndexRange take_front(int64_t n) const
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
constexpr IndexRange drop_front(int64_t n) const
local_group_size(16, 16) .push_constant(Type b
AlignedIndexRanges split_index_range_by_alignment(const IndexRange range, const int64_t alignment)
__int64 int64_t
Definition stdint.h:89