Blender V5.0
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
8
9#pragma once
10
11#include <array>
12
13#include "BLI_index_range.hh"
15#include "BLI_span.hh"
16#include "BLI_utility_mixins.hh"
17
18namespace blender {
19
29template<typename T> class IndexRangesBuilder : NonCopyable, NonMovable {
30 private:
32 T *c_;
34 MutableSpan<T> data_;
35
36 public:
38 {
39 static_assert(std::is_signed_v<T>);
40 /* Set the first value to -1 so that when the first index is added, it is detected as the start
41 * of a new range. */
42 data_[0] = -1;
43 c_ = data_.data();
44 }
45
47 bool add(const T index)
48 {
49 return this->add_range(index, index + 1);
50 }
51
56 bool add_range(const T start, const T end)
57 {
58 /* Indices have to be added in ascending order. */
59 BLI_assert(start >= *c_);
60 BLI_assert(start >= 0);
61 BLI_assert(start < end);
62
63 const bool is_new_range = start > *c_;
64
65 /* Check that the capacity is not overflown. */
66 BLI_assert(!is_new_range || this->size() < this->capacity());
67
68 /* This is designed to either append to the last range or start a new range.
69 * It is intentionally branchless for more predictable performance on unpredictable data. */
70 c_ += is_new_range;
71 *c_ = start;
72 c_ += is_new_range;
73 *c_ = end;
74
75 return is_new_range;
76 }
77
79 int64_t size() const
80 {
81 return (c_ - data_.data()) / 2;
82 }
83
86 {
87 return data_.size() / 2;
88 }
89
91 bool is_empty() const
92 {
93 return c_ == data_.data();
94 }
95
97 {
98 return IndexRange(this->size());
99 }
100
103 {
104 const T start = data_[size_t(1) + 2 * size_t(i)];
105 const T end = data_[size_t(2) + 2 * size_t(i)];
106 return IndexRange::from_begin_end(start, end);
107 }
108
109 static constexpr int64_t buffer_size_for_ranges_num(const int64_t ranges_num)
110 {
111 /* Two values for each range (start, end) and the dummy prefix value. */
112 return ranges_num * 2 + 1;
113 }
114};
115
116template<typename T, int64_t MaxRangesNum> struct IndexRangesBuilderBuffer {
117 std::array<T, size_t(IndexRangesBuilder<T>::buffer_size_for_ranges_num(MaxRangesNum))> data;
118
119 operator MutableSpan<T>()
120 {
121 return this->data;
122 }
123};
124
125} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:46
BMesh const char void * data
long long int int64_t
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
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
#define T
std::array< T, size_t(IndexRangesBuilder< T >::buffer_size_for_ranges_num(MaxRangesNum))> data
i
Definition text_draw.cc:230