| 
									
										
										
										
											2021-09-09 12:54:20 +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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "FN_multi_function.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace blender::fn { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFVariable; | 
					
						
							|  |  |  | class MFInstruction; | 
					
						
							|  |  |  | class MFCallInstruction; | 
					
						
							|  |  |  | class MFBranchInstruction; | 
					
						
							|  |  |  | class MFDestructInstruction; | 
					
						
							|  |  |  | class MFDummyInstruction; | 
					
						
							|  |  |  | class MFReturnInstruction; | 
					
						
							|  |  |  | class MFProcedure; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Every instruction has exactly one of these types. */ | 
					
						
							|  |  |  | enum class MFInstructionType { | 
					
						
							|  |  |  |   Call, | 
					
						
							|  |  |  |   Branch, | 
					
						
							|  |  |  |   Destruct, | 
					
						
							|  |  |  |   Dummy, | 
					
						
							|  |  |  |   Return, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-11 11:43:59 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * An #MFInstructionCursor points to a position in a multi-function procedure, where an instruction | 
					
						
							|  |  |  |  * can be inserted. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFInstructionCursor { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   enum Type { | 
					
						
							|  |  |  |     None, | 
					
						
							|  |  |  |     Entry, | 
					
						
							|  |  |  |     Call, | 
					
						
							|  |  |  |     Destruct, | 
					
						
							|  |  |  |     Branch, | 
					
						
							|  |  |  |     Dummy, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   Type type_ = None; | 
					
						
							|  |  |  |   MFInstruction *instruction_ = nullptr; | 
					
						
							|  |  |  |   /* Only used when it is a branch instruction. */ | 
					
						
							|  |  |  |   bool branch_output_ = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFInstructionCursor() = default; | 
					
						
							|  |  |  |   MFInstructionCursor(MFCallInstruction &instruction); | 
					
						
							|  |  |  |   MFInstructionCursor(MFDestructInstruction &instruction); | 
					
						
							|  |  |  |   MFInstructionCursor(MFBranchInstruction &instruction, bool branch_output); | 
					
						
							|  |  |  |   MFInstructionCursor(MFDummyInstruction &instruction); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static MFInstructionCursor ForEntry(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInstruction *next(MFProcedure &procedure) const; | 
					
						
							|  |  |  |   void set_next(MFProcedure &procedure, MFInstruction *new_instruction) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInstruction *instruction() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Type type() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend bool operator==(const MFInstructionCursor &a, const MFInstructionCursor &b) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return a.type_ == b.type_ && a.instruction_ == b.instruction_ && | 
					
						
							|  |  |  |            a.branch_output_ == b.branch_output_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend bool operator!=(const MFInstructionCursor &a, const MFInstructionCursor &b) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return !(a == b); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * A variable is similar to a virtual register in other libraries. During evaluation, every is | 
					
						
							|  |  |  |  * either uninitialized or contains a value for every index (remember, a multi-function procedure | 
					
						
							|  |  |  |  * is always evaluated for many indices at the same time). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFVariable : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   MFDataType data_type_; | 
					
						
							|  |  |  |   Vector<MFInstruction *> users_; | 
					
						
							|  |  |  |   std::string name_; | 
					
						
							|  |  |  |   int id_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend MFProcedure; | 
					
						
							|  |  |  |   friend MFCallInstruction; | 
					
						
							|  |  |  |   friend MFBranchInstruction; | 
					
						
							|  |  |  |   friend MFDestructInstruction; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFDataType data_type() const; | 
					
						
							|  |  |  |   Span<MFInstruction *> users(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   StringRefNull name() const; | 
					
						
							|  |  |  |   void set_name(std::string name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int id() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Base class for all instruction types. */ | 
					
						
							|  |  |  | class MFInstruction : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  protected: | 
					
						
							|  |  |  |   MFInstructionType type_; | 
					
						
							| 
									
										
										
										
											2021-09-11 11:43:59 +02:00
										 |  |  |   Vector<MFInstructionCursor> prev_; | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend MFProcedure; | 
					
						
							|  |  |  |   friend MFCallInstruction; | 
					
						
							|  |  |  |   friend MFBranchInstruction; | 
					
						
							|  |  |  |   friend MFDestructInstruction; | 
					
						
							|  |  |  |   friend MFDummyInstruction; | 
					
						
							|  |  |  |   friend MFReturnInstruction; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFInstructionType type() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Other instructions that come before this instruction. There can be multiple previous | 
					
						
							|  |  |  |    * instructions when branching is used in the procedure. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-09-11 11:43:59 +02:00
										 |  |  |   Span<MFInstructionCursor> prev() const; | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * References a multi-function that is evaluated when the instruction is executed. It also | 
					
						
							|  |  |  |  * references the variables whose data will be passed into the multi-function. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFCallInstruction : public MFInstruction { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   const MultiFunction *fn_ = nullptr; | 
					
						
							|  |  |  |   MFInstruction *next_ = nullptr; | 
					
						
							|  |  |  |   MutableSpan<MFVariable *> params_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend MFProcedure; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   const MultiFunction &fn() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInstruction *next(); | 
					
						
							|  |  |  |   const MFInstruction *next() const; | 
					
						
							|  |  |  |   void set_next(MFInstruction *instruction); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void set_param_variable(int param_index, MFVariable *variable); | 
					
						
							|  |  |  |   void set_params(Span<MFVariable *> variables); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Span<MFVariable *> params(); | 
					
						
							|  |  |  |   Span<const MFVariable *> params() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * What makes a branch instruction special is that it has two successor instructions. One that will | 
					
						
							|  |  |  |  * be used when a condition variable was true, and one otherwise. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFBranchInstruction : public MFInstruction { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   MFVariable *condition_ = nullptr; | 
					
						
							|  |  |  |   MFInstruction *branch_true_ = nullptr; | 
					
						
							|  |  |  |   MFInstruction *branch_false_ = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend MFProcedure; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFVariable *condition(); | 
					
						
							|  |  |  |   const MFVariable *condition() const; | 
					
						
							|  |  |  |   void set_condition(MFVariable *variable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInstruction *branch_true(); | 
					
						
							|  |  |  |   const MFInstruction *branch_true() const; | 
					
						
							|  |  |  |   void set_branch_true(MFInstruction *instruction); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInstruction *branch_false(); | 
					
						
							|  |  |  |   const MFInstruction *branch_false() const; | 
					
						
							|  |  |  |   void set_branch_false(MFInstruction *instruction); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * A destruct instruction destructs a single variable. So the variable value will be uninitialized | 
					
						
							|  |  |  |  * after this instruction. All variables that are not output variables of the procedure, have to be | 
					
						
							|  |  |  |  * destructed before the procedure ends. Destructing early is generally a good thing, because it | 
					
						
							|  |  |  |  * might help with memory buffer reuse, which decreases memory-usage and increases performance. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFDestructInstruction : public MFInstruction { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   MFVariable *variable_ = nullptr; | 
					
						
							|  |  |  |   MFInstruction *next_ = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend MFProcedure; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFVariable *variable(); | 
					
						
							|  |  |  |   const MFVariable *variable() const; | 
					
						
							|  |  |  |   void set_variable(MFVariable *variable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInstruction *next(); | 
					
						
							|  |  |  |   const MFInstruction *next() const; | 
					
						
							|  |  |  |   void set_next(MFInstruction *instruction); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * This instruction does nothing, it just exists to building a procedure simpler in some cases. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFDummyInstruction : public MFInstruction { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   MFInstruction *next_ = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend MFProcedure; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFInstruction *next(); | 
					
						
							|  |  |  |   const MFInstruction *next() const; | 
					
						
							|  |  |  |   void set_next(MFInstruction *instruction); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * This instruction ends the procedure. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFReturnInstruction : public MFInstruction { | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Inputs and outputs of the entire procedure network. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | struct MFParameter { | 
					
						
							|  |  |  |   MFParamType::InterfaceType type; | 
					
						
							|  |  |  |   MFVariable *variable; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ConstMFParameter { | 
					
						
							|  |  |  |   MFParamType::InterfaceType type; | 
					
						
							|  |  |  |   const MFVariable *variable; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * A multi-function procedure allows composing multi-functions in arbitrary ways. It consists of | 
					
						
							|  |  |  |  * variables and instructions that operate on those variables. Branching and looping within the | 
					
						
							|  |  |  |  * procedure is supported as well. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Typically, a #MFProcedure should be constructed using a #MFProcedureBuilder, which has many more | 
					
						
							|  |  |  |  * utility methods for common use cases. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class MFProcedure : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   LinearAllocator<> allocator_; | 
					
						
							|  |  |  |   Vector<MFCallInstruction *> call_instructions_; | 
					
						
							|  |  |  |   Vector<MFBranchInstruction *> branch_instructions_; | 
					
						
							|  |  |  |   Vector<MFDestructInstruction *> destruct_instructions_; | 
					
						
							|  |  |  |   Vector<MFDummyInstruction *> dummy_instructions_; | 
					
						
							|  |  |  |   Vector<MFReturnInstruction *> return_instructions_; | 
					
						
							|  |  |  |   Vector<MFVariable *> variables_; | 
					
						
							|  |  |  |   Vector<MFParameter> params_; | 
					
						
							|  |  |  |   MFInstruction *entry_ = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend class MFProcedureDotExport; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFProcedure() = default; | 
					
						
							|  |  |  |   ~MFProcedure(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFVariable &new_variable(MFDataType data_type, std::string name = ""); | 
					
						
							|  |  |  |   MFCallInstruction &new_call_instruction(const MultiFunction &fn); | 
					
						
							|  |  |  |   MFBranchInstruction &new_branch_instruction(); | 
					
						
							|  |  |  |   MFDestructInstruction &new_destruct_instruction(); | 
					
						
							|  |  |  |   MFDummyInstruction &new_dummy_instruction(); | 
					
						
							|  |  |  |   MFReturnInstruction &new_return_instruction(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Span<ConstMFParameter> params() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInstruction *entry(); | 
					
						
							|  |  |  |   const MFInstruction *entry() const; | 
					
						
							|  |  |  |   void set_entry(MFInstruction &entry); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Span<MFVariable *> variables(); | 
					
						
							|  |  |  |   Span<const MFVariable *> variables() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::string to_dot() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool validate() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   bool validate_all_instruction_pointers_set() const; | 
					
						
							|  |  |  |   bool validate_all_params_provided() const; | 
					
						
							|  |  |  |   bool validate_same_variables_in_one_call() const; | 
					
						
							|  |  |  |   bool validate_parameters() const; | 
					
						
							|  |  |  |   bool validate_initialization() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct InitState { | 
					
						
							|  |  |  |     bool can_be_initialized = false; | 
					
						
							|  |  |  |     bool can_be_uninitialized = false; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   InitState find_initialization_state_before_instruction(const MFInstruction &target_instruction, | 
					
						
							|  |  |  |                                                          const MFVariable &variable) const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace multi_function_procedure_types { | 
					
						
							|  |  |  | using MFVariable = fn::MFVariable; | 
					
						
							|  |  |  | using MFInstruction = fn::MFInstruction; | 
					
						
							|  |  |  | using MFCallInstruction = fn::MFCallInstruction; | 
					
						
							|  |  |  | using MFBranchInstruction = fn::MFBranchInstruction; | 
					
						
							|  |  |  | using MFDestructInstruction = fn::MFDestructInstruction; | 
					
						
							|  |  |  | using MFProcedure = fn::MFProcedure; | 
					
						
							|  |  |  | }  // namespace multi_function_procedure_types
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFInstructionCursor Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-11 11:43:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline MFInstructionCursor::MFInstructionCursor(MFCallInstruction &instruction) | 
					
						
							|  |  |  |     : type_(Call), instruction_(&instruction) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstructionCursor::MFInstructionCursor(MFDestructInstruction &instruction) | 
					
						
							|  |  |  |     : type_(Destruct), instruction_(&instruction) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstructionCursor::MFInstructionCursor(MFBranchInstruction &instruction, | 
					
						
							|  |  |  |                                                 bool branch_output) | 
					
						
							|  |  |  |     : type_(Branch), instruction_(&instruction), branch_output_(branch_output) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstructionCursor::MFInstructionCursor(MFDummyInstruction &instruction) | 
					
						
							|  |  |  |     : type_(Dummy), instruction_(&instruction) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstructionCursor MFInstructionCursor::ForEntry() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   MFInstructionCursor cursor; | 
					
						
							|  |  |  |   cursor.type_ = Type::Entry; | 
					
						
							|  |  |  |   return cursor; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstruction *MFInstructionCursor::instruction() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* This isn't really const correct unfortunately, because to make it correct we'll need a const
 | 
					
						
							|  |  |  |    * version of #MFInstructionCursor. */ | 
					
						
							|  |  |  |   return instruction_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstructionCursor::Type MFInstructionCursor::type() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return type_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFVariable Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline MFDataType MFVariable::data_type() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return data_type_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<MFInstruction *> MFVariable::users() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return users_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline StringRefNull MFVariable::name() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return name_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline int MFVariable::id() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return id_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFInstruction Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline MFInstructionType MFInstruction::type() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return type_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-11 11:43:59 +02:00
										 |  |  | inline Span<MFInstructionCursor> MFInstruction::prev() const | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return prev_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFCallInstruction Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline const MultiFunction &MFCallInstruction::fn() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *fn_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstruction *MFCallInstruction::next() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return next_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFInstruction *MFCallInstruction::next() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return next_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<MFVariable *> MFCallInstruction::params() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return params_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const MFVariable *> MFCallInstruction::params() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return params_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFBranchInstruction Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline MFVariable *MFBranchInstruction::condition() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return condition_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFVariable *MFBranchInstruction::condition() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return condition_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstruction *MFBranchInstruction::branch_true() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return branch_true_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFInstruction *MFBranchInstruction::branch_true() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return branch_true_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstruction *MFBranchInstruction::branch_false() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return branch_false_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFInstruction *MFBranchInstruction::branch_false() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return branch_false_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFDestructInstruction Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline MFVariable *MFDestructInstruction::variable() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return variable_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFVariable *MFDestructInstruction::variable() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return variable_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstruction *MFDestructInstruction::next() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return next_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFInstruction *MFDestructInstruction::next() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return next_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFDummyInstruction Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline MFInstruction *MFDummyInstruction::next() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return next_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFInstruction *MFDummyInstruction::next() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return next_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #MFProcedure Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline Span<ConstMFParameter> MFProcedure::params() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static_assert(sizeof(MFParameter) == sizeof(ConstMFParameter)); | 
					
						
							|  |  |  |   return params_.as_span().cast<ConstMFParameter>(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInstruction *MFProcedure::entry() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return entry_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFInstruction *MFProcedure::entry() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return entry_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<MFVariable *> MFProcedure::variables() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return variables_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const MFVariable *> MFProcedure::variables() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return variables_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 11:10:25 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | }  // namespace blender::fn
 |