269 template<
typename Fn>
289 template<
typename T,
typename Fn>
292 Fn &&get_group_index,
324 std::optional<RawMaskIterator>
find(
int64_t query_index)
const;
426 template<
typename IndexT,
typename Fn>
486 std::optional<IndexRange>
to_range()
const;
501 template<
int64_t N = 4>
521 const int16_t *segment_indices_;
522 std::array<int64_t, 2> cumulative_segment_sizes_;
533 cumulative_segment_sizes_[0] = 0;
534 data.segments_num_ = 1;
535 data.indices_by_segment_ = &segment_indices_;
536 data.segment_offsets_ = &segment_offset_;
537 data.cumulative_segment_sizes_ = cumulative_segment_sizes_.data();
538 data.begin_index_in_segment_ = 0;
551 segment_offset_ = segment.offset();
552 segment_indices_ =
indices.data();
553 cumulative_segment_sizes_[1] = int16_t(indices_num);
554 data.indices_num_ = indices_num;
555 data.end_index_in_segment_ = indices_num;
570 alignas(64)
static const std::array<int16_t, max_segment_size>
data =
651 static constexpr int64_t cumulative_sizes_for_empty_mask[1] = {0};
653 data.indices_num_ = 0;
654 data.segments_num_ = 0;
655 data.cumulative_segment_sizes_ = cumulative_sizes_for_empty_mask;
743 return this->
last() + 1;
755 [&](
const int64_t cumulative_size) {
return cumulative_size <= full_index; });
796 const int64_t segment_size = end_index - begin_index;
813 std::is_invocable_r_v<void, Fn, IndexMaskSegment, int64_t> ||
814 std::is_invocable_r_v<void, Fn, IndexRange, int64_t>;
820 if constexpr (std::is_invocable_r_v<void, Fn, int64_t, int64_t>) {
837 const IndexMask sub_mask = this->slice(range);
838 sub_mask.foreach_index([&](const int64_t i, [[maybe_unused]] const int64_t index_pos) {
839 if constexpr (std::is_invocable_r_v<void, Fn, int64_t, int64_t>) {
840 fn(i, index_pos + range.start());
849template<
typename T,
typename Fn>
850#if (defined(__GNUC__) && !defined(__clang__))
851[[gnu::optimize(
"O3")]]
855 BLI_assert(segment.last() < std::numeric_limits<T>::max());
857 const T start =
T(segment[0]);
858 const T last =
T(segment.last());
859 for (
T i = start;
i <= last;
i++) {
870template<
typename T,
typename Fn>
871#if (defined(__GNUC__) && !defined(__clang__))
872[[gnu::optimize(
"O3")]]
878 BLI_assert(segment.last() < std::numeric_limits<T>::max());
879 BLI_assert(segment.size() + segment_pos < std::numeric_limits<T>::max());
881 const T start =
T(segment[0]);
882 const T last =
T(segment.last());
883 for (
T i = start,
pos =
T(segment_pos);
i <= last;
i++,
pos++) {
888 T pos =
T(segment_pos);
889 for (
const int64_t i : segment.index_range()) {
890 const T index =
T(segment[
i]);
897template<
typename IndexT,
typename Fn>
902 if constexpr (std::is_invocable_r_v<void, Fn, IndexT, IndexT>) {
911template<
typename IndexT,
typename Fn>
915 const IndexMask sub_mask = this->slice(range);
916 sub_mask.foreach_segment(
917 [&](const IndexMaskSegment segment, [[maybe_unused]] const int64_t segment_pos) {
918 if constexpr (std::is_invocable_r_v<void, Fn, IndexT, IndexT>) {
919 optimized_foreach_index_with_pos<IndexT>(segment, segment_pos + range.start(), fn);
922 optimized_foreach_index<IndexT>(segment, fn);
935 fn(range, start_segment_pos);
956 const IndexMask sub_mask = this->slice(range);
957 sub_mask.foreach_segment_optimized(
958 [&fn, range_start = range.start()](const auto segment,
959 [[maybe_unused]] const int64_t start_segment_pos) {
960 if constexpr (has_segment_and_start_parameter<Fn>) {
961 fn(segment, start_segment_pos + range_start);
972 [[maybe_unused]]
int64_t segment_pos = 0;
989 const IndexMask sub_mask = this->slice(range);
990 sub_mask.foreach_segment(
991 [&fn, range_start = range.start()](const IndexMaskSegment mask_segment,
992 [[maybe_unused]] const int64_t segment_pos) {
993 if constexpr (has_segment_and_start_parameter<Fn>) {
994 fn(mask_segment, segment_pos + range_start);
1011 fn(range, segment_pos);
1016 segment_pos += next_range_size;
1017 base_indices = base_indices.
drop_front(next_range_size);
1030template<
typename Fn>
1041 int16_t *r_current = r_true_indices;
1042 const int16_t *in_end =
indices.base_span().end();
1044 for (
const int16_t *in_current =
indices.base_span().data(); in_current < in_end;
1046 const int16_t local_index = *in_current;
1048 const bool condition = predicate(global_index);
1049 *r_current = local_index;
1054 r_current += condition;
1056 const int16_t true_indices_num = int16_t(r_current - r_true_indices);
1057 return true_indices_num;
1061template<
typename T,
typename Fn>
1064 Fn &&get_group_index,
1069 const int group_index = get_group_index(
i);
1070 indices_by_group[group_index].
append(
T(
i));
1087 return std::nullopt;
1128 const uint32_t random_seed,
1129 const float probability,
1133 const uint32_t random_seed,
1134 const float probability,
1140using index_mask::IndexMask;
1141using index_mask::IndexMaskFromSegment;
1142using index_mask::IndexMaskMemory;
1143using index_mask::IndexMaskSegment;
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
const IndexMask & update(IndexMaskSegment segment)
IndexMaskSegment slice(const IndexRange &range) const
IndexMaskSegment shift(const int64_t shift) const
IndexMaskSegment(const OffsetSpan< int64_t, int16_t > span)
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
IndexMaskSegment segment(int64_t segment_i) const
std::optional< IndexRange > to_range() const
void foreach_index_optimized(Fn &&fn) const
IndexMask slice(IndexRange range) const
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
IndexRange bounds() const
int64_t operator[](int64_t i) const
int64_t iterator_to_index(const RawMaskIterator &it) const
int64_t min_array_size() const
static void from_groups(const IndexMask &universe, IndexMaskMemory &memory, Fn &&get_group_index, MutableSpan< IndexMask > r_masks)
IndexRange index_range() const
Vector< std::variant< IndexRange, IndexMaskSegment >, N > to_spans_and_ranges() const
IndexMaskData & data_for_inplace_construction()
void foreach_range(Fn &&fn) const
void foreach_segment_optimized(Fn &&fn) const
void foreach_index(Fn &&fn) const
RawMaskIterator index_to_iterator(int64_t index) const
int64_t segments_num() const
void foreach_segment(Fn &&fn) const
constexpr int64_t first() const
constexpr int64_t one_after_last() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr int64_t start() const
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
void provide_buffer(void *buffer, const int64_t size)
constexpr int64_t size() const
constexpr IndexRange index_range() const
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
Span< int16_t > base_span() const
constexpr Span drop_front(int64_t n) const
constexpr bool is_empty() const
void append(const T &value)
const IndexMask & update(IndexMaskSegment segment)
IndexMaskSegment slice(const IndexRange &range) const
IndexMaskSegment shift(const int64_t shift) const
IndexMaskSegment(const OffsetSpan< int64_t, int16_t > span)
IndexMask slice_and_shift(IndexRange range, int64_t offset, IndexMaskMemory &memory) const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_every_nth(int64_t n, int64_t indices_num, const int64_t initial_offset, IndexMaskMemory &memory)
IndexMaskSegment segment(int64_t segment_i) const
void to_indices(MutableSpan< T > r_indices) const
IndexMask slice_content(IndexRange range) const
Vector< IndexRange > to_ranges_invert(IndexRange universe) const
static IndexMask from_bits(BitSpan bits, IndexMaskMemory &memory)
Vector< IndexRange > to_ranges() const
std::optional< RawMaskIterator > find(int64_t query_index) const
std::optional< IndexRange > to_range() const
static Vector< IndexMask, 4 > from_group_ids(const VArray< int > &group_ids, IndexMaskMemory &memory, VectorSet< int > &r_index_by_group_id)
static IndexMask from_repeating(const IndexMask &mask_to_repeat, int64_t repetitions, int64_t stride, int64_t initial_offset, IndexMaskMemory &memory)
static IndexMask from_union(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
IndexMask shift(const int64_t offset, IndexMaskMemory &memory) const
void foreach_index_optimized(Fn &&fn) const
std::optional< RawMaskIterator > find_larger_equal(int64_t query_index) const
IndexMask slice(IndexRange range) const
static IndexMask from_ranges(OffsetIndices< T > offsets, const IndexMask &mask, IndexMaskMemory &memory)
static IndexMask from_intersection(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
IndexRange bounds() const
int64_t operator[](int64_t i) const
int64_t iterator_to_index(const RawMaskIterator &it) const
static IndexMask from_segments(Span< IndexMaskSegment > segments, IndexMaskMemory &memory)
int64_t min_array_size() const
static void from_groups(const IndexMask &universe, IndexMaskMemory &memory, Fn &&get_group_index, MutableSpan< IndexMask > r_masks)
static IndexMask from_batch_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, FunctionRef< int64_t(const IndexMaskSegment &universe_segment, IndexRangesBuilder< int16_t > &builder)> batch_predicate)
static IndexMask from_initializers(const Span< Initializer > initializers, IndexMaskMemory &memory)
IndexRange index_range() const
void set_bits(MutableBitSpan r_bits, int64_t offset=0) const
Vector< std::variant< IndexRange, IndexMaskSegment >, N > to_spans_and_ranges() const
std::optional< RawMaskIterator > find_smaller_equal(int64_t query_index) const
friend bool operator!=(const IndexMask &a, const IndexMask &b)
IndexMaskData & data_for_inplace_construction()
bool contains(int64_t query_index) const
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void foreach_range(Fn &&fn) const
void to_bits(MutableBitSpan r_bits, int64_t offset=0) const
static IndexMask from_bools_inverse(const VArray< bool > &bools, IndexMaskMemory &memory)
void foreach_segment_optimized(Fn &&fn) const
friend bool operator==(const IndexMask &a, const IndexMask &b)
void to_bools(MutableSpan< bool > r_bools) const
void foreach_index(Fn &&fn) const
RawMaskIterator index_to_iterator(int64_t index) const
static void foreach_segment_zipped(Span< IndexMask > masks, FunctionRef< bool(Span< IndexMaskSegment > segments)> fn)
int64_t segments_num() const
static IndexMask from_difference(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
std::variant< IndexRange, Span< int64_t >, Span< int >, int64_t > Initializer
void foreach_segment(Fn &&fn) const
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static int64_t last_if(Iterator begin, Iterator end, Predicate &&predicate)
IndexMask from_predicate_impl(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, FunctionRef< int64_t(IndexMaskSegment indices, int16_t *r_true_indices)> filter_indices)
constexpr bool has_segment_and_start_parameter
void index_range_to_mask_segments(const IndexRange range, Vector< IndexMaskSegment, N > &r_segments)
static constexpr int64_t max_segment_size
static constexpr int64_t max_segment_size_mask_high
void build_reverse_map(const IndexMask &mask, MutableSpan< T > r_map)
static constexpr int64_t max_segment_size_mask_low
std::ostream & operator<<(std::ostream &stream, const IndexMask &mask)
void optimized_foreach_index(const IndexMaskSegment segment, const Fn fn)
bool operator==(const RawMaskIterator &a, const RawMaskIterator &b)
std::array< int16_t, max_segment_size > build_static_indices_array()
void optimized_foreach_index_with_pos(const IndexMaskSegment segment, const int64_t segment_pos, const Fn fn)
const IndexMask & get_static_index_mask_for_min_size(const int64_t min_size)
int64_t consolidate_index_mask_segments(MutableSpan< IndexMaskSegment > segments, IndexMaskMemory &memory)
IndexMask random_mask(const IndexMask &mask, const int64_t universe_size, const uint32_t random_seed, const float probability, IndexMaskMemory &memory)
bool operator!=(const RawMaskIterator &a, const RawMaskIterator &b)
const std::array< int16_t, max_segment_size > & get_static_indices_array()
void masked_fill(MutableSpan< T > data, const T &value, const IndexMask &mask)
void init_empty_mask(IndexMaskData &data)
static constexpr int64_t max_segment_size_shift
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
int64_t find_size_of_next_range(const Span< T > indices)
bool non_empty_is_range(const Span< T > indices)
const int64_t * cumulative_segment_sizes_
const int16_t ** indices_by_segment_
int64_t end_index_in_segment_
int64_t begin_index_in_segment_
const int64_t * segment_offsets_