49 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			49 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
#include <string>
 | 
						|
#include "convert.h"
 | 
						|
namespace refl {
 | 
						|
	template <typename To, typename From>
 | 
						|
	inline bool Convert::ConvertTo(Any& to, const Any& from) {
 | 
						|
		if constexpr (std::is_same_v<To, std::string>) {
 | 
						|
			if constexpr (std::is_same_v<From, char>) {
 | 
						|
				std::construct_at(to.CastTo<To*>(), from.CastTo<From*>());
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
		else if constexpr (std::is_arithmetic_v<To>) {
 | 
						|
			if constexpr (std::is_arithmetic_v<From>) {
 | 
						|
				*to.CastTo<To*>() = (To)*from.CastTo<From*>();
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	inline ConvertMap Convert::BuildClassMap()
 | 
						|
	{
 | 
						|
		ConvertMap classMap;
 | 
						|
#define RegisterToFrom(To, From) classMap.emplace(std::make_pair(&TypeInfo<To>::StaticClass, &TypeInfo<From>::StaticClass), &Convert::ConvertTo<To, From>);\
 | 
						|
		classMap.emplace(std::make_pair(&TypeInfo<From>::StaticClass, &TypeInfo<To>::StaticClass), &Convert::ConvertTo<From, To>)
 | 
						|
 | 
						|
		RegisterToFrom(int, uint32_t);
 | 
						|
		RegisterToFrom(int, uint16_t);
 | 
						|
		RegisterToFrom(int, float);
 | 
						|
		RegisterToFrom(int, double);
 | 
						|
		RegisterToFrom(float, uint32_t);
 | 
						|
		RegisterToFrom(float, double);
 | 
						|
		RegisterToFrom(std::string, char);
 | 
						|
#undef RegisterToFrom
 | 
						|
		return classMap;
 | 
						|
	}
 | 
						|
	inline bool Convert::Construct(Any& to,const Any& from)
 | 
						|
	{
 | 
						|
		if (to.Construct(from))
 | 
						|
			return true;
 | 
						|
		auto it = ClassMap.find(std::make_pair(to.cls, from.cls));
 | 
						|
		if (it != ClassMap.end()) {
 | 
						|
			return it->second(to, from);
 | 
						|
		}
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
} |