#include "stdafx.h" #include "reflection/type.h" #include "reflection/member.h" #include namespace RBX { namespace Reflection { size_t StringHashPredicate::operator ()(const char* s) const { return boost::hash_range(s, s + strlen(s)); } std::ostream& operator<<( std::ostream& os, const Type& type ) { return os << "Type::" << type.name; } template<> const Type& Type::getSingleton >() { static TType > type("Array"); return type; } template<> const Type& Type::getSingleton() { static TType > type("Variant"); return type; } template<> Variant& Variant::convert(void) { return *this; } template<> shared_ptr& Variant::convert >(void) { shared_ptr* v = tryCast >(); if (v) return *v; shared_ptr* t = tryCast >(); if (t) { // empty table is the same as an empty array. (This makes Lua easier, since an empty Lua table could be either) if ((*t)->size()==0) { value = shared_ptr(new ValueArray()); _type = &Type::singleton >(); return cast >(); } } throw std::runtime_error("Unable to cast to Array"); } template<> const Type& Type::getSingleton >() { static TType > type("Dictionary"); return type; } template<> shared_ptr& Variant::convert >(void) { shared_ptr* v = tryCast >(); if (v) return *v; shared_ptr* a = tryCast >(); if (a) { // empty array is the same as an empty table. (This makes Lua easier, since an empty Lua table could be either) if ((*a)->size()==0) { value = shared_ptr(new ValueTable()); _type = &Type::singleton >(); return cast >(); } } throw std::runtime_error("Unable to cast to Dictionary"); } template<> const Type& Type::getSingleton >() { static TType > type("Map"); return type; } template<> shared_ptr& Variant::convert >(void) { shared_ptr* v = tryCast >(); if (v==NULL) throw std::runtime_error("Unable to cast to Map"); return *v; } // Declare the "void" type now template<> const Type& Type::getSingleton() { static TType type("void"); return type; } static std::vector* allTypes; void Type::addToAllTypes() { static std::vector v; allTypes = &v; v.push_back(this); } const std::vector& Type::getAllTypes() { return *allTypes; } SignatureDescriptor::SignatureDescriptor() :resultType(&Type::singleton()) { } SignatureDescriptor::Item::Item(const RBX::Name* name, const Type* type, const Variant& defaultValue) :name(name) ,type(type) ,defaultValue(defaultValue) { // Arguments must be camelCase RBXASSERT(name->c_str()[0] == tolower(name->c_str()[0])); } SignatureDescriptor::Item::Item(const RBX::Name* name, const Type* type) :name(name) ,type(type) ,defaultValue() { // Arguments must be camelCase RBXASSERT(name->c_str()[0] == tolower(name->c_str()[0])); RBXASSERT(defaultValue.isVoid()); } void SignatureDescriptor::addArgument(const RBX::Name& name, const Type& type) { Item i(&name, &type); arguments.push_back(i); } void SignatureDescriptor::addArgument(const RBX::Name& name, const Type& type, const Variant& defaultValue) { RBXASSERT(defaultValue.isVoid() || defaultValue.type()==type); Item i(&name, &type, defaultValue); arguments.push_back(i); } }} // namespace