5#include "testing/testing.h"
14class AddFunction :
public MultiFunction {
18 static Signature signature = []() {
20 SignatureBuilder builder(
"Add", signature);
21 builder.single_input<
int>(
"A");
22 builder.single_input<
int>(
"B");
23 builder.single_output<
int>(
"Result");
26 this->set_signature(&signature);
29 void call(
const IndexMask &mask, Params
params, Context )
const override
31 const VArray<int> &a =
params.readonly_single_input<
int>(0,
"A");
32 const VArray<int> &
b =
params.readonly_single_input<
int>(1,
"B");
33 MutableSpan<int> result =
params.uninitialized_single_output<
int>(2,
"Result");
35 mask.foreach_index([&](
const int64_t i) { result[i] = a[i] +
b[i]; });
39TEST(multi_function, AddFunction)
43 Array<int> input1 = {4, 5, 6};
44 Array<int> input2 = {10, 20, 30};
47 IndexMaskMemory memory;
49 ParamsBuilder
params(fn, &mask);
50 params.add_readonly_single_input(input1.as_span());
51 params.add_readonly_single_input(input2.as_span());
52 params.add_uninitialized_single_output(output.as_mutable_span());
54 ContextBuilder context;
56 fn.call(mask,
params, context);
63TEST(multi_function, AddPrefixFunction)
67 Array<std::string> strings = {
71 "Another much longer string to trigger an allocation",
74 std::string prefix =
"AB";
76 IndexMaskMemory memory;
78 ParamsBuilder
params(fn, &mask);
79 params.add_readonly_single_input(&prefix);
80 params.add_single_mutable(strings.as_mutable_span());
82 ContextBuilder context;
84 fn.call(mask,
params, context);
88 EXPECT_EQ(strings[2],
"ABThis is a test");
89 EXPECT_EQ(strings[3],
"ABAnother much longer string to trigger an allocation");
92TEST(multi_function, CreateRangeFunction)
94 CreateRangeFunction fn;
97 GVectorArray_TypedMutableRef<int> ranges_ref{ranges};
98 Array<int> sizes = {3, 0, 6, 1, 4};
100 IndexMaskMemory memory;
102 ParamsBuilder
params(fn, &mask);
103 params.add_readonly_single_input(sizes.as_span());
104 params.add_vector_output(ranges);
106 ContextBuilder context;
108 fn.call(mask,
params, context);
123TEST(multi_function, GenericAppendFunction)
128 GVectorArray_TypedMutableRef<int> vectors_ref{vectors};
129 vectors_ref.append(0, 1);
130 vectors_ref.append(0, 2);
131 vectors_ref.append(2, 6);
132 Array<int> values = {5, 7, 3, 1};
134 const IndexMask
mask(IndexRange(vectors.size()));
135 ParamsBuilder
params(fn, &mask);
136 params.add_vector_mutable(vectors);
137 params.add_readonly_single_input(values.as_span());
139 ContextBuilder context;
141 fn.call(mask,
params, context);
157TEST(multi_function, CustomMF_Constant)
159 CustomMF_Constant<int> fn{42};
163 IndexMaskMemory memory;
165 ParamsBuilder
params(fn, &mask);
166 params.add_uninitialized_single_output(outputs.as_mutable_span());
168 ContextBuilder context;
170 fn.call(mask,
params, context);
178TEST(multi_function, CustomMF_GenericConstant)
185 IndexMaskMemory memory;
187 ParamsBuilder
params(fn, &mask);
188 params.add_uninitialized_single_output(outputs.as_mutable_span());
190 ContextBuilder context;
192 fn.call(mask,
params, context);
200TEST(multi_function, CustomMF_GenericConstantArray)
202 std::array<int, 4> values = {3, 4, 5, 6};
203 CustomMF_GenericConstantArray fn{GSpan(
Span(values))};
206 GVectorArray_TypedMutableRef<int> vector_array_ref{vector_array};
208 IndexMaskMemory memory;
210 ParamsBuilder
params(fn, &mask);
211 params.add_vector_output(vector_array);
213 ContextBuilder context;
215 fn.call(mask,
params, context);
221 for (
int i = 1; i < 4; i++) {
229TEST(multi_function, IgnoredOutputs)
231 OptionalOutputsFunction fn;
233 const IndexMask
mask(10);
234 ParamsBuilder
params(fn, &mask);
235 params.add_ignored_single_output(
"Out 1");
236 params.add_ignored_single_output(
"Out 2");
237 ContextBuilder context;
238 fn.call(mask,
params, context);
241 Array<int> results_1(10);
242 Array<std::string> results_2(10, NoInitialization());
243 const IndexMask
mask(10);
245 ParamsBuilder
params(fn, &mask);
246 params.add_uninitialized_single_output(results_1.as_mutable_span(),
"Out 1");
247 params.add_uninitialized_single_output(results_2.as_mutable_span(),
"Out 2");
248 ContextBuilder context;
249 fn.call(mask,
params, context);
254 EXPECT_EQ(results_2[0],
"hello, this is a long string");
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static const CPPType & get()
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
local_group_size(16, 16) .push_constant(Type b
ccl_device_inline float4 mask(const int4 mask, const float4 a)
TEST(multi_function_procedure, ConstantOutput)
static blender::bke::bNodeSocketTemplate outputs[]