#pragma once
#include <string>
#include "type.h"
#include "../std/sarray.h"
namespace refl {
	class UClass;
	class FieldPtr;
	//生命周期短，适用于传参，不建议保存数据
	//只能指向指针，引用=>指针，指针=>指针，T => T*,T的类型丢失
	struct ArgsView {
	public:
		const void* val;
		const UClass* cls;
		constexpr ArgsView() : val(nullptr), cls(nullptr) {}
		//右值=>右值压入栈，caller入栈地址
		//左值=>caller变量地址
		template<typename T>
		constexpr ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){
			if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
				val = v.val;
				cls = v.cls;
			}
		}
		template<typename T>
		constexpr ArgsView(T* v) : val(v), cls(&TypeInfo<args_type_t<T>*>::StaticClass) {
		}
		template<typename T>//参数 T* => T*
		constexpr inline T cast_to() const {
			if constexpr (std::is_pointer_v<T>) {
				return (T)val;
			}
			else if constexpr (std::is_reference_v<T>){
				using RT = std::remove_reference_t<T>;
				return *(RT*)val;
			}else{
				return *(T*)val;
			}
		}
		template<typename T>
		T cast_ret() const {
			if constexpr (std::is_pointer_v<T>) {
				return *(T*)val;
			}
			else if constexpr (std::is_reference_v<T>) {
				using RT = std::remove_reference_t<T>;
				return **(RT**)val;
			}
			else {
				return *(T*)val;
			}
		}
		bool ConvertTo(const UClass* toClass);
	};
	//存入的是真实的数据类型,type用于拷贝数据
	struct ArgsValue : public ArgsView {
		const UClass* type;
		template<typename T>
		constexpr ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo<args_type_t<T>>::StaticClass){}
	};
	struct ArgsValueList{
		void* data;
		ArgsView* ptr;
		int num;
		bool isMemoryOwner{false};
		ArgsValueList(const sarray<ArgsValue>& args,void* memory = nullptr);
		~ArgsValueList();
		constexpr static int GetArgsSize(const sarray<ArgsValue>& args);
	};
	class ObjectView {
	public:
		const void* ptr;
		const UClass* cls;
		const FieldPtr* cache{ nullptr };
		ObjectView(const void* ptr, const UClass* cls) : ptr(ptr), cls(cls) {}
	public:

		template<typename T>
		bool Get(const Name& name, T& t);

		template<typename T>
		bool Set(const Name& name, const T& t);

		bool Invoke(const Name& name,const sarray<ArgsView>& ArgsList);//这里是内存分配慢呀，这里是可以改成栈容器的

		bool Invoke(const Name& name,std::vector<ArgsView>& ArgsList);

		ObjectView Parent();
	};
}