/* SPDX-License-Identifier: Apache-2.0 */ #include "FN_multi_function.hh" namespace blender::fn::tests { class AddPrefixFunction : public MultiFunction { public: AddPrefixFunction() { static MFSignature signature = create_signature(); this->set_signature(&signature); } static MFSignature create_signature() { MFSignatureBuilder signature{"Add Prefix"}; signature.single_input("Prefix"); signature.single_mutable("Strings"); return signature.build(); } void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { const VArray &prefixes = params.readonly_single_input(0, "Prefix"); MutableSpan strings = params.single_mutable(1, "Strings"); for (int64_t i : mask) { strings[i] = prefixes[i] + strings[i]; } } }; class CreateRangeFunction : public MultiFunction { public: CreateRangeFunction() { static MFSignature signature = create_signature(); this->set_signature(&signature); } static MFSignature create_signature() { MFSignatureBuilder signature{"Create Range"}; signature.single_input("Size"); signature.vector_output("Range"); return signature.build(); } void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { const VArray &sizes = params.readonly_single_input(0, "Size"); GVectorArray &ranges = params.vector_output(1, "Range"); for (int64_t i : mask) { int size = sizes[i]; for (int j : IndexRange(size)) { ranges.append(i, &j); } } } }; class GenericAppendFunction : public MultiFunction { private: MFSignature signature_; public: GenericAppendFunction(const CPPType &type) { MFSignatureBuilder signature{"Append"}; signature.vector_mutable("Vector", type); signature.single_input("Value", type); signature_ = signature.build(); this->set_signature(&signature_); } void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { GVectorArray &vectors = params.vector_mutable(0, "Vector"); const GVArray &values = params.readonly_single_input(1, "Value"); for (int64_t i : mask) { BUFFER_FOR_CPP_TYPE_VALUE(values.type(), buffer); values.get(i, buffer); vectors.append(i, buffer); values.type().destruct(buffer); } } }; class ConcatVectorsFunction : public MultiFunction { public: ConcatVectorsFunction() { static MFSignature signature = create_signature(); this->set_signature(&signature); } static MFSignature create_signature() { MFSignatureBuilder signature{"Concat Vectors"}; signature.vector_mutable("A"); signature.vector_input("B"); return signature.build(); } void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { GVectorArray &a = params.vector_mutable(0); const GVVectorArray &b = params.readonly_vector_input(1); a.extend(mask, b); } }; class AppendFunction : public MultiFunction { public: AppendFunction() { static MFSignature signature = create_signature(); this->set_signature(&signature); } static MFSignature create_signature() { MFSignatureBuilder signature{"Append"}; signature.vector_mutable("Vector"); signature.single_input("Value"); return signature.build(); } void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { GVectorArray_TypedMutableRef vectors = params.vector_mutable(0); const VArray &values = params.readonly_single_input(1); for (int64_t i : mask) { vectors.append(i, values[i]); } } }; class SumVectorFunction : public MultiFunction { public: SumVectorFunction() { static MFSignature signature = create_signature(); this->set_signature(&signature); } static MFSignature create_signature() { MFSignatureBuilder signature{"Sum Vectors"}; signature.vector_input("Vector"); signature.single_output("Sum"); return signature.build(); } void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { const VVectorArray &vectors = params.readonly_vector_input(0); MutableSpan sums = params.uninitialized_single_output(1); for (int64_t i : mask) { int sum = 0; for (int j : IndexRange(vectors.get_vector_size(i))) { sum += vectors.get_vector_element(i, j); } sums[i] = sum; } } }; class OptionalOutputsFunction : public MultiFunction { public: OptionalOutputsFunction() { static MFSignature signature = create_signature(); this->set_signature(&signature); } static MFSignature create_signature() { MFSignatureBuilder signature{"Optional Outputs"}; signature.single_output("Out 1"); signature.single_output("Out 2"); return signature.build(); } void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { if (params.single_output_is_required(0, "Out 1")) { MutableSpan values = params.uninitialized_single_output(0, "Out 1"); values.fill_indices(mask, 5); } MutableSpan values = params.uninitialized_single_output(1, "Out 2"); for (const int i : mask) { new (&values[i]) std::string("hello, this is a long string"); } } }; } // namespace blender::fn::tests