#ifndef XNA_CSHARP_TYPE_HPP #define XNA_CSHARP_TYPE_HPP #include "../default.hpp" #include "object.hpp" #include <type_traits> #include <typeinfo> #include <map> namespace xna { class Type : public Object { public: constexpr String FullName() const { return fullName; } constexpr bool IsClass() const { return isClass; } constexpr bool IsEnum() const { return isEnum; } constexpr bool IsValueType() const { return isValueType; } constexpr bool IsPrimitive() const { return isPrimitive; } virtual size_t GetHashCode() const; constexpr bool operator==(const Type& other) const { return fullName == other.fullName && isClass == other.isClass && isEnum == other.isEnum && isValueType == other.isValueType && isPrimitive == other.isPrimitive; } bool operator()(Type const& t1, Type const& t2) const { return t1.GetHashCode() < t2.GetHashCode(); } template <class T> friend sptr<Type> typeof(); public: inline static auto NameOfRegisteredTypes = std::map<std::string, sptr<Type>>(); private: String fullName; bool isClass{ false }; bool isEnum{ false }; bool isValueType{ false }; bool isPrimitive{ false }; }; template <class T> inline sptr<Type> typeof() { if (std::is_arithmetic<T>::value) { auto primitiveType = New<Type>(); primitiveType->fullName = typeid(T).name(); primitiveType->isPrimitive = true; primitiveType->isValueType = true; return primitiveType; } if (std::is_enum<T>::value) { auto enumType = New<Type>(); enumType->fullName = typeid(T).name(); enumType->isValueType = true; enumType->isEnum = true; return enumType; } if (std::is_class<T>::value) { auto classType = New<Type>(); classType->fullName = typeid(T).name(); classType->isClass = true; return classType; } return nullptr; } template <class T> inline sptr<Type> typeof(T const* object) { return typeof<T>(); } template <class T> inline sptr<Type> typeof(T const& object) { return typeof<T>(); } } #endif