/* SPDX-License-Identifier: Apache-2.0 */ #include "FN_multi_function.hh" namespace blender::fn::multi_function::tests { class AddPrefixFunction : public MultiFunction { public: AddPrefixFunction() { static const Signature signature = []() { Signature signature; SignatureBuilder builder{"Add Prefix", signature}; builder.single_input("Prefix"); builder.single_mutable("Strings"); return signature; }(); this->set_signature(&signature); } void call(IndexMask mask, Params params, Context /*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 const Signature signature = []() { Signature signature; SignatureBuilder builder{"Create Range", signature}; builder.single_input("Size"); builder.vector_output("Range"); return signature; }(); this->set_signature(&signature); } void call(IndexMask mask, Params params, Context /*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: Signature signature_; public: GenericAppendFunction(const CPPType &type) { SignatureBuilder builder{"Append", signature_}; builder.vector_mutable("Vector", type); builder.single_input("Value", type); this->set_signature(&signature_); } void call(IndexMask mask, Params params, Context /*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 const Signature signature = []() { Signature signature; SignatureBuilder builder{"Concat Vectors", signature}; builder.vector_mutable("A"); builder.vector_input("B"); return signature; }(); this->set_signature(&signature); } void call(IndexMask mask, Params params, Context /*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 const Signature signature = []() { Signature signature; SignatureBuilder builder{"Append", signature}; builder.vector_mutable("Vector"); builder.single_input("Value"); return signature; }(); this->set_signature(&signature); } void call(IndexMask mask, Params params, Context /*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 const Signature signature = []() { Signature signature; SignatureBuilder builder{"Sum Vectors", signature}; builder.vector_input("Vector"); builder.single_output("Sum"); return signature; }(); this->set_signature(&signature); } void call(IndexMask mask, Params params, Context /*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 const Signature signature = []() { Signature signature; SignatureBuilder builder{"Optional Outputs", signature}; builder.single_output("Out 1"); builder.single_output("Out 2"); return signature; }(); this->set_signature(&signature); } void call(IndexMask mask, Params params, Context /*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::multi_function::tests