| 
									
										
										
										
											2023-02-13 10:57:10 +08:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | #include <VTAll.hpp>
 | 
					
						
							| 
									
										
										
										
											2023-02-13 10:57:10 +08:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | #include <functional>
 | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | #include <deque>
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | #include <unordered_map>
 | 
					
						
							|  |  |  | #include <stdexcept>
 | 
					
						
							|  |  |  | #include <cinttypes>
 | 
					
						
							|  |  |  | #include <initializer_list>
 | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Unvirt::CmdHelper { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	class CmdSplitter { | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 		enum class StateType : int { | 
					
						
							|  |  |  | 			SPACE, | 
					
						
							|  |  |  | 			SINGLE, | 
					
						
							|  |  |  | 			DOUBLE, | 
					
						
							|  |  |  | 			ESCAPE, | 
					
						
							|  |  |  | 			NORMAL | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 		CmdSplitter() : | 
					
						
							|  |  |  | 			mCmdChar(0), mBuffer(nullptr), mResult(nullptr), | 
					
						
							|  |  |  | 			mState(StateType::NORMAL), mPreState(StateType::NORMAL) {} | 
					
						
							|  |  |  | 		~CmdSplitter() {} | 
					
						
							|  |  |  | 		LIBCMO_DISABLE_COPY_MOVE(CmdSplitter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		std::deque<std::string> Convert(const std::string& u8cmd); | 
					
						
							|  |  |  | 	protected: | 
					
						
							|  |  |  | 		char mCmdChar; | 
					
						
							|  |  |  | 		std::string* mBuffer; | 
					
						
							|  |  |  | 		std::deque<std::string>* mResult; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | 		StateType mState, mPreState; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		void ProcSpace(void); | 
					
						
							|  |  |  | 		void ProcSingle(void); | 
					
						
							|  |  |  | 		void ProcDouble(void); | 
					
						
							|  |  |  | 		void ProcEscape(void); | 
					
						
							|  |  |  | 		void ProcNormal(void); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	class HelpDocument { | 
					
						
							|  |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		HelpDocument(); | 
					
						
							|  |  |  | 		~HelpDocument(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		LIBCMO_DISABLE_COPY_MOVE(HelpDocument); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		void Push(const std::string& arg_name, const std::string& arg_desc); | 
					
						
							|  |  |  | 		void Pop(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		void Terminate(std::string& command_desc); | 
					
						
							|  |  |  | 		void Print(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected: | 
					
						
							|  |  |  | 		struct StackItem { | 
					
						
							|  |  |  | 			StackItem() : m_Name(), m_Desc() {} | 
					
						
							|  |  |  | 			StackItem(const std::string& name, const std::string& desc) : m_Name(name), m_Desc(desc) {} | 
					
						
							|  |  |  | 			LIBCMO_DEFAULT_COPY_MOVE(StackItem); | 
					
						
							|  |  |  | 			std::string m_Name; | 
					
						
							|  |  |  | 			std::string m_Desc; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		std::deque<StackItem> m_Stack; | 
					
						
							|  |  |  | 		struct ResultItem { | 
					
						
							|  |  |  | 			ResultItem() : m_CmdDesc(), m_ArgDesc() {} | 
					
						
							|  |  |  | 			ResultItem(const std::string& desc) : m_CmdDesc(desc), m_ArgDesc() {} | 
					
						
							|  |  |  | 			LIBCMO_DEFAULT_COPY_MOVE(ResultItem); | 
					
						
							|  |  |  | 			std::string m_CmdDesc; | 
					
						
							|  |  |  | 			std::vector<StackItem> m_ArgDesc; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		std::vector<ResultItem> m_Results; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	enum class NodeType { | 
					
						
							|  |  |  | 		Literal, Choice, Argument | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	class ArgumentsMap; | 
					
						
							|  |  |  | 	using ExecutionFct = std::function<void(const ArgumentsMap*)>; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	class AbstractNode { | 
					
						
							|  |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		AbstractNode(); | 
					
						
							|  |  |  | 		virtual ~AbstractNode(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		LIBCMO_DISABLE_COPY_MOVE(AbstractNode); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		AbstractNode* Then(AbstractNode*); | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		AbstractNode* Executes(ExecutionFct, const char* = nullptr); | 
					
						
							|  |  |  | 		AbstractNode* Comment(const char*); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 		void Help(HelpDocument*); | 
					
						
							|  |  |  | 		bool Consume(std::deque<std::string>&, ArgumentsMap*); | 
					
						
							|  |  |  | 		virtual NodeType GetNodeType() = 0; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		virtual bool IsConflictWith(AbstractNode*) = 0; | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	protected: | 
					
						
							|  |  |  | 		virtual std::string GetHelpSymbol() = 0; | 
					
						
							|  |  |  | 		virtual bool BeginAccept(const std::string&, ArgumentsMap*) = 0; | 
					
						
							|  |  |  | 		virtual void EndAccept(ArgumentsMap*) = 0; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		std::vector<AbstractNode*> m_Literals; | 
					
						
							|  |  |  | 		std::vector<AbstractNode*> m_Choices; | 
					
						
							|  |  |  | 		std::vector<AbstractNode*> m_Args; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		ExecutionFct m_Execution; | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		std::string m_ExecutionDesc; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		std::string m_Comment; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	class CommandRoot : public AbstractNode { | 
					
						
							|  |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		CommandRoot(); | 
					
						
							|  |  |  | 		virtual ~CommandRoot(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		LIBCMO_DISABLE_COPY_MOVE(CommandRoot); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Root use special consume and help functions.
 | 
					
						
							|  |  |  | 		bool RootConsume(std::deque<std::string>&); | 
					
						
							|  |  |  | 		HelpDocument* RootHelp(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 		virtual NodeType GetNodeType() override { throw std::logic_error("Root can not be called."); } | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		virtual bool IsConflictWith(AbstractNode*) override { throw std::logic_error("Root can not be called."); } | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	protected: | 
					
						
							|  |  |  | 		virtual std::string GetHelpSymbol()  override { throw std::logic_error("Root can not be called."); } | 
					
						
							|  |  |  | 		virtual bool BeginAccept(const std::string&, ArgumentsMap*) override { throw std::logic_error("Root can not be called."); } | 
					
						
							|  |  |  | 		virtual void EndAccept(ArgumentsMap*) override { throw std::logic_error("Root can not be called."); } | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	class Literal : public AbstractNode { | 
					
						
							|  |  |  | 		friend class Choice; | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		friend class AbstractArgument; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		Literal(const char* words); | 
					
						
							|  |  |  | 		virtual ~Literal(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		LIBCMO_DISABLE_COPY_MOVE(Literal); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 		virtual NodeType GetNodeType() override; | 
					
						
							|  |  |  | 		virtual bool IsConflictWith(AbstractNode* node) override; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	protected: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		virtual std::string GetHelpSymbol() override; | 
					
						
							|  |  |  | 		virtual bool BeginAccept(const std::string&, ArgumentsMap*) override; | 
					
						
							|  |  |  | 		virtual void EndAccept(ArgumentsMap*) override; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		std::string m_Literal; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	class Choice : public AbstractNode { | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		friend class Literal; | 
					
						
							|  |  |  | 		friend class AbstractArgument; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		using vType = size_t; | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		Choice(const char* argname, const std::initializer_list<std::string>& vocabulary); | 
					
						
							|  |  |  | 		virtual ~Choice(); | 
					
						
							|  |  |  | 		LIBCMO_DISABLE_COPY_MOVE(Choice); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		vType* GetIndex(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 		virtual NodeType GetNodeType() override; | 
					
						
							|  |  |  | 		virtual bool IsConflictWith(AbstractNode* node) override; | 
					
						
							|  |  |  | 	protected: | 
					
						
							|  |  |  | 		virtual std::string GetHelpSymbol() override; | 
					
						
							|  |  |  | 		virtual bool BeginAccept(const std::string&, ArgumentsMap*) override; | 
					
						
							|  |  |  | 		virtual void EndAccept(ArgumentsMap*) override; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		std::string m_ChoiceName; | 
					
						
							|  |  |  | 		std::vector<std::string> m_Vocabulary; | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		bool m_Accepted; | 
					
						
							|  |  |  | 		size_t m_GottenIndex; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	class AbstractArgument : public AbstractNode { | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		friend class Literal; | 
					
						
							|  |  |  | 		friend class Choice; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		AbstractArgument(const char* argname); | 
					
						
							|  |  |  | 		virtual ~AbstractArgument(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		LIBCMO_DISABLE_COPY_MOVE(AbstractArgument); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		template<class T> | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		T GetData() {  | 
					
						
							|  |  |  | 			return reinterpret_cast<T>(m_ParsedData);  | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 		virtual NodeType GetNodeType() override; | 
					
						
							|  |  |  | 		virtual bool IsConflictWith(AbstractNode* node) override; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	protected: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		virtual std::string GetHelpSymbol() override; | 
					
						
							|  |  |  | 		virtual bool BeginAccept(const std::string&, ArgumentsMap*) override; | 
					
						
							|  |  |  | 		virtual void EndAccept(ArgumentsMap*) override; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		virtual bool BeginParse(const std::string&) = 0; | 
					
						
							|  |  |  | 		virtual void EndParse() = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		std::string m_ArgName; | 
					
						
							|  |  |  | 		bool m_Accepted; | 
					
						
							|  |  |  | 		void* m_ParsedData; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * @brief Return true mean this value can accept. | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 	using IntLimit = std::function<bool(int32_t)>; | 
					
						
							|  |  |  | 	class IntArgument : public AbstractArgument { | 
					
						
							|  |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		using vType = int32_t; | 
					
						
							|  |  |  | 		IntArgument(const char* argname, IntLimit limit = nullptr) : | 
					
						
							|  |  |  | 			AbstractArgument(argname), m_IntLimit(limit) {} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		virtual ~IntArgument() {} | 
					
						
							|  |  |  | 		LIBCMO_DISABLE_COPY_MOVE(IntArgument); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected: | 
					
						
							|  |  |  | 		virtual bool BeginParse(const std::string&) override; | 
					
						
							|  |  |  | 		virtual void EndParse() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		IntLimit m_IntLimit; | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2023-02-13 10:57:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	class StringArgument : public AbstractArgument { | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		using vType = std::string; | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		StringArgument(const char* argname) :  | 
					
						
							|  |  |  | 			AbstractArgument(argname) {} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		virtual ~StringArgument() {} | 
					
						
							|  |  |  | 		LIBCMO_DISABLE_COPY_MOVE(StringArgument); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected: | 
					
						
							|  |  |  | 		virtual bool BeginParse(const std::string&) override; | 
					
						
							|  |  |  | 		virtual void EndParse() override; | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2023-02-13 16:52:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	class EncodingArgument : public AbstractArgument { | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		using vType = std::vector<std::string>; | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		EncodingArgument(const char* argname) :  | 
					
						
							|  |  |  | 			AbstractArgument(argname) {} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		virtual ~EncodingArgument() {} | 
					
						
							|  |  |  | 		LIBCMO_DISABLE_COPY_MOVE(EncodingArgument); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected: | 
					
						
							|  |  |  | 		virtual bool BeginParse(const std::string&) override; | 
					
						
							|  |  |  | 		virtual void EndParse() override; | 
					
						
							| 
									
										
										
										
											2023-03-03 11:06:26 +08:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2023-02-13 22:13:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	class ArgumentsMap { | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 		ArgumentsMap() : m_Data() {} | 
					
						
							|  |  |  | 		~ArgumentsMap() {} | 
					
						
							|  |  |  | 		LIBCMO_DISABLE_COPY_MOVE(ArgumentsMap); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void Add(const std::string& k, AbstractNode* v); | 
					
						
							|  |  |  | 		void Remove(const std::string& k); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		template<class _Ty> | 
					
						
							|  |  |  | 		_Ty* Get(const char* k) const { | 
					
						
							|  |  |  | 			if (k == nullptr) throw std::invalid_argument("Null argument name."); | 
					
						
							|  |  |  | 			std::string conv(k); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			auto finder = m_Data.find(conv); | 
					
						
							|  |  |  | 			if (finder == m_Data.end()) throw std::invalid_argument("No such argument name."); | 
					
						
							|  |  |  | 			AbstractNode* node = finder->second; | 
					
						
							|  |  |  | 			switch (node->GetNodeType()) { | 
					
						
							|  |  |  | 				case NodeType::Argument: | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 					return reinterpret_cast<_Ty*>(dynamic_cast<AbstractArgument*>(node)->GetData<_Ty*>()); | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 				case NodeType::Choice: | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 					return reinterpret_cast<_Ty*>(dynamic_cast<Choice*>(node)->GetIndex()); | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 				case NodeType::Literal: | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					throw std::runtime_error("No such argument type."); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected: | 
					
						
							|  |  |  | 		std::unordered_map<std::string, AbstractNode*> m_Data; | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |