Blender V4.3
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
5#pragma once
6
7#include <algorithm>
8#include <optional>
9
10#include "BLI_index_mask_fwd.hh"
11#include "BLI_index_range.hh"
12#include "BLI_span.hh"
13
15
17struct NoSortCheck {};
18
29template<typename T> class OffsetIndices {
30 private:
31 static_assert(std::is_integral_v<T>);
32
33 Span<T> offsets_;
34
35 public:
36 OffsetIndices() = default;
37 OffsetIndices(const Span<T> offsets) : offsets_(offsets)
38 {
39 BLI_assert(offsets_.size() < 2 || std::is_sorted(offsets_.begin(), offsets_.end()));
40 }
41
47 OffsetIndices(const Span<T> offsets, NoSortCheck) : offsets_(offsets) {}
48
50 T total_size() const
51 {
52 return offsets_.size() > 1 ? offsets_.last() - offsets_.first() : 0;
53 }
54
59 int64_t size() const
60 {
61 return std::max<int64_t>(offsets_.size() - 1, 0);
62 }
63
64 bool is_empty() const
65 {
66 return this->size() == 0;
67 }
68
70 {
71 return IndexRange(this->size());
72 }
73
74 IndexRange operator[](const int64_t index) const
75 {
76 BLI_assert(index >= 0);
77 BLI_assert(index < offsets_.size() - 1);
78 const int64_t begin = offsets_[index];
79 const int64_t end = offsets_[index + 1];
80 return IndexRange::from_begin_end(begin, end);
81 }
82
83 IndexRange operator[](const IndexRange indices) const
84 {
85 const int64_t begin = offsets_[indices.start()];
86 const int64_t end = offsets_[indices.one_after_last()];
87 return IndexRange::from_begin_end(begin, end);
88 }
89
95 OffsetIndices slice(const IndexRange range) const
96 {
97 BLI_assert(range.is_empty() || offsets_.index_range().drop_back(1).contains(range.last()));
98 return OffsetIndices(offsets_.slice(range.start(), range.size() + 1));
99 }
100
101 Span<T> data() const
102 {
103 return offsets_;
104 }
105};
106
115template<typename T> struct GroupedSpan {
118
119 GroupedSpan() = default;
121 {
122 BLI_assert(this->offsets.total_size() == this->data.size());
123 }
124
125 Span<T> operator[](const int64_t index) const
126 {
127 return this->data.slice(this->offsets[index]);
128 }
129
130 int64_t size() const
131 {
132 return this->offsets.size();
133 }
134
136 {
137 return this->offsets.index_range();
138 }
139
140 bool is_empty() const
141 {
142 return this->data.size() == 0;
143 }
144};
145
150 int start_offset = 0);
151
152std::optional<OffsetIndices<int>> accumulate_counts_to_offsets_with_overflow_check(
153 MutableSpan<int> counts_to_offsets, int start_offset = 0);
154
156void fill_constant_group_size(int size, int start_offset, MutableSpan<int> offsets);
157
159void copy_group_sizes(OffsetIndices<int> offsets, const IndexMask &mask, MutableSpan<int> sizes);
160
162void gather_group_sizes(OffsetIndices<int> offsets, const IndexMask &mask, MutableSpan<int> sizes);
164
166int sum_group_sizes(OffsetIndices<int> offsets, const IndexMask &mask);
167int sum_group_sizes(OffsetIndices<int> offsets, Span<int> indices);
168
171 const IndexMask &selection,
172 int start_offset,
173 MutableSpan<int> dst_offsets);
175 const IndexMask &selection,
176 MutableSpan<int> dst_offsets)
177{
178 return gather_selected_offsets(src_offsets, selection, 0, dst_offsets);
179}
185
190
191} // namespace blender::offset_indices
192
193namespace blender {
194using offset_indices::GroupedSpan;
195using offset_indices::OffsetIndices;
196} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:50
constexpr IndexRange drop_back(int64_t n) const
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
constexpr bool contains(int64_t value) const
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:138
constexpr const T & first() const
Definition BLI_span.hh:316
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr const T & last(const int64_t n=0) const
Definition BLI_span.hh:326
constexpr const T * end() const
Definition BLI_span.hh:225
constexpr IndexRange index_range() const
Definition BLI_span.hh:402
constexpr const T * begin() const
Definition BLI_span.hh:221
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
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)
__int64 int64_t
Definition stdint.h:89
GroupedSpan(OffsetIndices< int > offsets, Span< T > data)
Span< T > operator[](const int64_t index) const