Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenlib/BLI_virtual_array.hh
| Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | public: | ||||
| } | } | ||||
| /** | /** | ||||
| * Copy values from the virtual array into the provided span. The index of the value in the | * Copy values from the virtual array into the provided span. The index of the value in the | ||||
| * virtual array is the same as the index in the span. | * virtual array is the same as the index in the span. | ||||
| */ | */ | ||||
| virtual void materialize(IndexMask mask, MutableSpan<T> r_span) const | virtual void materialize(IndexMask mask, MutableSpan<T> r_span) const | ||||
| { | { | ||||
| T *dst = r_span.data(); | mask.foreach_index([&](const int64_t i) { r_span[i] = this->get(i); }); | ||||
| /* Optimize for a few different common cases. */ | |||||
| const CommonVArrayInfo info = this->common_info(); | |||||
| switch (info.type) { | |||||
| case CommonVArrayInfo::Type::Any: { | |||||
| mask.foreach_index([&](const int64_t i) { dst[i] = this->get(i); }); | |||||
| break; | |||||
| } | |||||
| case CommonVArrayInfo::Type::Span: { | |||||
| const T *src = static_cast<const T *>(info.data); | |||||
| mask.foreach_index([&](const int64_t i) { dst[i] = src[i]; }); | |||||
| break; | |||||
| } | |||||
| case CommonVArrayInfo::Type::Single: { | |||||
| const T single = *static_cast<const T *>(info.data); | |||||
| mask.foreach_index([&](const int64_t i) { dst[i] = single; }); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * Same as #materialize but #r_span is expected to be uninitialized. | * Same as #materialize but #r_span is expected to be uninitialized. | ||||
| */ | */ | ||||
| virtual void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const | virtual void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const | ||||
| { | { | ||||
| T *dst = r_span.data(); | T *dst = r_span.data(); | ||||
| /* Optimize for a few different common cases. */ | |||||
| const CommonVArrayInfo info = this->common_info(); | |||||
| switch (info.type) { | |||||
| case CommonVArrayInfo::Type::Any: { | |||||
| mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); }); | mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); }); | ||||
| break; | |||||
| } | |||||
| case CommonVArrayInfo::Type::Span: { | |||||
| const T *src = static_cast<const T *>(info.data); | |||||
| mask.foreach_index([&](const int64_t i) { new (dst + i) T(src[i]); }); | |||||
| break; | |||||
| } | |||||
| case CommonVArrayInfo::Type::Single: { | |||||
| const T single = *static_cast<const T *>(info.data); | |||||
| mask.foreach_index([&](const int64_t i) { new (dst + i) T(single); }); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * Copy values from the virtual array into the provided span. Contrary to #materialize, the index | * Copy values from the virtual array into the provided span. Contrary to #materialize, the index | ||||
| * in virtual array is not the same as the index in the output span. Instead, the span is filled | * in virtual array is not the same as the index in the output span. Instead, the span is filled | ||||
| * without gaps. | * without gaps. | ||||
| */ | */ | ||||
| virtual void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const | virtual void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const | ||||
| { | { | ||||
| BLI_assert(mask.size() == r_span.size()); | BLI_assert(mask.size() == r_span.size()); | ||||
| mask.to_best_mask_type([&](auto best_mask) { | mask.to_best_mask_type([&](auto best_mask) { | ||||
| for (const int64_t i : IndexRange(best_mask.size())) { | for (const int64_t i : IndexRange(best_mask.size())) { | ||||
JacquesLucke: I actually meant to do the opposite at some point: Removing the special cases from `VArrayImpl`… | |||||
Done Inline ActionsNope! Only consistency, but I agree it would be better like you suggested. I can implement that here if you'd like HooglyBoogly: Nope! Only consistency, but I agree it would be better like you suggested. I can implement that… | |||||
Done Inline ActionsSounds good. JacquesLucke: Sounds good. | |||||
| r_span[i] = this->get(best_mask[i]); | r_span[i] = this->get(best_mask[i]); | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| /** | /** | ||||
| * Same as #materialize_compressed but #r_span is expected to be uninitialized. | * Same as #materialize_compressed but #r_span is expected to be uninitialized. | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | bool is_same(const VArrayImpl<T> &other) const final | ||||
| } | } | ||||
| const CommonVArrayInfo other_info = other.common_info(); | const CommonVArrayInfo other_info = other.common_info(); | ||||
| if (other_info.type != CommonVArrayInfo::Type::Span) { | if (other_info.type != CommonVArrayInfo::Type::Span) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return data_ == static_cast<const T *>(other_info.data); | return data_ == static_cast<const T *>(other_info.data); | ||||
| } | } | ||||
| void materialize(IndexMask mask, MutableSpan<T> r_span) const override | |||||
| { | |||||
| mask.foreach_index([&](const int64_t i) { r_span[i] = data_[i]; }); | |||||
| } | |||||
| void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override | |||||
| { | |||||
| T *dst = r_span.data(); | |||||
| mask.foreach_index([&](const int64_t i) { new (dst + i) T(data_[i]); }); | |||||
| } | |||||
| void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override | void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override | ||||
| { | { | ||||
| BLI_assert(mask.size() == r_span.size()); | |||||
| mask.to_best_mask_type([&](auto best_mask) { | mask.to_best_mask_type([&](auto best_mask) { | ||||
| for (const int64_t i : IndexRange(best_mask.size())) { | for (const int64_t i : IndexRange(best_mask.size())) { | ||||
| r_span[i] = data_[best_mask[i]]; | r_span[i] = data_[best_mask[i]]; | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| void materialize_compressed_to_uninitialized(IndexMask mask, | void materialize_compressed_to_uninitialized(IndexMask mask, | ||||
| MutableSpan<T> r_span) const override | MutableSpan<T> r_span) const override | ||||
| { | { | ||||
| BLI_assert(mask.size() == r_span.size()); | |||||
| T *dst = r_span.data(); | T *dst = r_span.data(); | ||||
| mask.to_best_mask_type([&](auto best_mask) { | mask.to_best_mask_type([&](auto best_mask) { | ||||
| for (const int64_t i : IndexRange(best_mask.size())) { | for (const int64_t i : IndexRange(best_mask.size())) { | ||||
| new (dst + i) T(data_[best_mask[i]]); | new (dst + i) T(data_[best_mask[i]]); | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| }; | }; | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | T get(const int64_t UNUSED(index)) const override | ||||
| return value_; | return value_; | ||||
| } | } | ||||
| CommonVArrayInfo common_info() const override | CommonVArrayInfo common_info() const override | ||||
| { | { | ||||
| return CommonVArrayInfo(CommonVArrayInfo::Type::Single, true, &value_); | return CommonVArrayInfo(CommonVArrayInfo::Type::Single, true, &value_); | ||||
| } | } | ||||
| void materialize(IndexMask mask, MutableSpan<T> r_span) const override | |||||
| { | |||||
| mask.foreach_index([&](const int64_t i) { r_span[i] = value_; }); | |||||
| } | |||||
| void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override | |||||
| { | |||||
| T *dst = r_span.data(); | |||||
| mask.foreach_index([&](const int64_t i) { new (dst + i) T(value_); }); | |||||
| } | |||||
| void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override | void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override | ||||
| { | { | ||||
| BLI_assert(mask.size() == r_span.size()); | BLI_assert(mask.size() == r_span.size()); | ||||
| UNUSED_VARS_NDEBUG(mask); | UNUSED_VARS_NDEBUG(mask); | ||||
| r_span.fill(value_); | r_span.fill(value_); | ||||
| } | } | ||||
| void materialize_compressed_to_uninitialized(IndexMask mask, | void materialize_compressed_to_uninitialized(IndexMask mask, | ||||
| ▲ Show 20 Lines • Show All 926 Lines • Show Last 20 Lines | |||||
I actually meant to do the opposite at some point: Removing the special cases from VArrayImpl and only implementing them in the corresponding subclasses. Do you see a strong reason for having everything in the base class?