| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup fn | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file provides an MFParams and MFParamsBuilder structure. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * `MFParamsBuilder` is used by a function caller to be prepare all parameters that are passed into | 
					
						
							|  |  |  |  * the function. `MFParams` is then used inside the called function to access the parameters. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-01 15:55:08 +02:00
										 |  |  | #include "BLI_resource_scope.hh"
 | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 13:23:53 +02:00
										 |  |  | #include "FN_generic_pointer.hh"
 | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | #include "FN_generic_vector_array.hh"
 | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  | #include "FN_generic_virtual_vector_array.hh"
 | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | #include "FN_multi_function_signature.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:25:20 +02:00
										 |  |  | namespace blender::fn { | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class MFParamsBuilder { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2021-04-01 15:55:08 +02:00
										 |  |  |   ResourceScope scope_; | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   const MFSignature *signature_; | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |   IndexMask mask_; | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int64_t min_array_size_; | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   Vector<const GVArray *> virtual_arrays_; | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   Vector<GMutableSpan> mutable_spans_; | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   Vector<const GVVectorArray *> virtual_vector_arrays_; | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   Vector<GVectorArray *> vector_arrays_; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend class MFParams; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |   MFParamsBuilder(const MFSignature &signature, const IndexMask mask) | 
					
						
							|  |  |  |       : signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size()) | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |  public: | 
					
						
							|  |  |  |   MFParamsBuilder(const class MultiFunction &fn, int64_t size); | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * The indices referenced by the #mask has to live longer than the params builder. This is | 
					
						
							|  |  |  |    * because the it might have to destruct elements for all masked indices in the end. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   MFParamsBuilder(const class MultiFunction &fn, const IndexMask *mask); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 11:43:54 +02:00
										 |  |  |   template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "") | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |     T *value_ptr = &scope_.add_value<T>(std::move(value)); | 
					
						
							| 
									
										
										
										
											2021-08-20 11:43:54 +02:00
										 |  |  |     this->add_readonly_single_input(value_ptr, expected_name); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |   template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |     this->add_readonly_single_input( | 
					
						
							|  |  |  |         scope_.construct<GVArray_For_SingleValueRef>(CPPType::get<T>(), min_array_size_, value), | 
					
						
							|  |  |  |         expected_name); | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   void add_readonly_single_input(const GSpan span, StringRef expected_name = "") | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |     this->add_readonly_single_input(scope_.construct<GVArray_For_GSpan>(span), expected_name); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-13 13:23:53 +02:00
										 |  |  |   void add_readonly_single_input(GPointer value, StringRef expected_name = "") | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |     this->add_readonly_single_input( | 
					
						
							|  |  |  |         scope_.construct<GVArray_For_SingleValueRef>(*value.type(), min_array_size_, value.get()), | 
					
						
							|  |  |  |         expected_name); | 
					
						
							| 
									
										
										
										
											2021-05-13 13:23:53 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   void add_readonly_single_input(const GVArray &ref, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()), expected_name); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(ref.size() >= min_array_size_); | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     virtual_arrays_.append(&ref); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "") | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |     this->add_readonly_vector_input(scope_.construct<GVVectorArray_For_GVectorArray>(vector_array), | 
					
						
							|  |  |  |                                     expected_name); | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-08-20 11:43:54 +02:00
										 |  |  |   void add_readonly_vector_input(const GSpan single_vector, StringRef expected_name = "") | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     this->add_readonly_vector_input( | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |         scope_.construct<GVVectorArray_For_SingleGSpan>(single_vector, min_array_size_), | 
					
						
							| 
									
										
										
										
											2021-08-20 11:43:54 +02:00
										 |  |  |         expected_name); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(ref.size() >= min_array_size_); | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     virtual_vector_arrays_.append(&ref); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |   template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-07-21 17:20:05 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1), | 
					
						
							|  |  |  |                                           expected_name); | 
					
						
							| 
									
										
										
										
											2020-07-21 17:20:05 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |   void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(ref.size() >= min_array_size_); | 
					
						
							|  |  |  |     mutable_spans_.append(ref); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |   void add_ignored_single_output(StringRef expected_name = "") | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     this->assert_current_param_name(expected_name); | 
					
						
							|  |  |  |     const int param_index = this->current_param_index(); | 
					
						
							|  |  |  |     const MFParamType ¶m_type = signature_->param_types[param_index]; | 
					
						
							|  |  |  |     BLI_assert(param_type.category() == MFParamType::SingleOutput); | 
					
						
							|  |  |  |     const CPPType &type = param_type.data_type().single_type(); | 
					
						
							|  |  |  |     /* An empty span indicates that this is ignored. */ | 
					
						
							|  |  |  |     const GMutableSpan dummy_span{type}; | 
					
						
							|  |  |  |     mutable_spans_.append(dummy_span); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |   void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()), | 
					
						
							|  |  |  |                                     expected_name); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(vector_array.size() >= min_array_size_); | 
					
						
							|  |  |  |     vector_arrays_.append(&vector_array); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |   void add_single_mutable(GMutableSpan ref, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(ref.size() >= min_array_size_); | 
					
						
							|  |  |  |     mutable_spans_.append(ref); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |   void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()), | 
					
						
							|  |  |  |                                     expected_name); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(vector_array.size() >= min_array_size_); | 
					
						
							|  |  |  |     vector_arrays_.append(&vector_array); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   GMutableSpan computed_array(int param_index) | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(ELEM(signature_->param_types[param_index].category(), | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |                     MFParamType::SingleOutput, | 
					
						
							|  |  |  |                     MFParamType::SingleMutable)); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     return mutable_spans_[data_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   GVectorArray &computed_vector_array(int param_index) | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(ELEM(signature_->param_types[param_index].category(), | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |                     MFParamType::VectorOutput, | 
					
						
							|  |  |  |                     MFParamType::VectorMutable)); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     return *vector_arrays_[data_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-01 15:55:08 +02:00
										 |  |  |   ResourceScope &resource_scope() | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-04-01 15:55:08 +02:00
										 |  |  |     return scope_; | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |   void assert_current_param_type(MFParamType param_type, StringRef expected_name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  |     UNUSED_VARS_NDEBUG(param_type, expected_name); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int param_index = this->current_param_index(); | 
					
						
							| 
									
										
										
										
											2020-07-23 17:57:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (expected_name != "") { | 
					
						
							|  |  |  |       StringRef actual_name = signature_->param_names[param_index]; | 
					
						
							|  |  |  |       BLI_assert(actual_name == expected_name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     MFParamType expected_type = signature_->param_types[param_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |     BLI_assert(expected_type == param_type); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |   void assert_current_param_name(StringRef expected_name) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     UNUSED_VARS_NDEBUG(expected_name); | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							|  |  |  |     if (expected_name.is_empty()) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const int param_index = this->current_param_index(); | 
					
						
							|  |  |  |     StringRef actual_name = signature_->param_names[param_index]; | 
					
						
							|  |  |  |     BLI_assert(actual_name == expected_name); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int current_param_index() const | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     return virtual_arrays_.size() + mutable_spans_.size() + virtual_vector_arrays_.size() + | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |            vector_arrays_.size(); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFParams { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   MFParamsBuilder *builder_; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   MFParams(MFParamsBuilder &builder) : builder_(&builder) | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   template<typename T> const VArray<T> &readonly_single_input(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     const GVArray &array = this->readonly_single_input(param_index, name); | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |     return builder_->scope_.construct<GVArray_Typed<T>>(array); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   const GVArray &readonly_single_input(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::SingleInput); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     return *builder_->virtual_arrays_[data_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * \return True when the caller provided a buffer for this output parameter. This allows the | 
					
						
							|  |  |  |    * called multi-function to skip some computation. It is still valid to call | 
					
						
							|  |  |  |    * #uninitialized_single_output when this returns false. In this case a new temporary buffer is | 
					
						
							|  |  |  |    * allocated. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   bool single_output_is_required(int param_index, StringRef name = "") | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::SingleOutput); | 
					
						
							|  |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							|  |  |  |     return !builder_->mutable_spans_[data_index].is_empty(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   template<typename T> | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   MutableSpan<T> uninitialized_single_output(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return this->uninitialized_single_output(param_index, name).typed<T>(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   GMutableSpan uninitialized_single_output(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::SingleOutput); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |     GMutableSpan span = builder_->mutable_spans_[data_index]; | 
					
						
							|  |  |  |     if (span.is_empty()) { | 
					
						
							|  |  |  |       /* The output is ignored by the caller, but the multi-function does not handle this case. So
 | 
					
						
							|  |  |  |        * create a temporary buffer that the multi-function can write to. */ | 
					
						
							|  |  |  |       const CPPType &type = span.type(); | 
					
						
							|  |  |  |       void *buffer = builder_->scope_.linear_allocator().allocate( | 
					
						
							|  |  |  |           builder_->min_array_size_ * type.size(), type.alignment()); | 
					
						
							|  |  |  |       if (!type.is_trivially_destructible()) { | 
					
						
							|  |  |  |         /* Make sure the temporary elements will be destructed in the end. */ | 
					
						
							|  |  |  |         builder_->scope_.add_destruct_call( | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |             [&type, buffer, mask = builder_->mask_]() { type.destruct_indices(buffer, mask); }); | 
					
						
							| 
									
										
										
										
											2021-09-14 14:52:44 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       span = GMutableSpan{type, buffer, builder_->min_array_size_}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return span; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 13:12:25 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Same as #uninitialized_single_output, but returns an empty span when the output is not | 
					
						
							|  |  |  |    * required. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   template<typename T> | 
					
						
							|  |  |  |   MutableSpan<T> uninitialized_single_output_if_required(int param_index, StringRef name = "") | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return this->uninitialized_single_output_if_required(param_index, name).typed<T>(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "") | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::SingleOutput); | 
					
						
							|  |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							|  |  |  |     return builder_->mutable_spans_[data_index]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   template<typename T> | 
					
						
							|  |  |  |   const VVectorArray<T> &readonly_vector_input(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     const GVVectorArray &vector_array = this->readonly_vector_input(param_index, name); | 
					
						
							| 
									
										
										
										
											2021-09-14 16:08:09 +02:00
										 |  |  |     return builder_->scope_.construct<VVectorArray_For_GVVectorArray<T>>(vector_array); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::VectorInput); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     return *builder_->virtual_vector_arrays_[data_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   template<typename T> | 
					
						
							|  |  |  |   GVectorArray_TypedMutableRef<T> vector_output(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     return {this->vector_output(param_index, name)}; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   GVectorArray &vector_output(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::VectorOutput); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     return *builder_->vector_arrays_[data_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return this->single_mutable(param_index, name).typed<T>(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   GMutableSpan single_mutable(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::SingleMutable); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     return builder_->mutable_spans_[data_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |   template<typename T> | 
					
						
							|  |  |  |   GVectorArray_TypedMutableRef<T> vector_mutable(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-22 15:48:08 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-03-21 19:31:24 +01:00
										 |  |  |     return {this->vector_mutable(param_index, name)}; | 
					
						
							| 
									
										
										
										
											2020-06-22 15:48:08 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   GVectorArray &vector_mutable(int param_index, StringRef name = "") | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     this->assert_correct_param(param_index, name, MFParamType::VectorMutable); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     int data_index = builder_->signature_->data_index(param_index); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     return *builder_->vector_arrays_[data_index]; | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   void assert_correct_param(int param_index, StringRef name, MFParamType param_type) | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     UNUSED_VARS_NDEBUG(param_index, name, param_type); | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(builder_->signature_->param_types[param_index] == param_type); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |     if (name.size() > 0) { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |       BLI_assert(builder_->signature_->param_names[param_index] == name); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   void assert_correct_param(int param_index, StringRef name, MFParamType::Category category) | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     UNUSED_VARS_NDEBUG(param_index, name, category); | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |     BLI_assert(builder_->signature_->param_types[param_index].category() == category); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |     if (name.size() > 0) { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |       BLI_assert(builder_->signature_->param_names[param_index] == name); | 
					
						
							| 
									
										
										
										
											2020-06-16 16:35:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:25:20 +02:00
										 |  |  | }  // namespace blender::fn
 |