Blender V4.3
BLI_index_ranges_builder.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
7#include <array>
8
9#include "BLI_index_range.hh"
11#include "BLI_span.hh"
12#include "BLI_utility_mixins.hh"
13
14namespace blender {
15
25template<typename T> class IndexRangesBuilder : NonCopyable, NonMovable {
26 private:
28 T *c_;
30 MutableSpan<T> data_;
31
32 public:
34 {
35 static_assert(std::is_signed_v<T>);
36 /* Set the first value to -1 so that when the first index is added, it is detected as the start
37 * of a new range. */
38 data_[0] = -1;
39 c_ = data_.data();
40 }
41
43 bool add(const T index)
44 {
45 return this->add_range(index, index + 1);
46 }
47
52 bool add_range(const T start, const T end)
53 {
54 /* Indices have to be added in ascending order. */
55 BLI_assert(start >= *c_);
56 BLI_assert(start >= 0);
57 BLI_assert(start < end);
58
59 const bool is_new_range = start > *c_;
60
61 /* Check that the capacity is not overflown. */
62 BLI_assert(!is_new_range || this->size() < this->capacity());
63
64 /* This is designed to either append to the last range or start a new range.
65 * It is intentionally branchless for more predictable performance on unpredictable data. */
66 c_ += is_new_range;
67 *c_ = start;
68 c_ += is_new_range;
69 *c_ = end;
70
71 return is_new_range;
72 }
73
75 int64_t size() const
76 {
77 return (c_ - data_.data()) / 2;
78 }
79
82 {
83 return data_.size() / 2;
84 }
85
87 bool is_empty() const
88 {
89 return c_ == data_.data();
90 }
91
93 {
94 return IndexRange(this->size());
95 }
96
99 {
100 const T start = data_[size_t(1) + 2 * size_t(i)];
101 const T end = data_[size_t(2) + 2 * size_t(i)];
102 return IndexRange::from_begin_end(start, end);
103 }
104
105 static constexpr int64_t buffer_size_for_ranges_num(const int64_t ranges_num)
106 {
107 /* Two values for each range (start, end) and the dummy prefix value. */
108 return ranges_num * 2 + 1;
109 }
110};
111
112template<typename T, int64_t MaxRangesNum> struct IndexRangesBuilderBuffer {
113 std::array<T, size_t(IndexRangesBuilder<T>::buffer_size_for_ranges_num(MaxRangesNum))> data;
114
115 operator MutableSpan<T>()
116 {
117 return this->data;
118 }
119};
120
121} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:50
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
bool add_range(const T start, const T end)
static constexpr int64_t buffer_size_for_ranges_num(const int64_t ranges_num)
IndexRangesBuilder(MutableSpan< T > data)
IndexRange operator[](const int64_t i) const
#define T
__int64 int64_t
Definition stdint.h:89
std::array< T, size_t(IndexRangesBuilder< T >::buffer_size_for_ranges_num(MaxRangesNum))> data