diff options
author | Jacques Lucke <jacques@blender.org> | 2020-06-30 18:59:33 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-06-30 19:18:48 +0300 |
commit | 613f62d15ce1851a8b7017013e9cced1009ad431 (patch) | |
tree | 2ca4befbd04b2bc1644eae653fe5204bd30658b2 /source/blender/functions/FN_multi_function_builder.hh | |
parent | d92e5f895058e3756795aa070a6977c647ff08f8 (diff) |
Functions: add two more customizable multi-functions
Diffstat (limited to 'source/blender/functions/FN_multi_function_builder.hh')
-rw-r--r-- | source/blender/functions/FN_multi_function_builder.hh | 103 |
1 files changed, 89 insertions, 14 deletions
diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 08d4ec672cd..9fcf31443b2 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -36,15 +36,15 @@ namespace fn { * 2. single output (SO) of type Out1 * * This example creates a function that adds 10 to the incoming values: - * CustomFunction_SI_SO<int, int> fn("add 10", [](int value) { return value + 10; }); + * CustomMF_SI_SO<int, int> fn("add 10", [](int value) { return value + 10; }); */ -template<typename In1, typename Out1> class CustomFunction_SI_SO : public MultiFunction { +template<typename In1, typename Out1> class CustomMF_SI_SO : public MultiFunction { private: using FunctionT = std::function<void(IndexMask, VSpan<In1>, MutableSpan<Out1>)>; FunctionT m_function; public: - CustomFunction_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) + CustomMF_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) { MFSignatureBuilder signature = this->get_builder(name); signature.single_input<In1>("In1"); @@ -52,8 +52,8 @@ template<typename In1, typename Out1> class CustomFunction_SI_SO : public MultiF } template<typename ElementFuncT> - CustomFunction_SI_SO(StringRef name, ElementFuncT element_fn) - : CustomFunction_SI_SO(name, CustomFunction_SI_SO::create_function(element_fn)) + CustomMF_SI_SO(StringRef name, ElementFuncT element_fn) + : CustomMF_SI_SO(name, CustomMF_SI_SO::create_function(element_fn)) { } @@ -79,13 +79,13 @@ template<typename In1, typename Out1> class CustomFunction_SI_SO : public MultiF * 3. single output (SO) of type Out1 */ template<typename In1, typename In2, typename Out1> -class CustomFunction_SI_SI_SO : public MultiFunction { +class CustomMF_SI_SI_SO : public MultiFunction { private: using FunctionT = std::function<void(IndexMask, VSpan<In1>, VSpan<In2>, MutableSpan<Out1>)>; FunctionT m_function; public: - CustomFunction_SI_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) + CustomMF_SI_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) { MFSignatureBuilder signature = this->get_builder(name); signature.single_input<In1>("In1"); @@ -94,8 +94,8 @@ class CustomFunction_SI_SI_SO : public MultiFunction { } template<typename ElementFuncT> - CustomFunction_SI_SI_SO(StringRef name, ElementFuncT element_fn) - : CustomFunction_SI_SI_SO(name, CustomFunction_SI_SI_SO::create_function(element_fn)) + CustomMF_SI_SI_SO(StringRef name, ElementFuncT element_fn) + : CustomMF_SI_SI_SO(name, CustomMF_SI_SI_SO::create_function(element_fn)) { } @@ -109,7 +109,7 @@ class CustomFunction_SI_SI_SO : public MultiFunction { void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { VSpan<In1> in1 = params.readonly_single_input<In1>(0); - VSpan<In2> in2 = params.readonly_single_input<In1>(1); + VSpan<In2> in2 = params.readonly_single_input<In2>(1); MutableSpan<Out1> out1 = params.uninitialized_single_output<Out1>(2); m_function(mask, in1, in2, out1); } @@ -117,23 +117,75 @@ class CustomFunction_SI_SI_SO : public MultiFunction { /** * Generates a multi-function with the following parameters: + * 1. single input (SI) of type In1 + * 2. single input (SI) of type In2 + * 3. single input (SI) of type In3 + * 4. single output (SO) of type Out1 + */ +template<typename In1, typename In2, typename In3, typename Out1> +class CustomMF_SI_SI_SI_SO : public MultiFunction { + private: + using FunctionT = + std::function<void(IndexMask, VSpan<In1>, VSpan<In2>, VSpan<In3>, MutableSpan<Out1>)>; + FunctionT m_function; + + public: + CustomMF_SI_SI_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) + { + MFSignatureBuilder signature = this->get_builder(name); + signature.single_input<In1>("In1"); + signature.single_input<In2>("In2"); + signature.single_input<In3>("In3"); + signature.single_output<Out1>("Out1"); + } + + template<typename ElementFuncT> + CustomMF_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn) + : CustomMF_SI_SI_SI_SO(name, CustomMF_SI_SI_SI_SO::create_function(element_fn)) + { + } + + template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn) + { + return [=](IndexMask mask, + VSpan<In1> in1, + VSpan<In2> in2, + VSpan<In3> in3, + MutableSpan<Out1> out1) { + mask.foreach_index( + [&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i], in3[i])); }); + }; + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VSpan<In1> in1 = params.readonly_single_input<In1>(0); + VSpan<In2> in2 = params.readonly_single_input<In2>(1); + VSpan<In3> in3 = params.readonly_single_input<In3>(2); + MutableSpan<Out1> out1 = params.uninitialized_single_output<Out1>(3); + m_function(mask, in1, in2, in3, out1); + } +}; + +/** + * Generates a multi-function with the following parameters: * 1. single mutable (SM) of type Mut1 */ -template<typename Mut1> class CustomFunction_SM : public MultiFunction { +template<typename Mut1> class CustomMF_SM : public MultiFunction { private: using FunctionT = std::function<void(IndexMask, MutableSpan<Mut1>)>; FunctionT m_function; public: - CustomFunction_SM(StringRef name, FunctionT function) : m_function(std::move(function)) + CustomMF_SM(StringRef name, FunctionT function) : m_function(std::move(function)) { MFSignatureBuilder signature = this->get_builder(name); signature.single_mutable<Mut1>("Mut1"); } template<typename ElementFuncT> - CustomFunction_SM(StringRef name, ElementFuncT element_fn) - : CustomFunction_SM(name, CustomFunction_SM::create_function(element_fn)) + CustomMF_SM(StringRef name, ElementFuncT element_fn) + : CustomMF_SM(name, CustomMF_SM::create_function(element_fn)) { } @@ -151,6 +203,29 @@ template<typename Mut1> class CustomFunction_SM : public MultiFunction { } }; +/** + * Generates a multi-function that outputs a constant value. + */ +template<typename T> class CustomMF_Constant : public MultiFunction { + private: + T m_value; + + public: + template<typename U> CustomMF_Constant(U &&value) : m_value(std::forward<U>(value)) + { + MFSignatureBuilder signature = this->get_builder("Constant"); + std::stringstream ss; + ss << m_value; + signature.single_output<T>(ss.str()); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + MutableSpan<T> output = params.uninitialized_single_output<T>(0); + mask.foreach_index([&](uint i) { new (&output[i]) T(m_value); }); + } +}; + } // namespace fn } // namespace blender |