Blender V5.0
BLI_offset_indices.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
8
9#pragma once
10
11#include <algorithm>
12#include <optional>
13
14#include "BLI_index_mask_fwd.hh"
15#include "BLI_index_range.hh"
16#include "BLI_span.hh"
17
19
21struct NoSortCheck {};
22
34template<typename T> class OffsetIndices {
35 private:
36 static_assert(std::is_integral_v<T>);
37
38 Span<T> offsets_;
39
40 public:
41 OffsetIndices() = default;
42 OffsetIndices(const Span<T> offsets) : offsets_(offsets)
43 {
44 BLI_assert(offsets_.size() < 2 || std::is_sorted(offsets_.begin(), offsets_.end()));
45 }
46
52 OffsetIndices(const Span<T> offsets, NoSortCheck /*no_sort_check*/) : offsets_(offsets) {}
53
55 T total_size() const
56 {
57 return offsets_.size() > 1 ? offsets_.last() - offsets_.first() : 0;
58 }
59
64 int64_t size() const
65 {
66 return std::max<int64_t>(offsets_.size() - 1, 0);
67 }
68
69 bool is_empty() const
70 {
71 return this->size() == 0;
72 }
73
75 {
76 return IndexRange(this->size());
77 }
78
79 IndexRange operator[](const int64_t index) const
80 {
81 BLI_assert(index >= 0);
82 BLI_assert(index < offsets_.size() - 1);
83 const int64_t begin = offsets_[index];
84 const int64_t end = offsets_[index + 1];
86 }
87
89 {
90 const int64_t begin = offsets_[indices.start()];
91 const int64_t end = offsets_[indices.one_after_last()];
93 }
94
100 OffsetIndices slice(const IndexRange range) const
101 {
102 BLI_assert(range.is_empty() || offsets_.index_range().drop_back(1).contains(range.last()));
103 return OffsetIndices(offsets_.slice(range.start(), range.size() + 1));
104 }
105
106 Span<T> data() const
107 {
108 return offsets_;
109 }
110};
111
120template<typename T> struct GroupedSpan {
123
124 GroupedSpan() = default;
126 {
127 BLI_assert(this->offsets.total_size() == this->data.size());
128 }
129
130 Span<T> operator[](const int64_t index) const
131 {
132 return this->data.slice(this->offsets[index]);
133 }
134
135 int64_t size() const
136 {
137 return this->offsets.size();
138 }
139
141 {
142 return this->offsets.index_range();
143 }
144
145 bool is_empty() const
146 {
147 return this->data.size() == 0;
148 }
149};
150
155 int start_offset = 0);
156
157std::optional<OffsetIndices<int>> accumulate_counts_to_offsets_with_overflow_check(
158 MutableSpan<int> counts_to_offsets, int start_offset = 0);
159
161void fill_constant_group_size(int size, int start_offset, MutableSpan<int> offsets);
162
165
169
173
176 const IndexMask &selection,
177 int start_offset,
178 MutableSpan<int> dst_offsets);
180 const IndexMask &selection,
181 MutableSpan<int> dst_offsets)
182{
183 return gather_selected_offsets(src_offsets, selection, 0, dst_offsets);
184}
185
191
196
197} // namespace blender::offset_indices
198
199namespace blender {
200using offset_indices::GroupedSpan;
201using offset_indices::OffsetIndices;
202} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:46
iter begin(iter)
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
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 int64_t start() const
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:137
constexpr int64_t size() const
Definition BLI_span.hh:252
OffsetIndices(const Span< T > offsets, NoSortCheck)
IndexRange operator[](const int64_t index) const
OffsetIndices slice(const IndexRange range) const
IndexRange operator[](const IndexRange indices) const
static ushort indices[]
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
#define T
void copy_group_sizes(OffsetIndices< int > offsets, const IndexMask &mask, MutableSpan< int > sizes)
void build_reverse_map(OffsetIndices< int > offsets, MutableSpan< int > r_map)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
std::optional< OffsetIndices< int > > accumulate_counts_to_offsets_with_overflow_check(MutableSpan< int > counts_to_offsets, int start_offset=0)
void gather_group_sizes(OffsetIndices< int > offsets, const IndexMask &mask, MutableSpan< int > sizes)
void fill_constant_group_size(int size, int start_offset, MutableSpan< int > offsets)
void build_reverse_offsets(Span< int > indices, MutableSpan< int > offsets)
int sum_group_sizes(OffsetIndices< int > offsets, const IndexMask &mask)
OffsetIndices< int > gather_selected_offsets(OffsetIndices< int > src_offsets, const IndexMask &selection, int start_offset, MutableSpan< int > dst_offsets)
GroupedSpan(OffsetIndices< int > offsets, Span< T > data)
Span< T > operator[](const int64_t index) const