From 28d31c96b65f6a93bbe4c52250e9fc8f8e370f16 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 9 Dec 2004 05:28:20 +0000 Subject: [PATCH] Added Marco Jez's osgIntrospection + osgWrapper libs with osgintrospection example --- examples/osgintrospection/GNUmakefile | 16 + examples/osgintrospection/GNUmakefile.inst | 11 + .../osgintrospection/osgintrospection.cpp | 227 ++ include/osgIntrospection/Attributes | 246 ++ include/osgIntrospection/CustomAttribute | 17 + .../osgIntrospection/CustomAttributeProvider | 112 + include/osgIntrospection/Exceptions | 189 ++ include/osgIntrospection/Export | 43 + include/osgIntrospection/MethodInfo | 126 + include/osgIntrospection/ParameterInfo | 96 + include/osgIntrospection/PropertyInfo | 262 ++ include/osgIntrospection/ReaderWriter | 271 ++ include/osgIntrospection/Reflection | 81 + include/osgIntrospection/ReflectionMacros | 323 +++ include/osgIntrospection/Reflector | 523 ++++ include/osgIntrospection/Type | 408 +++ include/osgIntrospection/TypedMethodInfo | 2243 +++++++++++++++++ include/osgIntrospection/Value | 427 ++++ include/osgIntrospection/variant_cast | 63 + .../CustomAttributeProvider.cpp | 43 + src/osgIntrospection/DefaultReflectors.cpp | 33 + src/osgIntrospection/GNUmakefile | 20 + src/osgIntrospection/MethodInfo.cpp | 15 + src/osgIntrospection/PropertyInfo.cpp | 233 ++ src/osgIntrospection/Reflection.cpp | 78 + src/osgIntrospection/Type.cpp | 247 ++ src/osgIntrospection/Value.cpp | 87 + src/osgWrappers/GNUmakefile | 7 + src/osgWrappers/osg/BlendFunc.cpp | 37 + src/osgWrappers/osg/Drawable.cpp | 13 + src/osgWrappers/osg/GNUmakefile | 24 + src/osgWrappers/osg/Geode.cpp | 12 + src/osgWrappers/osg/Geometry.cpp | 16 + src/osgWrappers/osg/Group.cpp | 12 + src/osgWrappers/osg/Material.cpp | 31 + src/osgWrappers/osg/Node.cpp | 23 + src/osgWrappers/osg/Object.cpp | 23 + src/osgWrappers/osg/StateAttribute.cpp | 65 + src/osgWrappers/osg/StateSet.cpp | 53 + src/osgWrappers/osg/Vec2.cpp | 10 + 40 files changed, 6766 insertions(+) create mode 100644 examples/osgintrospection/GNUmakefile create mode 100644 examples/osgintrospection/GNUmakefile.inst create mode 100644 examples/osgintrospection/osgintrospection.cpp create mode 100644 include/osgIntrospection/Attributes create mode 100644 include/osgIntrospection/CustomAttribute create mode 100644 include/osgIntrospection/CustomAttributeProvider create mode 100644 include/osgIntrospection/Exceptions create mode 100644 include/osgIntrospection/Export create mode 100644 include/osgIntrospection/MethodInfo create mode 100644 include/osgIntrospection/ParameterInfo create mode 100644 include/osgIntrospection/PropertyInfo create mode 100644 include/osgIntrospection/ReaderWriter create mode 100644 include/osgIntrospection/Reflection create mode 100644 include/osgIntrospection/ReflectionMacros create mode 100644 include/osgIntrospection/Reflector create mode 100644 include/osgIntrospection/Type create mode 100644 include/osgIntrospection/TypedMethodInfo create mode 100644 include/osgIntrospection/Value create mode 100644 include/osgIntrospection/variant_cast create mode 100644 src/osgIntrospection/CustomAttributeProvider.cpp create mode 100644 src/osgIntrospection/DefaultReflectors.cpp create mode 100644 src/osgIntrospection/GNUmakefile create mode 100644 src/osgIntrospection/MethodInfo.cpp create mode 100644 src/osgIntrospection/PropertyInfo.cpp create mode 100644 src/osgIntrospection/Reflection.cpp create mode 100644 src/osgIntrospection/Type.cpp create mode 100644 src/osgIntrospection/Value.cpp create mode 100644 src/osgWrappers/GNUmakefile create mode 100644 src/osgWrappers/osg/BlendFunc.cpp create mode 100644 src/osgWrappers/osg/Drawable.cpp create mode 100644 src/osgWrappers/osg/GNUmakefile create mode 100644 src/osgWrappers/osg/Geode.cpp create mode 100644 src/osgWrappers/osg/Geometry.cpp create mode 100644 src/osgWrappers/osg/Group.cpp create mode 100644 src/osgWrappers/osg/Material.cpp create mode 100644 src/osgWrappers/osg/Node.cpp create mode 100644 src/osgWrappers/osg/Object.cpp create mode 100644 src/osgWrappers/osg/StateAttribute.cpp create mode 100644 src/osgWrappers/osg/StateSet.cpp create mode 100644 src/osgWrappers/osg/Vec2.cpp diff --git a/examples/osgintrospection/GNUmakefile b/examples/osgintrospection/GNUmakefile new file mode 100644 index 000000000..82829c3f3 --- /dev/null +++ b/examples/osgintrospection/GNUmakefile @@ -0,0 +1,16 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgintrospection.cpp\ + +LIBS += -losgIntrospection -losgDB -losgUtil -losg $(GL_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgintrospection + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgintrospection/GNUmakefile.inst b/examples/osgintrospection/GNUmakefile.inst new file mode 100644 index 000000000..41a66ef0e --- /dev/null +++ b/examples/osgintrospection/GNUmakefile.inst @@ -0,0 +1,11 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgintrospection.cpp\ + +LIBS += -losgIntrospection -losgDB -losgUtil -losg $(GL_LIBS) $(OTHER_LIBS) + +EXEC = osgintrospection + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgintrospection/osgintrospection.cpp b/examples/osgintrospection/osgintrospection.cpp new file mode 100644 index 000000000..9cd0ed1af --- /dev/null +++ b/examples/osgintrospection/osgintrospection.cpp @@ -0,0 +1,227 @@ +#include + +#include +#include +#include +#include + +#include + +#include + +using namespace osgIntrospection; + + +// borrowed from osgDB... +std::string createLibraryNameForWrapper(const std::string& ext) +{ +#if defined(WIN32) + // !! recheck evolving Cygwin DLL extension naming protocols !! NHV + #ifdef __CYGWIN__ + return "cygosgwrapper_"+ext+".dll"; + #elif defined(__MINGW32__) + return "libosgwrapper_"+ext+".dll"; + #else + #ifdef _DEBUG + return "osgwrapper_"+ext+"d.dll"; + #else + return "osgwrapper_"+ext+".dll"; + #endif + #endif +#elif macintosh + return "osgwrapper_"+ext; +#elif defined(__hpux__) + // why don't we use PLUGIN_EXT from the makefiles here? + return "osgwrapper_"+ext+".sl"; +#else + return "osgwrapper_"+ext+".so"; +#endif + +} + +void print_types() +{ + // get the map of types that have been reflected + const TypeMap &tm = Reflection::getTypes(); + + // iterate through the type map and display some + // details for each type + for (TypeMap::const_iterator i=tm.begin(); i!=tm.end(); ++i) + { + // ignore pointer types and undefined types + if (!i->second->isDefined() || i->second->isPointer()) + continue; + + // print the type name + std::cout << i->second->getQualifiedName() << "\n"; + + // check whether the type is abstract + if (i->second->isAbstract()) std::cout << "\t[abstract]\n"; + + // check whether the type is atomic + if (i->second->isAtomic()) std::cout << "\t[atomic]\n"; + + // check whether the type is an enumeration. If yes, display + // the list of enumeration labels + if (i->second->isEnum()) + { + std::cout << "\t[enum]\n"; + std::cout << "\tenumeration values:\n"; + const EnumLabelMap &emap = i->second->getEnumLabels(); + for (EnumLabelMap::const_iterator j=emap.begin(); j!=emap.end(); ++j) + { + std::cout << "\t\t" << j->second << " = " << j->first << "\n"; + } + } + + // if the type has one or more base types, then display their + // names + if (i->second->getNumBaseTypes() > 0) + { + std::cout << "\tderived from: "; + for (int j=0; jsecond->getNumBaseTypes(); ++j) + { + const Type &base = i->second->getBaseType(j); + std::cout << base.getQualifiedName() << " "; + } + std::cout << "\n"; + } + + // display a list of methods defined for the current type + const MethodInfoList &mil = i->second->getMethods(); + if (!mil.empty()) + { + std::cout << "\t* methods:\n"; + for (MethodInfoList::const_iterator j=mil.begin(); j!=mil.end(); ++j) + { + // get the MethodInfo object that describes the current + // method + const MethodInfo &mi = **j; + + std::cout << "\t "; + + // display the method's return type if defined + if (mi.getReturnType().isDefined()) + std::cout << mi.getReturnType().getQualifiedName() << " "; + else + std::cout << "[UNDEFINED TYPE] "; + + // display the method's name + std::cout << mi.getName() << "("; + + // display method's parameters + const ParameterInfoList ¶ms = mi.getParameters(); + for (ParameterInfoList::const_iterator k=params.begin(); k!=params.end(); ++k) + { + // get the ParameterInfo object that describes the + // current parameter + const ParameterInfo &pi = **k; + + // display the parameter's modifier + if (pi.isIn()) + std::cout << "IN"; + if (pi.isOut()) + std::cout << "OUT"; + if (pi.isIn() || pi.isOut()) + std::cout << " "; + + // display the parameter's type name + std::cout << pi.getParameterType().getQualifiedName(); + + // display the parameter's name if defined + if (!pi.getName().empty()) + std::cout << " " << pi.getName(); + + if ((k+1)!=params.end()) + std::cout << ", "; + } + std::cout << ")"; + if (mi.isConst()) + std::cout << " const"; + std::cout << "\n"; + } + } + + // display a list of properties defined for the current type + const PropertyInfoList &pil = i->second->getProperties(); + if (!pil.empty()) + { + std::cout << "\t* properties:\n"; + for (PropertyInfoList::const_iterator j=pil.begin(); j!=pil.end(); ++j) + { + // get the PropertyInfo object that describes the current + // property + const PropertyInfo &pi = **j; + + std::cout << "\t "; + + std::cout << "{"; + std::cout << (pi.canGet()? "G": " "); + std::cout << (pi.canSet()? "S": " "); + std::cout << (pi.canCount()? "C": " "); + std::cout << (pi.canAdd()? "A": " "); + std::cout << "} "; + + // display the property's name + std::cout << pi.getName(); + + // display the property's value type if defined + std::cout << " ("; + if (pi.getPropertyType().isDefined()) + std::cout << pi.getPropertyType().getQualifiedName(); + else + std::cout << "UNDEFINED TYPE"; + std::cout << ") "; + + // check whether the property is an array property + if (pi.isArray()) + { + std::cout << " [ARRAY]"; + } + + // check whether the property is an indexed property + if (pi.isIndexed()) + { + std::cout << " [INDEXED]\n\t\t indices:\n"; + + const ParameterInfoList &ind = pi.getIndexParameters(); + + // print the list of indices + int num = 1; + for (ParameterInfoList::const_iterator k=ind.begin(); k!=ind.end(); ++k, ++num) + { + std::cout << "\t\t " << num << ") "; + const ParameterInfo &par = **k; + std::cout << par.getParameterType().getQualifiedName() << " " << par.getName(); + std::cout << "\n"; + } + } + + std::cout << "\n"; + } + } + std::cout << "\n" << std::string(75, '-') << "\n"; + } +} + +int main() +{ + // load the library of wrappers that reflect the + // classes defined in the 'osg' namespace. In the + // future this will be done automatically under + // certain circumstances (like deserialization). + osg::ref_ptr osg_reflectors = + osgDB::DynamicLibrary::loadLibrary(createLibraryNameForWrapper("osg")); + + // display a detailed list of reflected types + try + { + print_types(); + } + catch(const osgIntrospection::Exception &e) + { + std::cerr << e.what() << std::endl; + } + + return 0; +} diff --git a/include/osgIntrospection/Attributes b/include/osgIntrospection/Attributes new file mode 100644 index 000000000..86550a9cd --- /dev/null +++ b/include/osgIntrospection/Attributes @@ -0,0 +1,246 @@ +#ifndef OSGINTROSPECTION_ATTRIBUTES_ +#define OSGINTROSPECTION_ATTRIBUTES_ + +#include +#include +#include + +namespace osgIntrospection +{ + + /// By adding this attribute to a PropertyInfo you specify that there + /// is no default value for that property. + class NoDefaultValueAttribute: public CustomAttribute {}; + + + /// By adding this attribute to a PropertyInfo you specify a custom + /// default value for that property. + class DefaultValueAttribute: public CustomAttribute + { + public: + DefaultValueAttribute(const Value &v): v_(v) {} + const Value &getDefaultValue() const { return v_; } + private: + Value v_; + }; + + /// Base struct for custom property getters. Descendants may override + /// one or more of the get() methods to provide the means for retrieving + /// the value of a property. The first version of get() is used with + /// indexed properties, the second one serves simple properties and the + /// last one is used with array properties. + struct PropertyGetter + { + virtual Value get(const Value &instance, const ValueList &indices) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::IGET); } + virtual Value get(const Value &instance) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::GET); } + virtual Value get(const Value &instance, int i) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::AGET); } + virtual ~PropertyGetter() {} + }; + + /// By setting an attribute of this class you can specify a custom object + /// that will be used to retrieve the value of a property instead of the + /// default getter method. + class CustomPropertyGetAttribute: public CustomAttribute + { + public: + CustomPropertyGetAttribute(const PropertyGetter *getter) + : CustomAttribute(), getter_(getter) {} + + const PropertyGetter *getGetter() const { return getter_; } + + ~CustomPropertyGetAttribute() + { + delete getter_; + } + + private: + const PropertyGetter *getter_; + }; + + /// Base struct for custom property setters. Descendants may override + /// one or more of the set() methods to provide the means for setting + /// the value of a property. The first version of set() is used with + /// indexed properties, the second one serves simple properties and the + /// last one is used with array properties. + struct PropertySetter + { + virtual void set(Value &instance, ValueList &indices, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ISET); } + virtual void set(Value &instance, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::SET); } + virtual void set(Value &instance, int i, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ASET); } + virtual ~PropertySetter() {} + }; + + /// By setting an attribute of this class you can specify a custom object + /// that will be used to set the value of a property instead of the + /// default setter method. + class CustomPropertySetAttribute: public CustomAttribute + { + public: + CustomPropertySetAttribute(const PropertySetter *setter) + : CustomAttribute(), setter_(setter) {} + + const PropertySetter *getSetter() const { return setter_; } + + ~CustomPropertySetAttribute() + { + delete setter_; + } + + private: + const PropertySetter *setter_; + }; + + /// Base struct for custom array property counters. Descendants should + /// override the count() method which must return the number of items + /// in a chosen array property for the given instance. + struct PropertyCounter + { + virtual int count(const Value &instance) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::COUNT); } + virtual ~PropertyCounter() {} + }; + + /// By setting an attribute of this class you can specify a custom object + /// that will be used to count the number of items in an array property. + class CustomPropertyCountAttribute: public CustomAttribute + { + public: + CustomPropertyCountAttribute(const PropertyCounter *counter) + : CustomAttribute(), counter_(counter) {} + + const PropertyCounter *getCounter() const { return counter_; } + + ~CustomPropertyCountAttribute() + { + delete counter_; + } + + private: + const PropertyCounter *counter_; + }; + + /// Base struct for custom array property adders. Descendants should + /// override the add() method whose purpose is to add a new item to + /// an array property. + struct PropertyAdder + { + virtual void add(Value&, const Value&) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ADD); } + virtual ~PropertyAdder() {} + }; + + /// By setting an attribute of this class you can specify a custom object + /// that will be used to add a new item to an array property. + class CustomPropertyAddAttribute: public CustomAttribute + { + public: + CustomPropertyAddAttribute(const PropertyAdder *adder) + : CustomAttribute(), adder_(adder) {} + + const PropertyAdder *getAdder() const { return adder_; } + + ~CustomPropertyAddAttribute() + { + delete adder_; + } + + private: + const PropertyAdder *adder_; + }; + + + /// This struct allows customization of an indexed property's index set. + /// You must derive from this struct and provide a concrete implementation + /// of getIndexValueSet(), which must return (in parameter values) a list + /// of valid values to be used as indices. The whichindex parameter + /// specifies which index is being queried (0 = first index, 1 = second + /// index, ...). + /// See CustomIndexAttribute for details. + struct IndexInfo + { + virtual const ParameterInfoList &getIndexParameters() const = 0; + virtual void getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const = 0; + virtual ~IndexInfo() {} + }; + + + /// By default each index in an indexed property is assumed to be an + /// enumeration. When serialization is performed, indices are chosen + /// from the set of enum labels that were defined for the index type. + /// With this attribute you can provide custom code to determine the + /// set of values to be used as indices, instead of the default enum + /// values. This attribute is required, for example, when the number + /// and/or value of indices is not constant over time (such as in + /// associative containers). + class CustomIndexAttribute: public CustomAttribute + { + public: + CustomIndexAttribute(const IndexInfo *ii) + : CustomAttribute(), ii_(ii) {} + + const IndexInfo *getIndexInfo() const + { + return ii_; + } + + ~CustomIndexAttribute() + { + delete ii_; + } + + private: + const IndexInfo *ii_; + }; + + /// Attribute for overriding the type of a property with a custom + /// type. If you add this attribute to a PropertyInfo object, then + /// all subsequent calls to getValue()/getArrayItem()/getIndexedValue() + /// will perform a conversion from the actual property's type to + /// the custom type specified through this attribute. Similarly, all + /// methods in PropertyInfo that alter the property's value will accept + /// a value of the custom type instead of the actual type. In this + /// case the conversion is implicit and occurs later within the accessor + /// methods. + class PropertyTypeAttribute: public CustomAttribute + { + public: + PropertyTypeAttribute(const Type &type) + : CustomAttribute(), type_(type) {} + + const Type &getPropertyType() const + { + return type_; + } + + private: + const Type &type_; + }; + + /// Attribute for overriding the type of an index (of an indexed + /// property) with a custom type. Behaves like PropertyTypeAttribute, + /// but it affects the value of an index instead of the property's + /// value itself. + /// NOTE: property with custom indexing attributes are not affected + /// by this attribute! + class IndexTypeAttribute: public CustomAttribute + { + public: + IndexTypeAttribute(int whichindex, const Type &type) + : CustomAttribute(), wi_(whichindex), type_(type) {} + + int getWhichIndex() const + { + return wi_; + } + + const Type &getIndexType() const + { + return type_; + } + + private: + int wi_; + const Type &type_; + }; + +} + +#endif diff --git a/include/osgIntrospection/CustomAttribute b/include/osgIntrospection/CustomAttribute new file mode 100644 index 000000000..39bb80cca --- /dev/null +++ b/include/osgIntrospection/CustomAttribute @@ -0,0 +1,17 @@ +#ifndef OSGINTROSPECTION_CUSTOMATTRIBUTE_ +#define OSGINTROSPECTION_CUSTOMATTRIBUTE_ + +namespace osgIntrospection +{ + + /// The base class for custom attributes. This is an empty class + /// for now. + class CustomAttribute + { + public: + virtual ~CustomAttribute() {} + }; + +} + +#endif diff --git a/include/osgIntrospection/CustomAttributeProvider b/include/osgIntrospection/CustomAttributeProvider new file mode 100644 index 000000000..b47009258 --- /dev/null +++ b/include/osgIntrospection/CustomAttributeProvider @@ -0,0 +1,112 @@ +#ifndef OSGINTROSPECTION_CUSTOMATTRIBUTEPROVIDER_ +#define OSGINTROSPECTION_CUSTOMATTRIBUTEPROVIDER_ + +#include +#include + +#include +#include + +namespace osgIntrospection +{ + + // forward declarations + class Type; + class CustomAttribute; + class CustomAttributeProvider; + + // vector of attributes + typedef std::vector CustomAttributeList; + + // vector of attribute providers + typedef std::vector CustomAttributeProviderList; + + + /// This is the base class for custom attribute providers, that is objects + /// that can be assigned a list of custom attributes. Methods defined in + /// this class provide the means for adding, retrieving and searching for + /// attributes. + class OSGINTROSPECTION_EXPORT CustomAttributeProvider + { + public: + /// Returns the const list of custom attributes. + inline const CustomAttributeList &getCustomAttributes() const + { + return attribs_; + } + + /// Returns the list of custom attributes. + inline CustomAttributeList &getCustomAttributes() + { + return attribs_; + } + + /// Adds a new attribute to the list. + inline CustomAttributeProvider *addAttribute(const CustomAttribute *attr) + { + attribs_.push_back(attr); + return this; + } + + /// Returns whether at least one attribute of the given type is + /// present in the attribute list. If the inherit parameter is + /// set to true, the search is forwarded to base types. + bool isDefined(const Type &type, bool inherit) const; + + /// Returns whether at least one attribute of the given type is + /// present in the attribute list. If the inherit parameter is + /// set to true, the search is forwarded to base types. + /// [template version] + template inline bool isDefined(bool inherit) const + { + for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i) + if (typeid(**i) == typeid(T)) return true; + if (inherit) + { + CustomAttributeProviderList providers; + getInheritedProviders(providers); + for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i) + { + if ((*i)->isDefined(true)) return true; + } + } + return false; + } + + /// Searchs for an attribute of the given type and returns a pointer + /// to it if found, a null pointer otherwise. If the inherit parameter + /// is set to true, the search is forwarded to base types. + const CustomAttribute *getAttribute(const Type &type, bool inherit) const; + + /// Searchs for an attribute of the given type and returns a pointer + /// to it if found, a null pointer otherwise. If the inherit parameter + /// is set to true, the search is forwarded to base types. + /// [template version] + template inline const T *getAttribute(bool inherit) const + { + for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i) + if (typeid(**i) == typeid(T)) return static_cast(*i); + if (inherit) + { + CustomAttributeProviderList providers; + getInheritedProviders(providers); + for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i) + { + const T *ca = (*i)->getAttribute(true); + if (ca) return ca; + } + } + return 0; + } + + protected: + virtual void getInheritedProviders(CustomAttributeProviderList &providers) const = 0; + virtual ~CustomAttributeProvider() {} + + private: + CustomAttributeList attribs_; + }; + +} + +#endif diff --git a/include/osgIntrospection/Exceptions b/include/osgIntrospection/Exceptions new file mode 100644 index 000000000..b005c64fc --- /dev/null +++ b/include/osgIntrospection/Exceptions @@ -0,0 +1,189 @@ +#ifndef OSGINTROSPECTION_EXCEPTIONS_ +#define OSGINTROSPECTION_EXCEPTIONS_ + +#include +#include + +namespace osgIntrospection +{ + + class Exception + { + public: + Exception(const std::string &msg): msg_(msg) {} + const std::string &what() const throw() { return msg_; } + + private: + std::string msg_; + }; + + struct ReflectionException: public Exception + { + ReflectionException(const std::string &msg): Exception(msg) {} + }; + + struct TypeNotDefinedException: public ReflectionException + { + TypeNotDefinedException(const std::type_info &ti) + : ReflectionException("type `" + std::string(ti.name()) + "' is declared but not defined") + { + } + }; + + struct TypeIsAbstractException: public ReflectionException + { + TypeIsAbstractException(const std::type_info &ti) + : ReflectionException("cannot create instances of abstract type `" + std::string(ti.name()) + "'") + { + } + }; + + struct InvalidFunctionPointerException: public ReflectionException + { + InvalidFunctionPointerException() + : ReflectionException("invalid function pointer during invoke()") + { + } + }; + + struct ConstIsConstException: public ReflectionException + { + ConstIsConstException() + : ReflectionException("cannot modify a const value") + { + } + }; + + struct EmptyValueException: public ReflectionException + { + EmptyValueException() + : ReflectionException("cannot retrieve an empty value") + { + } + }; + + struct TypeNotFoundException: public ReflectionException + { + TypeNotFoundException(const std::string &qname) + : ReflectionException("type `" + qname + "' not found") + { + } + }; + + struct MethodNotFoundException: public ReflectionException + { + MethodNotFoundException(const std::string &name, const std::string &cname) + : ReflectionException("could not find a suitable method of name `" + name + "' in class `" + cname + "'") + { + } + }; + + struct StreamWriteErrorException: public ReflectionException + { + StreamWriteErrorException() + : ReflectionException("an error occured while trying to write to a stream") + { + } + }; + + struct StreamReadErrorException: public ReflectionException + { + StreamReadErrorException() + : ReflectionException("an error occured while trying to read from a stream") + { + } + }; + + class StreamingNotSupportedException: public ReflectionException + { + public: + enum OperationType + { + ANY, + TEXT_WRITE, + TEXT_READ, + BINARY_WRITE, + BINARY_READ + }; + + StreamingNotSupportedException(OperationType op, const std::type_info &type) + : ReflectionException(build_msg(op, type)) + { + } + + private: + std::string build_msg(OperationType op, const std::type_info &type) + { + std::string opstr; + switch (op) + { + case TEXT_WRITE: opstr = "writing to text stream"; break; + case TEXT_READ: opstr = "reading from text stream"; break; + case BINARY_WRITE: opstr = "writing to binary stream"; break; + case BINARY_READ: opstr = "reading from binary stream"; break; + case ANY: + default: opstr = "streaming"; + } + return opstr + std::string(" is not supported on type `" + std::string(type.name()) + "'"); + } + }; + + struct TypeConversionException: public ReflectionException + { + TypeConversionException(const std::type_info &type1, const std::type_info &type2) + : ReflectionException("cannot convert from type `" + std::string(type1.name()) + "' to type `" + std::string(type2.name()) + "'") + { + } + }; + + class PropertyAccessException: public ReflectionException + { + public: + enum AccessType + { + GET, + SET, + IGET, + ISET, + AGET, + ASET, + ADD, + COUNT + }; + + PropertyAccessException(const std::string &pname, AccessType denied) + : ReflectionException(build_msg(pname, denied)) + { + } + + private: + std::string build_msg(const std::string &pname, AccessType denied) const + { + std::string msg; + switch (denied) + { + case GET: msg = "retrieved"; break; + case SET: msg = "set"; break; + case IGET: msg = "retrieved with indices"; break; + case ISET: msg = "set with indices"; break; + case AGET: msg = "retrieved with array index"; break; + case ASET: msg = "set with array index"; break; + case ADD: msg = "added"; break; + case COUNT: msg = "counted"; break; + default: msg = "?"; + } + return std::string("value for property `" + pname + "' cannot be " + msg); + } + }; + + struct IndexValuesNotDefinedException: ReflectionException + { + IndexValuesNotDefinedException(const std::string &name, const std::string &iname) + : ReflectionException("couldn't determine a finite set of values for index `" + iname + "' of property `" + name + "'. Make sure that either: 1) the index is an enumeration, or 2) a valid custom indexing attribute was assigned to the property.") + { + } + }; + +} + +#endif diff --git a/include/osgIntrospection/Export b/include/osgIntrospection/Export new file mode 100644 index 000000000..e121f5f2c --- /dev/null +++ b/include/osgIntrospection/Export @@ -0,0 +1,43 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGINTROSPECTION_EXPORTHDR +#define OSGINTROSPECTION_EXPORTHDR 1 + +// define USE_DEPRECATED_API is used to include in API which is being fazed out +// if you can compile your apps with this turned off you are +// well placed for compatablity with future versions. +//#define USE_DEPRECATED_API + +#if defined(_MSC_VER) + #pragma warning(disable : 4251) +#endif + +#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__) + # ifdef OSGINTROSPECTION_LIBRARY + # define OSGINTROSPECTION_EXPORT __declspec(dllexport) + # else + # define OSGINTROSPECTION_EXPORT __declspec(dllimport) + # endif /* OSGINTROSPECTION_LIBRARY */ +#else + # define OSGINTROSPECTION_EXPORT +#endif + +// set up define for whether member templates are supported by VisualStudio compilers. +#ifdef _MSC_VER +# if (_MSC_VER < 1300) +# error Your compiler doesn't support member templates. The reflection framework can't be compiled. +# endif +#endif + +#endif diff --git a/include/osgIntrospection/MethodInfo b/include/osgIntrospection/MethodInfo new file mode 100644 index 000000000..e233c7a02 --- /dev/null +++ b/include/osgIntrospection/MethodInfo @@ -0,0 +1,126 @@ +#ifndef OSGINTROSPECTION_METHODINFO_ +#define OSGINTROSPECTION_METHODINFO_ + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace osgIntrospection +{ + + class Type; + + /// Class MethodInfo stores information about a class method. It is an + /// abstract class, so it must be derived to provide the actual + /// implementation of isConst() and invoke(). Instances of this class + /// can't be modified after their creation. + class OSGINTROSPECTION_EXPORT MethodInfo: public CustomAttributeProvider + { + public: + /// Direct initialization constructor. + inline MethodInfo(const std::string &qname, const Type &decltype, const Type &rtype, const ParameterInfoList &plist); + + /// Returns the Type object associated to the type that + /// declares the reflected method. + inline virtual const Type &getDeclaringType() const; + + /// Returns the name of the reflected method. + inline virtual const std::string &getName() const; + + /// Returns the return type of the reflected method. + inline const Type &getReturnType() const; + + /// Returns a list of objects that describe the reflected + /// method's parameters. + inline const ParameterInfoList &getParameters() const; + + /// Returns whether the reflected method is const or not. + virtual bool isConst() const = 0; + + /// Invokes the reflected method dynamically on the given const + /// instance, passing it the arguments as a list of Value objects. + virtual Value invoke(const Value &instance, ValueList &args) const = 0; + + /// Invokes the reflected method dynamically on the given instance, + /// passing it the arguments as a list of Value objects. + virtual Value invoke(Value &instance, ValueList &args) const = 0; + + /// Invokes the reflected method dynamically on the given const + /// instance, without arguments. + inline Value invoke(const Value &instance) const; + + /// Invokes the reflected method dynamically on the given + /// instance, without arguments. + inline Value invoke(Value &instance) const; + + private: + inline std::string strip_namespace(const std::string &s) const; + + virtual void getInheritedProviders(CustomAttributeProviderList &providers) const; + + std::string name_; + const Type &decltype_; + const Type &rtype_; + ParameterInfoList params_; + }; + + // INLINE METHODS + + inline MethodInfo::MethodInfo(const std::string &qname, const Type &decltype, const Type &rtype, const ParameterInfoList &plist) + : CustomAttributeProvider(), + decltype_(decltype), + rtype_(rtype), + params_(plist) + { + name_ = strip_namespace(qname); + } + + inline std::string MethodInfo::strip_namespace(const std::string &s) const + { + std::string::size_type p = s.rfind("::"); + if (p != std::string::npos) + return s.substr(p+2); + return s; + } + + inline const std::string &MethodInfo::getName() const + { + return name_; + } + + inline const Type &MethodInfo::getDeclaringType() const + { + return decltype_; + } + + inline const Type &MethodInfo::getReturnType() const + { + return rtype_; + } + + inline const ParameterInfoList &MethodInfo::getParameters() const + { + return params_; + } + + inline Value MethodInfo::invoke(const Value &instance) const + { + ValueList args; + return invoke(instance, args); + } + + inline Value MethodInfo::invoke(Value &instance) const + { + ValueList args; + return invoke(instance, args); + } + +} + +#endif diff --git a/include/osgIntrospection/ParameterInfo b/include/osgIntrospection/ParameterInfo new file mode 100644 index 000000000..cc86d1d0b --- /dev/null +++ b/include/osgIntrospection/ParameterInfo @@ -0,0 +1,96 @@ +#ifndef OSGINTROSPECTION_PARAMETERINFO_ +#define OSGINTROSPECTION_PARAMETERINFO_ + +#include +#include + +#include +#include + +namespace osgIntrospection +{ + + /// This class stores information about a function parameter. A parameter + /// is defined by its name, its type, its position within the parameter + /// list, and zero or more attributes. Attributes describe how the + /// parameter behave, for example whether it is an input or an output + /// parameter. + class ParameterInfo + { + public: + enum ParameterAttributes + { + NONE = 0, + + IN = 1, // parameter is used to pass data to the function + OUT = 2, // parameter is used to return data from the function + + INOUT = IN | OUT + }; + + /// Direct initialization constructor. + inline ParameterInfo(const std::string &name, const Type &type, int position, int attribs); + + /// Returns the parameter's name. + inline const std::string &getName() const; + + /// Return the parameter's position within the function's parameter + /// list. This position is zero-based. + inline int getPosition() const; + + /// Returns the parameter's type. + inline const Type &getParameterType() const; + + /// Returns the parameter's attributes. + inline int getAttributes() const; + + /// Returns whether the parameter has the IN attribute. + inline bool isIn() const { return (attribs_ & IN) != 0; } + + /// Returns whether the parameter has the OUT attribute. + inline bool isOut() const { return (attribs_ & OUT) != 0; } + + /// Returns whether the parameter has both the IN and the + /// OUT attribute. + inline bool isInOut() const { return isIn() && isOut(); } + + private: + std::string name_; + const Type &type_; + int position_; + int attribs_; + }; + + // INLINE METHODS + + inline ParameterInfo::ParameterInfo(const std::string &name, const Type &type, int position, int attribs) + : name_(name), + type_(type), + position_(position), + attribs_(attribs) + { + } + + inline const std::string &ParameterInfo::getName() const + { + return name_; + } + + inline int ParameterInfo::getPosition() const + { + return position_; + } + + inline const Type &ParameterInfo::getParameterType() const + { + return type_; + } + + inline int ParameterInfo::getAttributes() const + { + return attribs_; + } + +} + +#endif diff --git a/include/osgIntrospection/PropertyInfo b/include/osgIntrospection/PropertyInfo new file mode 100644 index 000000000..eaea961af --- /dev/null +++ b/include/osgIntrospection/PropertyInfo @@ -0,0 +1,262 @@ +#ifndef OSGINTROSPECTION_PROPERTYINFO_ +#define OSGINTROSPECTION_PROPERTYINFO_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace osgIntrospection +{ + + /// This class keeps information about a class' property. A property is + /// defined by a name and a set of methods that store and retrieve + /// values. When the user wants to "get" the value of a property, the + /// getter method will be invoked and its value returned. When the user + /// wants to "set" the value of a property, the setter method will be + /// called. There are three kinds of property: simple (get/set), indexed + /// (get[i1, i2, ...]/set[i1, i2, ...]), and array (count/add/get[i]/ + /// set[i]). + /// Objects of class PropertyInfo can't be modified once they have been + /// created, but they can be queried without restrictions. You can either + /// retrieve the accessor methods and invoke them manually, or you can + /// call getValue() / setValue() etc. methods to perform direct operations + /// on the property, given an instance of the declaring type to work on. + /// The latter technique is preferred because it checks for custom + /// attributes associated to the PropertyInfo object and passes control + /// to them when needed. + /// + class OSGINTROSPECTION_EXPORT PropertyInfo: public CustomAttributeProvider + { + public: + /// Direct initialization constructor for simple and indexed + /// properties. + /// You must pass the Type object associated to the class that + /// declares the property, the Type object that describes the + /// type of the property's value, the property name and the + /// getter/setter methods. Either the setter or the getter can + /// be null, meaning a restricted access. If both are null, the + /// user is expected to add a custom accessor attribute to this + /// PropertyInfo object. + /// If the getter method has parameters, the property is considered + /// to be indexed. The same is true if the getter is null and the + /// setter has more than one parameter. + PropertyInfo(const Type &decltype, const Type &ptype, const std::string &name, const MethodInfo *getm, const MethodInfo *setm) + : CustomAttributeProvider(), + decltype_(decltype), + ptype_(ptype), + name_(name), + getm_(getm), + setm_(setm), + numm_(0), + addm_(0), + is_array_(false) + { + if (getm_) + { + for (ParameterInfoList::size_type i=0; igetParameters().size(); ++i) + indices_.push_back(getm_->getParameters().at(i)); + } + else + { + if (setm_) + { + for (ParameterInfoList::size_type i=0; i<(setm_->getParameters().size()-1); ++i) + indices_.push_back(setm_->getParameters().at(i)); + } + } + } + + /// Direct initialization constructor for "array" properties. + /// You must pass the Type object associated to the type that + /// declares the property, the Type object that describes the + /// type of the property's value, the property name and the + /// getter/setter/counter/adder methods. + PropertyInfo(const Type &decltype, const Type &ptype, const std::string &name, const MethodInfo *getm, const MethodInfo *setm, const MethodInfo *numm, const MethodInfo *addm) + : CustomAttributeProvider(), + decltype_(decltype), + ptype_(ptype), + name_(name), + getm_(getm), + setm_(setm), + numm_(numm), + addm_(addm), + is_array_(true) + { + } + + /// Returns the number of indices + inline int getNumIndices() const + { + return static_cast(getIndexParameters().size()); + } + + /// Returns the name of the property being described. + inline virtual const std::string &getName() const + { + return name_; + } + + /// Returns the type that declares the property. + inline virtual const Type &getDeclaringType() const + { + return decltype_; + } + + /// Returns the type of the reflected property. + inline const Type &getPropertyType() const + { + const PropertyTypeAttribute *pta = getAttribute(false); + if (pta) return pta->getPropertyType(); + return ptype_; + } + + /// Returns the getter method. + inline const MethodInfo *getGetMethod() const + { + return getm_; + } + + /// Returns the setter method. + inline const MethodInfo *getSetMethod() const + { + return setm_; + } + + /// Returns the counter method. + inline const MethodInfo *getCountMethod() const + { + return numm_; + } + + /// Returns the adder method. + inline const MethodInfo *getAddMethod() const + { + return addm_; + } + + /// Returns whether the property's value can be retrieved. + inline bool canGet() const + { + return (getm_ != 0) || isDefined(false); + } + + /// Returns whether the property's value can be set. + inline bool canSet() const + { + return setm_ != 0 || isDefined(false); + } + + /// Returns whether the property's array of values can be counted. + inline bool canCount() const + { + return numm_ != 0 || isDefined(false); + } + + /// Returns whether items can be added to the array property. + inline bool canAdd() const + { + return addm_ != 0 || isDefined(false); + } + + /// Returns whether the property is simple. + inline bool isSimple() const + { + return !isIndexed() && !isArray(); + } + + /// Returns whether the property is indexed. + inline bool isIndexed() const + { + return getNumIndices() > 0; + } + + /// Returns whether the property is an array. + inline bool isArray() const + { + return is_array_; + } + + /// Returns the list of index parameters. + /// If the property is not indexed, this list is empty. If neither + /// the get method nor the set method are defined, this list is + /// empty unless a custom indexing attribute is defined. + const ParameterInfoList &getIndexParameters() const; + + /// Returns a list of valid values that can be used for the specified + /// index. If a custom indexing attribute is defined for this property, + /// then it will be queried for the index set, otherwise the index + /// will be treated as an enumeration and the set of enumeration + /// values will be returned. + void getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const; + + /// Invokes the getter method on the given instance and + /// returns the property's value. If a custom getter attribute + /// is defined, it will be invoked instead. + Value getValue(const Value &instance) const; + + /// Invokes the setter method on the given instance and + /// sets the property's value. If a custom setter attribute + /// is defined, it will be invoked instead. + void setValue(Value &instance, const Value &value) const; + + /// Invokes the getter method on the given instance passing a list + /// of indices and returns the indexed property's value. If a custom + /// getter attribute is defined, it will be invoked instead. + Value getIndexedValue(const Value &instance, ValueList &indices) const; + + /// Invokes the setter method on the given instance passing a list + /// of indices and sets the indexed property's value. If a custom + /// setter attribute is defined, it will be invoked instead. + void setIndexedValue(Value &instance, ValueList &indices, const Value &value) const; + + /// Invokes the counter method on the given instance and returns + /// the number of items of the array property. If a custom counter + /// attribute is defined, it will be invoked instead. + int getNumArrayItems(const Value &instance) const; + + /// Invokes the getter method on the given instance and returns + /// the i-th item of the array property. If a custom getter attribute + /// us defined, it will be invoked instead. + Value getArrayItem(const Value &instance, int i) const; + + /// Invokes the setter method on the given instance and sets + /// the i-th item of the array property. If a custom setter attribute + /// is defined, it will be invoked instead. + void setArrayItem(Value &instance, int i, const Value &value) const; + + /// Invokes the adder method on the given instance and adds + /// an item to the array property. If a custom adder attribute is + /// defined, it will be invoked instead. + void addArrayItem(Value &instance, const Value &value) const; + + /// Returns the default value associated to the reflected property. + /// If no default value has been specified, this method tries to + /// create an instance of the property type and then returns its + /// value. There are some attributes that change the behavior of + /// this method, for example NoDefaultValueAttribute. + Value getDefaultValue() const; + + protected: + virtual void getInheritedProviders(CustomAttributeProviderList &providers) const; + + private: + const Type &decltype_; + const Type &ptype_; + std::string name_; + const MethodInfo *getm_; + const MethodInfo *setm_; + const MethodInfo *numm_; + const MethodInfo *addm_; + ParameterInfoList indices_; + bool is_array_; + }; + +} + +#endif diff --git a/include/osgIntrospection/ReaderWriter b/include/osgIntrospection/ReaderWriter new file mode 100644 index 000000000..5737dd11a --- /dev/null +++ b/include/osgIntrospection/ReaderWriter @@ -0,0 +1,271 @@ +#ifndef OSGINTROSPECTION_READERWRITER_ +#define OSGINTROSPECTION_READERWRITER_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace osg +{ + + /// ---------------------------------------------------------------------- + /// TEMPORARY FIX + /// (currently osg::Vec? classes don't support input streaming) + /// (currently osg::ref_ptr<> class doesn't support I/O streaming) + inline std::istream& operator >> (std::istream& input, Vec2f& vec) + { + input >> vec._v[0] >> vec._v[1]; + return input; + } + + inline std::istream& operator >> (std::istream& input, Vec3f& vec) + { + input >> vec._v[0] >> vec._v[1] >> vec._v[2]; + return input; + } + + inline std::istream& operator >> (std::istream& input, Vec4& vec) + { + input >> vec._v[0] >> vec._v[1] >> vec._v[2] >> vec._v[3]; + return input; + } + + template + std::ostream &operator << (std::ostream &s, const osg::ref_ptr &r) + { + return s << r.get(); + } + + template + std::istream &operator >> (std::istream &s, osg::ref_ptr &r) + { + void *ptr; + s >> ptr; + r = (T *)ptr; + return s; + } + + /// + /// END OF TEMPORARY FIX + /// ---------------------------------------------------------------------- +} + +namespace osgIntrospection +{ + + /// This is the base class for reader/writer objects. A ReaderWriter's + /// purpose is to provide the means for writing the content of a Value + /// object to a stream and for reading it back. Descendants can either + /// be specialized for just one data type or they can handle several + /// types, that's up to the implementor. A derived class is not required + /// to support all streaming operations (text write, text read, bin write + /// and bin read), it can implement just some of them, although full + /// support is strongly encouraged. + class ReaderWriter + { + public: + class Options + { + public: + Options(): fno_(false) {} + virtual ~Options() {} + + bool getForceNumericOutput() const { return fno_; } + void setForceNumericOutput(bool fno) { fno_ = fno; } + + private: + bool fno_; + }; + + /// Writes a textual representation of the value's content to a stream. + virtual std::ostream &writeTextValue(std::ostream &, const Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_WRITE, v.getType().getStdTypeInfo()); } + + /// Reads a textual representation of the value's content from a stream. + virtual std::istream &readTextValue(std::istream &, Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_READ, v.getType().getStdTypeInfo()); } + + /// Writes a binary representation of the value's content to a stream. + virtual std::ostream &writeBinaryValue(std::ostream &, const Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::BINARY_WRITE, v.getType().getStdTypeInfo()); } + + /// Reads a binary representation of the value's content from a stream. + virtual std::istream &readBinaryValue(std::istream &, Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::BINARY_READ, v.getType().getStdTypeInfo()); } + + /// Virtual destructor. + virtual ~ReaderWriter() {} + }; + + /// This class template provides basic default streaming capabilities + /// for all types that define streaming operators (<< and >>). Most of + /// the standard types are able to be read and written this way, so the + /// StdReaderWriter template can be a convenient default for several + /// types. The binary representation is a raw copy of the memory content. + /// + /// TO-DO: improve binary streaming and avoid arch dependency. + /// + template + class StdReaderWriter: public ReaderWriter + { + public: + virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options * = 0) const + { + return (os << variant_cast(v)); + } + + virtual std::istream &readTextValue(std::istream &is, Value &v, const Options * = 0) const + { + if (v.isEmpty()) v = Value(T()); + return (is >> variant_cast(v)); + } + + virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options * = 0) const + { + return os.write(reinterpret_cast(extract_raw_data(v)), sizeof(T)); + } + + virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options * = 0) const + { + if (v.isEmpty()) v = Value(T()); + return is.read(reinterpret_cast(extract_raw_data(v)), sizeof(T)); + } + + }; + + /// This ReaderWriter can be used to read and write enumeration values. + /// The textual representation will be the enum label, if found, or the + /// numerical value. The binary representation doesn't take label names + /// into account. + template + class EnumReaderWriter: public ReaderWriter + { + virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options *options = 0) const + { + int numeric = static_cast(variant_cast(v)); + + if (!options || !options->getForceNumericOutput()) + { + const Type &type = v.getType(); + const EnumLabelMap &elm = type.getEnumLabels(); + EnumLabelMap::const_iterator i = elm.find(numeric); + if (i != elm.end()) + { + os << i->second; + return os; + } + else + { + std::vector labels; + + // it could be a bitmask + for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i) + { + if (i->first != 0 && ((i->first & numeric) == i->first)) + { + numeric ^= i->first; + labels.push_back(i->second); + } + } + + // check whether all bits were discovered + if (numeric == 0) + { + for (std::vector::const_iterator i=labels.begin(); i!=labels.end(); ++i) + { + os << *i; + if ((i+1) != labels.end()) os << " | "; + } + return os; + } + } + } + + return os << numeric; + } + + virtual std::istream &readTextValue(std::istream &is, Value &v, const Options * = 0) const + { + if (v.isEmpty()) v = Value(T()); + + int i; + if (is >> i) + { + variant_cast(v) = static_cast(i); + return is; + } + + is.clear(); + + std::string s; + if (is >> s) + { + const Type &type = v.getType(); + const EnumLabelMap &elm = type.getEnumLabels(); + for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i) + { + if (i->second.compare(s) == 0) + { + variant_cast(v) = static_cast(i->first); + return is; + } + } + } + + return is; + } + + virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options *options = 0) const + { + return os.write(reinterpret_cast(extract_raw_data(v)), sizeof(T)); + } + + virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options *options = 0) const + { + if (v.isEmpty()) + v = Value(T()); + return is.read(reinterpret_cast(extract_raw_data(v)), sizeof(T)); + } + + }; + + /// This is a ReaderWriter class that can be used to read and write + /// pointer values. Note: template parameter T must be a pointer! + template + class PtrReaderWriter: public ReaderWriter + { + public: + virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options* = 0) const + { + return (os << (void*)variant_cast(v)); + } + + virtual std::istream &readTextValue(std::istream &is, Value &v, const Options* = 0) const + { + void *ptr; + is >> ptr; + v = Value(T(ptr)); + return is; + } + + virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options* = 0) const + { + return os.write(reinterpret_cast(extract_raw_data(v)), sizeof(T)); + } + + virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options* = 0) const + { + T ptr; + is.read(reinterpret_cast(&ptr), sizeof(T)); + v = Value(ptr); + return is; + } + }; + +} + +#endif diff --git a/include/osgIntrospection/Reflection b/include/osgIntrospection/Reflection new file mode 100644 index 000000000..1c3111577 --- /dev/null +++ b/include/osgIntrospection/Reflection @@ -0,0 +1,81 @@ +#ifndef OSGINTROSPECTION_REFLECTION_ +#define OSGINTROSPECTION_REFLECTION_ + +#include + +#include +#include + +/// This macro emulates the behavior of the standard typeid operator, +/// returning the Type object associated to the type of the given +/// expression. +#define typeof(expr) osgIntrospection::Reflection::getType(typeid(expr)) + +namespace osgIntrospection +{ + + class Type; + + /// This predicate compares two instances of std::type_info for equality. + /// Note that we can't rely on default pointer comparison because it is + /// not guaranteed that &typeid(T) always returns the same pointer for a + /// given T (thanks Andrew Koenig). + struct TypeInfoCmp + { + bool operator()(const std::type_info *t1, const std::type_info *t2) const + { + return t1->before(*t2) != 0; + } + }; + + /// A map of types, indexed by their associated type_info structure. + typedef std::map TypeMap; + + + /// This class provides basic reflection services such as registration + /// of new types and queries on the global type map. + class OSGINTROSPECTION_EXPORT Reflection + { + public: + /// Returns the Type object associated to the given type_info + /// structure. If the type hasn't been created yet it is + /// automatically created and added to the global type map. + /// Please note that such type will have the status of + /// "declared", you still need to give details about it through + /// a Reflector class before you can query it. + static const Type &getType(const std::type_info &ti); + + /// Finds a Type object given its qualified name, which must + /// be identical to the qualified name returned by that Type's + /// getQualifiedName() method. If the type hasn't been created + /// yet, an exception is thrown. + static const Type &getType(const std::string &qname); + + /// Returns the global map of types. + static const TypeMap &getTypes(); + + /// Return the Type object associated to the C++ type 'void'. + /// This is a shortcut for typeof(void), which may be slow if + /// the type map is large. + static const Type &type_void(); + + private: + template friend class Reflector; + + struct StaticData + { + TypeMap typemap; + const Type *type_void; + }; + + static StaticData &getOrCreateStaticData(); + static Type *registerType(const std::type_info &ti); + static Type *registerOrReplaceType(const std::type_info &ti); + + private: + static StaticData *staticdata__; + }; + +} + +#endif diff --git a/include/osgIntrospection/ReflectionMacros b/include/osgIntrospection/ReflectionMacros new file mode 100644 index 000000000..48147d09c --- /dev/null +++ b/include/osgIntrospection/ReflectionMacros @@ -0,0 +1,323 @@ +#ifndef OSGINTROSPECTION_REFLECTIONMACROS_ +#define OSGINTROSPECTION_REFLECTIONMACROS_ + +#include + +// -------------------------------------------------------------------------- +// "private" macros, not to be used outside this file +// -------------------------------------------------------------------------- + +#define OSG_RM_CONCATENATE_MACRO(x, y) x##y +#define OSG_RM_LINEID1(x, y) OSG_RM_CONCATENATE_MACRO(x, y) +#define OSG_RM_LINEID(x) OSG_RM_LINEID1(x, __LINE__) + + +// -------------------------------------------------------------------------- +// QUICK REFLECTORS +// -------------------------------------------------------------------------- + +#define STD_VALUE_REFLECTOR(t) static osgIntrospection::StdValueReflector OSG_RM_LINEID(reflector) (#t); +#define VALUE_REFLECTOR_WITH_RW(t, rw) static osgIntrospection::ValueReflector OSG_RM_LINEID(reflector) (#t, new rw); +#define STD_PAIR_REFLECTOR(t) static osgIntrospection::StdPairReflector OSG_RM_LINEID(reflector) (#t); +#define STD_PAIR_REFLECTOR_WITH_TYPES(t, pt1, pt2) static osgIntrospection::StdPairReflector OSG_RM_LINEID(reflector) (#t); +#define ABSTRACT_OBJECT_REFLECTOR(t) static osgIntrospection::AbstractObjectReflector OSG_RM_LINEID(reflector) (#t); +#define STD_CONTAINER_REFLECTOR(t) static osgIntrospection::StdContainerReflector OSG_RM_LINEID(reflector) (#t); +#define STD_CONTAINER_REFLECTOR_WITH_TYPES(t, vt) static osgIntrospection::StdContainerReflector OSG_RM_LINEID(reflector) (#t); +#define STD_MAP_REFLECTOR(t) static osgIntrospection::StdMapReflector OSG_RM_LINEID(reflector) (#t); +#define STD_MAP_REFLECTOR_WITH_TYPES(t, it, vt) static osgIntrospection::StdMapReflector OSG_RM_LINEID(reflector) (#t); + + +// -------------------------------------------------------------------------- +// DETAILED REFLECTORS +// -------------------------------------------------------------------------- + +#define BEGIN_ENUM_REFLECTOR(c) \ + static struct OSG_RM_LINEID(reflector): public osgIntrospection::EnumReflector { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType(); + +#define BEGIN_VALUE_REFLECTOR(c) \ + static struct OSG_RM_LINEID(reflector): public osgIntrospection::ValueReflector { OSG_RM_LINEID(reflector)(): inherited(#c, 0) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType(); + +#define BEGIN_OBJECT_REFLECTOR(c) \ + static struct OSG_RM_LINEID(reflector): public osgIntrospection::ObjectReflector { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType(); + +#define BEGIN_ABSTRACT_OBJECT_REFLECTOR(c) \ + static struct OSG_RM_LINEID(reflector): public osgIntrospection::AbstractObjectReflector { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType(); + +#define END_REFLECTOR \ + } } OSG_RM_LINEID(reflector_instance); + + +// -------------------------------------------------------------------------- +// ATTRIBUTES +// -------------------------------------------------------------------------- + +#define Attribute(c) cap->addAttribute(new c); + + +// -------------------------------------------------------------------------- +// BASE TYPES +// -------------------------------------------------------------------------- + +#define BaseType(x) addBaseType(typeof(x)); + + +// -------------------------------------------------------------------------- +// PROPERTIES +// -------------------------------------------------------------------------- + +#define Property(t, n) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + Method0(t, get##n), \ + Method1(void, set##n, IN, t, value))) + +#define ReadOnlyProperty(t, n) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + Method0(t, get##n), \ + 0)) + +#define WriteOnlyProperty(t, n) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + 0, \ + Method1(void, set##n, IN, t, value))) + +#define PropertyWithCustomAccessors(t, n) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + 0, \ + 0)) + +#define ArrayProperty(t, n, np) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #np, \ + Method1(t, get##n, IN, unsigned int, index), \ + Method2(void, set##n, IN, unsigned int, index, IN, t, value), \ + Method0(unsigned int, getNum##np), \ + Method1(void, add##n, IN, t, value))) + +#define ArrayPropertyWithCustomAccessors(t, n, np) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #np, \ + 0, \ + 0, \ + 0, \ + 0)) + +#define ArrayPropertyWithReturnType(t, n, np, r) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + Method1(t, get##n, IN, unsigned int, index), \ + Method2(r, set##n, IN, unsigned int, index, IN, t, value), \ + Method0(unsigned int, getNum##np), \ + Method1(r, add##n, IN, t, value))) + +#define IndexedProperty IndexedProperty1 + +#define IndexedProperty1(t, n, i0, n0) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + Method1(t, get##n, IN, i0, n0), \ + Method2(void, set##n, IN, i0, n0, IN, t, value))) + +#define IndexedProperty2(t, n, i0, n0, i1, n1) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + Method2(t, get##n, IN, i0, n0, IN, i1, n1), \ + Method3(void, set##n, IN, i0, n0, IN i1, n1, IN, t, value))) + +#define IndexedProperty3(t, n, i0, n0, i1, n1, i2, n2) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ + Method3(t, get##n, IN, i0, n0, IN, i1, n1, IN, i2, n2), \ + Method4(void, set##n, IN, i0, n0, IN i1, n1, IN, i2, n2, IN, t, value))) + +// -------------------------------------------------------------------------- +// ENUM LABELS +// -------------------------------------------------------------------------- + +#define EnumLabel(x) addEnumLabel(x, #x, true); + + +// -------------------------------------------------------------------------- +// METHODS +// -------------------------------------------------------------------------- + +#define Method Method0 + +#define Method0(ret, fn) (\ + params.clear(), \ + addMethod(new osgIntrospection::TypedMethodInfo0(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method1(ret, fn, A0, P0, N0) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + addMethod(new osgIntrospection::TypedMethodInfo1(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method2(ret, fn, A0, P0, N0, A1, P1, N1) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + addMethod(new osgIntrospection::TypedMethodInfo2(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method3(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + addMethod(new osgIntrospection::TypedMethodInfo3(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method4(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + addMethod(new osgIntrospection::TypedMethodInfo4(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method5(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + addMethod(new osgIntrospection::TypedMethodInfo5(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method6(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + addMethod(new osgIntrospection::TypedMethodInfo6(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method7(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + addMethod(new osgIntrospection::TypedMethodInfo7(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method8(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + addMethod(new osgIntrospection::TypedMethodInfo8(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method9(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7, A8, P8, N8) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N8, osgIntrospection::Reflection::getType(typeid(P8)), 8, osgIntrospection::ParameterInfo::A8)), \ + addMethod(new osgIntrospection::TypedMethodInfo9(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method10(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7, A8, P8, N8, A9, P9, N9) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N8, osgIntrospection::Reflection::getType(typeid(P8)), 8, osgIntrospection::ParameterInfo::A8)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N9, osgIntrospection::Reflection::getType(typeid(P9)), 9, osgIntrospection::ParameterInfo::A9)), \ + addMethod(new osgIntrospection::TypedMethodInfo10(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method11(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7, A8, P8, N8, A9, P9, N9, A10, P10, N10) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N8, osgIntrospection::Reflection::getType(typeid(P8)), 8, osgIntrospection::ParameterInfo::A8)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N9, osgIntrospection::Reflection::getType(typeid(P9)), 9, osgIntrospection::ParameterInfo::A9)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N10, osgIntrospection::Reflection::getType(typeid(P10)), 10, osgIntrospection::ParameterInfo::A10)), \ + addMethod(new osgIntrospection::TypedMethodInfo11(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method12(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7, A8, P8, N8, A9, P9, N9, A10, P10, N10, A11, P11, N11) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N8, osgIntrospection::Reflection::getType(typeid(P8)), 8, osgIntrospection::ParameterInfo::A8)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N9, osgIntrospection::Reflection::getType(typeid(P9)), 9, osgIntrospection::ParameterInfo::A9)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N10, osgIntrospection::Reflection::getType(typeid(P10)), 10, osgIntrospection::ParameterInfo::A10)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N11, osgIntrospection::Reflection::getType(typeid(P11)), 11, osgIntrospection::ParameterInfo::A11)), \ + addMethod(new osgIntrospection::TypedMethodInfo12(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method13(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7, A8, P8, N8, A9, P9, N9, A10, P10, N10, A11, P11, N11, A12, P12, N12) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N8, osgIntrospection::Reflection::getType(typeid(P8)), 8, osgIntrospection::ParameterInfo::A8)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N9, osgIntrospection::Reflection::getType(typeid(P9)), 9, osgIntrospection::ParameterInfo::A9)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N10, osgIntrospection::Reflection::getType(typeid(P10)), 10, osgIntrospection::ParameterInfo::A10)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N11, osgIntrospection::Reflection::getType(typeid(P11)), 11, osgIntrospection::ParameterInfo::A11)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N12, osgIntrospection::Reflection::getType(typeid(P12)), 12, osgIntrospection::ParameterInfo::A12)), \ + addMethod(new osgIntrospection::TypedMethodInfo13(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method14(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7, A8, P8, N8, A9, P9, N9, A10, P10, N10, A11, P11, N11, A12, P12, N12, A13, P13, N13) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N8, osgIntrospection::Reflection::getType(typeid(P8)), 8, osgIntrospection::ParameterInfo::A8)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N9, osgIntrospection::Reflection::getType(typeid(P9)), 9, osgIntrospection::ParameterInfo::A9)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N10, osgIntrospection::Reflection::getType(typeid(P10)), 10, osgIntrospection::ParameterInfo::A10)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N11, osgIntrospection::Reflection::getType(typeid(P11)), 11, osgIntrospection::ParameterInfo::A11)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N12, osgIntrospection::Reflection::getType(typeid(P12)), 12, osgIntrospection::ParameterInfo::A12)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N13, osgIntrospection::Reflection::getType(typeid(P13)), 13, osgIntrospection::ParameterInfo::A13)), \ + addMethod(new osgIntrospection::TypedMethodInfo14(qualifyName(#fn), &reflected_type::fn, params))) + +#define Method15(ret, fn, A0, P0, N0, A1, P1, N1, A2, P2, N2, A3, P3, N3, A4, P4, N4, A5, P5, N5, A6, P6, N6, A7, P7, N7, A8, P8, N8, A9, P9, N9, A10, P10, N10, A11, P11, N11, A12, P12, N12, A13, P13, N13, A14, P14, N14) (\ + params.clear(), \ + params.push_back(new osgIntrospection::ParameterInfo(#N0, osgIntrospection::Reflection::getType(typeid(P0)), 0, osgIntrospection::ParameterInfo::A0)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N1, osgIntrospection::Reflection::getType(typeid(P1)), 1, osgIntrospection::ParameterInfo::A1)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N2, osgIntrospection::Reflection::getType(typeid(P2)), 2, osgIntrospection::ParameterInfo::A2)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N3, osgIntrospection::Reflection::getType(typeid(P3)), 3, osgIntrospection::ParameterInfo::A3)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N4, osgIntrospection::Reflection::getType(typeid(P4)), 4, osgIntrospection::ParameterInfo::A4)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N5, osgIntrospection::Reflection::getType(typeid(P5)), 5, osgIntrospection::ParameterInfo::A5)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N6, osgIntrospection::Reflection::getType(typeid(P6)), 6, osgIntrospection::ParameterInfo::A6)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N7, osgIntrospection::Reflection::getType(typeid(P7)), 7, osgIntrospection::ParameterInfo::A7)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N8, osgIntrospection::Reflection::getType(typeid(P8)), 8, osgIntrospection::ParameterInfo::A8)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N9, osgIntrospection::Reflection::getType(typeid(P9)), 9, osgIntrospection::ParameterInfo::A9)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N10, osgIntrospection::Reflection::getType(typeid(P10)), 10, osgIntrospection::ParameterInfo::A10)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N11, osgIntrospection::Reflection::getType(typeid(P11)), 11, osgIntrospection::ParameterInfo::A11)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N12, osgIntrospection::Reflection::getType(typeid(P12)), 12, osgIntrospection::ParameterInfo::A12)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N13, osgIntrospection::Reflection::getType(typeid(P13)), 13, osgIntrospection::ParameterInfo::A13)), \ + params.push_back(new osgIntrospection::ParameterInfo(#N14, osgIntrospection::Reflection::getType(typeid(P14)), 14, osgIntrospection::ParameterInfo::A14)), \ + addMethod(new osgIntrospection::TypedMethodInfo15(qualifyName(#fn), &reflected_type::fn, params))) + +#endif diff --git a/include/osgIntrospection/Reflector b/include/osgIntrospection/Reflector new file mode 100644 index 000000000..e973ca66b --- /dev/null +++ b/include/osgIntrospection/Reflector @@ -0,0 +1,523 @@ +#ifndef OSGINTROSPECTION_REFLECTOR_ +#define OSGINTROSPECTION_REFLECTOR_ + +#include +#include +#include +#include + +#include +#include + +namespace osgIntrospection +{ + + class CustomAttribute; + class CustomAttributeProvider; + class ReaderWriter; + + /// A Reflector is a proxy class that is used to create a new description + /// of a given type. If the type to be described is simple and doesn't + /// require additional details such as properties and methods, it can be + /// reflected by simply creating a global instance of one of the classes + /// derived from Reflector, for example ValueReflector. Other types may + /// need further information and therefore it could be necessary to create + /// a new subclass of Reflector or extend one of the existing subclasses. + /// The reflected type can be set by calling Reflector's protected + /// methods. + /// + /// NOTE: when you create a Reflector for type T, it will automatically + /// create descriptions for types T* and const T*. You should NEVER + /// create reflectors for pointer types explicitely. + /// + template + class Reflector + { + public: + typedef T reflected_type; + typedef Reflector inherited; + + /// Virtual destructor. + virtual ~Reflector() {} + + protected: + /// Direct initialization constructor. Parameter 'name' is the name + /// of the type being reflected, 'ns' is its namespace and 'rw' is + /// the ReaderWriter object associated to the type. + Reflector(const std::string &name, const std::string &ns, const ReaderWriter *rw); + + /// Direct initialization constructor. Parameter 'qname' is the + /// fully-qualified name of the type being reflected, i.e. containing + /// both the namespace and the name (separated by "::"). Parameter + /// 'rw' is the ReaderWriter object associated to the type. + Reflector(const std::string &qname, const ReaderWriter *rw); + + protected: + + /// Returns the Type object being described. + Type *getType() { return type_; } + + /// Declares a new base type for the current type. + void addBaseType(const Type &type); + + /// Adds a property description to the current type. + PropertyInfo *addProperty(PropertyInfo *pi); + + /// Adds a method description to the current type. + MethodInfo *addMethod(MethodInfo *mi); + + /// Adds an enumeration label to the current type. + void addEnumLabel(int v, const std::string &label, bool strip_namespace = true); + + /// Sets the instance creator for the current type. + void setInstanceCreator(const InstanceCreatorBase *icb); + + /// Returns a string containing the qualified version of 'name'. + std::string qualifyName(const std::string name) const; + + /// Adds a custom attribute to the type being described. + CustomAttributeProvider *addAttribute(const CustomAttribute *attrib); + + /// Sets the current type's ReaderWriter object. + void setReaderWriter(const ReaderWriter *rw); + + private: + void init(); + + Type *type_; + }; + + /// This reflector ought to be used to describe types that can be + /// created on the stack. Such types are for example int, double, + /// std::string, or other (possibly small) user-defined structs or + /// classes. The instance creator associated to types created through + /// this reflector will create Value objects whose internal type is T. + template + struct ValueReflector: public Reflector + { + typedef ValueReflector inherited; + + ValueReflector(const std::string &name, const std::string &ns, const ReaderWriter *rw = 0) + : Reflector(name, ns, rw) + { + setInstanceCreator(new ValueInstanceCreator); + } + + ValueReflector(const std::string &qname, const ReaderWriter *rw = 0) + : Reflector(qname, rw) + { + setInstanceCreator(new ValueInstanceCreator); + } + }; + + /// This reflector is to be used to describe abstract types that can't + /// be created directly, and therefore can't have an InstanceCreator + /// object associated to them. + template + struct AbstractObjectReflector: public Reflector + { + typedef AbstractObjectReflector inherited; + + AbstractObjectReflector(const std::string &name, const std::string &ns) + : Reflector(name, ns, 0) + { + } + + AbstractObjectReflector(const std::string &qname) + : Reflector(qname, 0) + { + } + }; + + /// This reflector is to be used to describe types that ought to be + /// created on the heap. Such types are for example all classes derived + /// from osg::Referenced. The instance creator associated to types + /// created through this reflector will create Value objects whose + /// internal type is T*. + template + struct ObjectReflector: public Reflector + { + typedef ObjectReflector inherited; + + ObjectReflector(const std::string &name, const std::string &ns) + : Reflector(name, ns, 0) + { + setInstanceCreator(new InstanceCreator); + } + + ObjectReflector(const std::string &qname) + : Reflector(qname, 0) + { + setInstanceCreator(new InstanceCreator); + } + }; + + + /// This reflector is a ValueReflector that should be used to define + /// types that can be read and written from/to streams using the << + /// and >> operators. A StdReaderWriter is assigned by default. + template + struct StdValueReflector: public ValueReflector + { + StdValueReflector(const std::string &name, const std::string &ns) + : ValueReflector(name, ns, new StdReaderWriter) + { + } + + StdValueReflector(const std::string &qname) + : ValueReflector(qname, new StdReaderWriter) + { + } + }; + + + /// This reflector is a ValueReflector that should be used to define + /// enumerations. It assigns an EnumReaderWriter by default. + template + struct EnumReflector: public ValueReflector + { + typedef EnumReflector inherited; + + EnumReflector(const std::string &name, const std::string &ns) + : ValueReflector(name, ns, new EnumReaderWriter) + { + } + + EnumReflector(const std::string &qname) + : ValueReflector(qname, new EnumReaderWriter) + { + } + }; + + + /// This class allows to define the means for reflecting STL containers + /// such as std::deque and std::vector. + template + struct StdContainerReflector: ValueReflector + { + struct Getter: PropertyGetter + { + virtual Value get(const Value &instance, int i) const + { + const T &ctr = variant_cast(instance); + return ctr.at(i); + } + }; + + struct Setter: PropertySetter + { + virtual void set(Value &instance, int i, const Value &v) const + { + T &ctr = variant_cast(instance); + ctr.at(i) = variant_cast(v); + } + }; + + struct Counter: PropertyCounter + { + virtual int count(const Value &instance) const + { + const T &ctr = variant_cast(instance); + return static_cast(ctr.size()); + } + }; + + struct Adder: PropertyAdder + { + virtual void add(Value &instance, const Value &v) const + { + T &ctr = variant_cast(instance); + ctr.push_back(variant_cast(v)); + } + }; + + StdContainerReflector(const std::string &name): ValueReflector(name) + { + PropertyInfo *pi = new PropertyInfo(typeof(T), typeof(typename T::value_type), "Items", 0, 0, 0, 0); + pi->addAttribute(new CustomPropertyGetAttribute(new Getter)); + pi->addAttribute(new CustomPropertySetAttribute(new Setter)); + pi->addAttribute(new CustomPropertyCountAttribute(new Counter)); + pi->addAttribute(new CustomPropertyAddAttribute(new Adder)); + + if (typeid(VT).before(typeid(typename T::value_type)) || + typeid(typename T::value_type).before(typeid(VT))) + { + pi->addAttribute(new PropertyTypeAttribute(typeof(VT))); + } + + addProperty(pi); + } + }; + + /// This class allows to define the means for reflecting STL associative + /// containers which hold pairs of key+value, such as std::map. + template + struct StdMapReflector: ValueReflector + { + typedef typename T::const_iterator const_iterator; + typedef typename T::key_type key_type; + typedef typename T::mapped_type mapped_type; + + struct Getter: PropertyGetter + { + virtual Value get(const Value &instance, const ValueList &indices) const + { + const T& ctr = variant_cast(instance); + const key_type& key = variant_cast(indices.front()); + + const_iterator i = ctr.find(key); + if (i == ctr.end()) return Value(); + return i->second; + } + }; + + struct Setter: PropertySetter + { + virtual void set(Value &instance, const ValueList &indices, const Value &v) const + { + T &ctr = variant_cast(instance); + ctr.insert(std::make_pair(variant_cast(indices.front()), variant_cast(v))); + } + }; + + struct Indexer: IndexInfo + { + ParameterInfoList params_; + const Type &itype_; + + Indexer() + : itype_(typeof(IT)) + { + params_.push_back(new ParameterInfo("key", typeof(key_type), 0, ParameterInfo::IN)); + } + + virtual ~Indexer() + { + delete params_.front(); + } + + virtual const ParameterInfoList &getIndexParameters() const + { + return params_; + } + + virtual void getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const + { + const T &ctr = variant_cast(instance); + for (const_iterator i=ctr.begin(); + i!=ctr.end(); + ++i) + { + values.push_back(Value(i->first).convertTo(itype_)); + } + } + }; + + StdMapReflector(const std::string &name): ValueReflector(name) + { + PropertyInfo *pi = new PropertyInfo(typeof(T), typeof(typename T::value_type), "Items", 0, 0); + pi->addAttribute(new CustomPropertyGetAttribute(new Getter)); + pi->addAttribute(new CustomPropertySetAttribute(new Setter)); + pi->addAttribute(new CustomIndexAttribute(new Indexer)); + + if (typeid(VT).before(typeid(typename T::mapped_type)) || + typeid(typename T::mapped_type).before(typeid(VT))) + { + pi->addAttribute(new PropertyTypeAttribute(typeof(VT))); + } + + addProperty(pi); + } + }; + + template + struct StdPairReflector: ValueReflector + { + struct Accessor: PropertyGetter, PropertySetter + { + Accessor(int i): i_(i) {} + + virtual Value get(const Value &instance) const + { + switch (i_) + { + case 0: return variant_cast(instance).first; + case 1: return variant_cast(instance).second; + default: return Value(); + } + } + + virtual void set(const Value &instance, const Value &v) const + { + T &ctr = variant_cast(instance); + + switch (i_) + { + case 0: ctr.first = variant_cast(v); break; + case 1: ctr.second = variant_cast(v); break; + } + } + + int i_; + }; + + StdPairReflector(const std::string &name): ValueReflector(name) + { + PropertyInfo *pi1 = new PropertyInfo(typeof(T), typeof(typename T::first_type), "first", 0, 0); + pi1->addAttribute(new CustomPropertyGetAttribute(new Accessor(0))); + pi1->addAttribute(new CustomPropertySetAttribute(new Accessor(0))); + + if (typeid(PT1).before(typeid(typename T::first_type)) || + typeid(typename T::first_type).before(typeid(PT1))) + pi1->addAttribute(new PropertyTypeAttribute(typeof(PT1))); + + addProperty(pi1); + + PropertyInfo *pi2 = new PropertyInfo(typeof(T), typeof(typename T::second_type), "second", 0, 0); + pi2->addAttribute(new CustomPropertyGetAttribute(new Accessor(1))); + pi2->addAttribute(new CustomPropertySetAttribute(new Accessor(1))); + + if (typeid(PT2).before(typeid(typename T::second_type)) || + typeid(typename T::second_type).before(typeid(PT2))) + pi2->addAttribute(new PropertyTypeAttribute(typeof(PT2))); + + addProperty(pi2); + } + }; + + + // TEMPLATE METHODS + + template + Reflector::Reflector(const std::string &name, const std::string &ns, const ReaderWriter *rw) + : type_(Reflection::registerOrReplaceType(typeid(T))) + { + type_->name_ = name; + type_->namespace_ = ns; + type_->rw_ = rw; + init(); + } + + template + Reflector::Reflector(const std::string &qname, const ReaderWriter *rw) + : type_(Reflection::registerOrReplaceType(typeid(T))) + { + std::string::size_type p = qname.rfind("::"); + if (p != std::string::npos) + { + type_->namespace_ = qname.substr(0, p); + type_->name_ = qname.substr(p+2); + } + else + { + type_->name_ = qname; + } + type_->rw_ = rw; + init(); + } + + template + void Reflector::init() + { + // pointer type + if (!type_->pointed_type_) + { + Type *ptype = Reflection::registerOrReplaceType(typeid(T*)); + ptype->name_ = type_->name_; + ptype->namespace_ = type_->namespace_; + ptype->pointed_type_ = type_; + ptype->is_defined_ = true; + ptype->set_instance_creator(new ValueInstanceCreator); + ptype->rw_ = new PtrReaderWriter(); + } + + // const pointer type + if (!type_->pointed_type_ || !type_->is_const_) + { + Type *cptype = Reflection::registerOrReplaceType(typeid(const T*)); + cptype->name_ = type_->name_; + cptype->namespace_ = type_->namespace_; + cptype->is_const_ = true; + cptype->pointed_type_ = type_; + cptype->is_defined_ = true; + cptype->set_instance_creator(new ValueInstanceCreator); + cptype->rw_ = new PtrReaderWriter(); + } + + type_->is_defined_ = true; + } + + template + void Reflector::addBaseType(const Type &type) + { + type_->base_.push_back(&type); + } + + template + PropertyInfo *Reflector::addProperty(PropertyInfo *pi) + { + type_->props_.push_back(pi); + return pi; + } + + template + MethodInfo *Reflector::addMethod(MethodInfo *mi) + { + type_->methods_.push_back(mi); + return mi; + } + + template + void Reflector::addEnumLabel(int v, const std::string &label, bool strip_namespace) + { + if (strip_namespace) + { + std::string::size_type p = label.rfind("::"); + if (p != std::string::npos) + { + type_->labels_.insert(std::make_pair(v, label.substr(p+2))); + return; + } + } + type_->labels_.insert(std::make_pair(v, label)); + } + + template + void Reflector::setInstanceCreator(const InstanceCreatorBase *icb) + { + type_->set_instance_creator(icb); + } + + template + std::string Reflector::qualifyName(const std::string name) const + { + std::string s; + if (!type_->namespace_.empty()) + { + s.append(type_->namespace_); + s.append("::"); + } + if (!type_->name_.empty()) + { + s.append(type_->name_); + s.append("::"); + } + s.append(name); + return s; + } + + template + CustomAttributeProvider *Reflector::addAttribute(const CustomAttribute *attrib) + { + return type_->addAttribute(attrib); + } + + template + void Reflector::setReaderWriter(const ReaderWriter *rw) + { + type_->rw_ = rw; + } + +} + +#endif diff --git a/include/osgIntrospection/Type b/include/osgIntrospection/Type new file mode 100644 index 000000000..2ac7aa0f6 --- /dev/null +++ b/include/osgIntrospection/Type @@ -0,0 +1,408 @@ +#ifndef OSGINTROSPECTION_TYPE_ +#define OSGINTROSPECTION_TYPE_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace osgIntrospection +{ + + // forward declarations + class MethodInfo; + class PropertyInfo; + class ParameterInfo; + class ReaderWriter; + + // typedefs for member info lists + typedef std::vector MethodInfoList; + typedef std::vector PropertyInfoList; + typedef std::vector ParameterInfoList; + + // typedef for enum label map + typedef std::map EnumLabelMap; + + /// Base class for instance creators. An instance creator is + /// a lightweight object that creates a Value containing an + /// instance of some type. Every non-abstract Type object has + /// an instance creator that creates instances of that type. + /// This is an abstract interface, it must be derived to + /// provide the actual implementation of createInstance(). + struct InstanceCreatorBase + { + virtual Value createInstance() const = 0; + }; + + /// This is an instance creator to be used with types that ought to + /// be created on the heap, for example all classes derived from + /// osg::Referenced. + template + struct InstanceCreator: public InstanceCreatorBase + { + Value createInstance() const + { + return new T(); + } + }; + + /// This is an instance creator to be used with types that can be + /// created on the stack (for example: int, std::string, or other + /// possibly small user-defined structs or classes). + template + struct ValueInstanceCreator: public InstanceCreatorBase + { + Value createInstance() const + { + return T(); + } + }; + + /// Objects of class Type are used to maintain information about + /// reflected types. They also provide a number of services, like + /// instance creation and dynamic calling of methods. + /// All details about the data type being described are available + /// at runtime, provided that the type was defined (and not just + /// declared) through a Reflector class. + /// It is not possible to modify a Type object once it has been + /// created, unless you are a class derived from Reflector (which + /// has firm friendship with this class). + class OSGINTROSPECTION_EXPORT Type: public CustomAttributeProvider + { + public: + /// Destructor. Note that this class is not meant to be subclassed. + ~Type(); + + /// Returns a reference to the std::type_info instance associated + /// to this Type. + inline const std::type_info &getStdTypeInfo() const; + + /// Returns true if this Type is defined, false if it's just + /// declared. See class Reflector if you want to create a new Type. + inline bool isDefined() const; + + /// Returns the name of the reflected type. + inline const std::string &getName() const; + + /// Returns the namespace of the reflected type. + inline const std::string &getNamespace() const; + + /// Returns the qualified name of the reflected type. The qualified + /// name is formed by the namespace, if present, plus other modifiers + /// like 'const' and/or '*' (pointer) where applicable. + inline std::string getQualifiedName() const; + + /// Returns the number of base types. + /// This number is zero if the type is not derived from any other + /// type. + inline int getNumBaseTypes() const; + + /// Returns the i-th base type. + inline const Type &getBaseType(int i) const; + + /// Returns whether the reflected type is abstract. + inline bool isAbstract() const; + + /// Returns whether the reflected type is "atomic", that is + /// it can be rendered to and decoded from a stream directly. + inline bool isAtomic() const; + + /// Returns whether the reflected type is an enumeration. + inline bool isEnum() const; + + /// Returns whether the reflected type is the type void. + inline bool isVoid() const; + + /// Returns true if the reflected type is a pointer, false otherwise. + inline bool isPointer() const; + + /// Returns true if the reflected type is a pointer AND it is const, + /// false otherwise. + inline bool isConstPointer() const; + + /// Returns true if the reflected type is a pointer AND it is not + /// const, false otherwise. + inline bool isNonConstPointer() const; + + /// Returns the pointed type. If the reflected type is not a pointer, + /// the object returned is typeof(void). + inline const Type &getPointedType() const; + + /// Returns the list of properties defined for this type. The list + /// does not include properties inherited from base types. + inline const PropertyInfoList &getProperties() const; + + /// Fills a list of properties that are either defined in this Type + /// or in inherited types. + void getAllProperties(PropertyInfoList &props) const; + + /// Returns the list of methods defined for this type. The list + /// does not include methods inherited from base types. + inline const MethodInfoList &getMethods() const; + + /// Fills a list of methods that are either defined in this Type + /// or in inherited types. + void getAllMethods(MethodInfoList &methods) const; + + /// Returns the map of enumeration labels. If the type is not an + /// enumeration, an empty map is returned. + inline const EnumLabelMap &getEnumLabels() const; + + /// Searches for a method that can be called with the given list of + /// arguments without raising type conversion errors. If more than + /// one method are suitable for calling, the best match is returned. + const MethodInfo *getCompatibleMethod(const std::string &name, const ValueList &values, bool inherit) const; + + /// Searches for a method whose parameters match exactly the given + /// list of parameter descriptions. + const MethodInfo *getMethod(const std::string &name, const ParameterInfoList ¶ms, bool inherit) const; + + /// Searches for a property given its name, type and list of indices. + /// Only exact matches are returned. + const PropertyInfo *getProperty(const std::string &name, const Type &ptype, const ParameterInfoList &indices, bool inherit) const; + + /// Searches for a suitable method and invokes it with the given list + /// of arguments (const instance). + Value invokeMethod(const std::string &name, const Value &instance, ValueList &args, bool inherit) const; + + /// Searches for a suitable method and invokes it with the given list + /// of arguments. + Value invokeMethod(const std::string &name, Value &instance, ValueList &args, bool inherit) const; + + /// Returns whether the reflected type is derived from another type. + bool isSubclassOf(const Type &type) const; + + /// Returns the instance of the reader/writer object assigned to + /// this type, if any. Otherwise it returns the null pointer. + inline const ReaderWriter *getReaderWriter() const; + + /// Creates an instance of the reflected type. The returned Value + /// can be casted to T*, where T is the reflected type. If the type + /// is abstract, an exception is thrown. + inline Value createInstance() const; + + protected: + Type(const std::type_info &ti) + : ti_(ti), + is_const_(false), + pointed_type_(0), + is_defined_(false), + icb_(0), + rw_(0) + { + } + + // throws an exception if the type is not defined. + void check_defined() const; + + virtual void getInheritedProviders(CustomAttributeProviderList &providers) const; + + void set_instance_creator(const InstanceCreatorBase *icb) + { + delete icb_; + icb_ = icb; + } + + private: + template friend class Reflector; + friend class Reflection; + + Type(const Type ©): CustomAttributeProvider(copy), ti_(copy.ti_) {} + + const std::type_info &ti_; + + std::string name_; + std::string namespace_; + + typedef std::vector TypeList; + TypeList base_; + + bool is_const_; + const Type *pointed_type_; + + PropertyInfoList props_; + MethodInfoList methods_; + + EnumLabelMap labels_; + bool is_defined_; + + const InstanceCreatorBase *icb_; + const ReaderWriter *rw_; + }; + + // OPERATORS + + /// Equality test operator. Returns true if the two instances of Type + /// describe the same type, false otherwise. + inline bool operator==(const Type &t1, const Type &t2) + { + return (t1.getStdTypeInfo() == t2.getStdTypeInfo()) != 0; + } + + /// Inequality test operator. Returns false if the two instances of Type + /// describe the same type, true otherwise. + inline bool operator!=(const Type &t1, const Type &t2) + { + return (t1.getStdTypeInfo() != t2.getStdTypeInfo()) != 0; + } + + /// Less than operator. Returns true if the first type comes before the + /// second one. The actual ordering is implementation-dependent. + inline bool operator<(const Type &t1, const Type &t2) + { + return (t1.getStdTypeInfo().before(t2.getStdTypeInfo())) != 0; + } + + /// Greater than or equal to operator. Returns !operator<(). + inline bool operator>=(const Type &t1, const Type &t2) + { + return !operator<(t1, t2); + } + + // INLINE METHODS + + inline void Type::check_defined() const + { + if (!is_defined_) + throw TypeNotDefinedException(ti_); + } + + inline const std::type_info &Type::getStdTypeInfo() const + { + return ti_; + } + + inline const std::string &Type::getName() const + { + check_defined(); + return name_; + } + + inline const std::string &Type::getNamespace() const + { + check_defined(); + return namespace_; + } + + inline std::string Type::getQualifiedName() const + { + check_defined(); + std::string qname; + if (is_const_) qname = "const "; + if (!namespace_.empty()) + { + qname.append(namespace_); + qname.append("::"); + } + qname.append(name_); + if (pointed_type_) + qname.append(" *"); + return qname; + } + + inline int Type::getNumBaseTypes() const + { + check_defined(); + return static_cast(base_.size()); + } + + inline bool Type::isConstPointer() const + { + check_defined(); + return is_const_ && pointed_type_; + } + + inline bool Type::isNonConstPointer() const + { + check_defined(); + return !is_const_ && pointed_type_; + } + + inline bool Type::isAbstract() const + { + check_defined(); + return icb_ == 0; + } + + inline bool Type::isAtomic() const + { + check_defined(); + return rw_ != 0; + } + + inline const PropertyInfoList &Type::getProperties() const + { + check_defined(); + return props_; + } + + inline const MethodInfoList &Type::getMethods() const + { + check_defined(); + return methods_; + } + + inline bool Type::isPointer() const + { + check_defined(); + return pointed_type_ != 0; + } + + inline bool Type::isVoid() const + { + return (ti_ == typeid(void)) != 0; + } + + inline const Type &Type::getPointedType() const + { + check_defined(); + if (pointed_type_) + return *pointed_type_; + return Reflection::type_void(); + } + + inline bool Type::isEnum() const + { + check_defined(); + return !labels_.empty(); + } + + inline const EnumLabelMap &Type::getEnumLabels() const + { + check_defined(); + return labels_; + } + + inline bool Type::isDefined() const + { + return is_defined_; + } + + inline const ReaderWriter *Type::getReaderWriter() const + { + check_defined(); + return rw_; + } + + inline const Type &Type::getBaseType(int i) const + { + check_defined(); + return *base_.at(i); + } + + inline Value Type::createInstance() const + { + check_defined(); + if (!icb_) + throw TypeIsAbstractException(ti_); + return icb_->createInstance(); + } + +} + +#endif diff --git a/include/osgIntrospection/TypedMethodInfo b/include/osgIntrospection/TypedMethodInfo new file mode 100644 index 000000000..8df0d14fb --- /dev/null +++ b/include/osgIntrospection/TypedMethodInfo @@ -0,0 +1,2243 @@ +#ifndef OSGINTROSPECTION_TYPEDMETHODINFO_ +#define OSGINTROSPECTION_TYPEDMETHODINFO_ + +#include +#include + +namespace osgIntrospection +{ + + /// Class templates TypedMethodInfoN (where 0 <= N <= 16) are concrete + /// implementations of MethodInfo. They are used to keep information + /// about class methods and to provide the means for calling them + /// dynamically. Each class template can handle methods with N arguments + /// and is parametrized by the class that declares the method and by the + /// return type. Both const and non-const methods are supported. + /// The invoke() methods allow to call the reflected method dynamically, + /// passing it the arguments as a list of Value objects. The instance + /// on which the reflected method will be called is passed to invoke() + /// as a Value object, which can contain either a value of type C or a + /// pointer to C. If the constness doesn't match (i.e., you try to call + /// a non-const reflected method on a const instance) an exception is + /// thrown. + /// + /// NOTE: currently, variant_cast<> does not check pointer conversions, + /// it simply converts one pointer into another even if they point to + /// types that are completely unrelated. + /// This means you won't probably get any exceptions if you try to call + /// a class' method on another class' instance, but of course that's a + /// bad, bad idea... + /// + template + class TypedMethodInfo0: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)() const; + typedef R (C::*FunctionType)(); + + TypedMethodInfo0(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo0(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(); + if (f_) return (variant_cast(instance)->*f_)(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(); + if (f_) return (variant_cast(instance)->*f_)(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(); + if (f_) return (variant_cast(instance).*f_)(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo1: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0) const; + typedef R (C::*FunctionType)(P0); + + TypedMethodInfo1(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo1(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo2: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1) const; + typedef R (C::*FunctionType)(P0, P1); + + TypedMethodInfo2(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo2(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo3: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2) const; + typedef R (C::*FunctionType)(P0, P1, P2); + + TypedMethodInfo3(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo3(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo4: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3); + + TypedMethodInfo4(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo4(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo5: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4); + + TypedMethodInfo5(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo5(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo6: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5); + + TypedMethodInfo6(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo6(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo7: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6); + + TypedMethodInfo7(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo7(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo8: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7); + + TypedMethodInfo8(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo8(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo9: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + + TypedMethodInfo9(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo9(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo10: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + + TypedMethodInfo10(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo10(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo11: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + + TypedMethodInfo11(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo11(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo12: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + + TypedMethodInfo12(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo12(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo13: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + + TypedMethodInfo13(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo13(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo14: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + + TypedMethodInfo14(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo14(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo15: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + + TypedMethodInfo15(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo15(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo16: public MethodInfo + { + public: + typedef R (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) const; + typedef R (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + + TypedMethodInfo16(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo16(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(R), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo0: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)() const; + typedef void (C::*FunctionType)(); + + TypedMethodInfo0(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo0(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(), Value(); + if (f_) return (variant_cast(instance)->*f_)(), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(), Value(); + if (f_) return (variant_cast(instance)->*f_)(), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(), Value(); + if (f_) return (variant_cast(instance).*f_)(), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo1: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0) const; + typedef void (C::*FunctionType)(P0); + + TypedMethodInfo1(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo1(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo2: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1) const; + typedef void (C::*FunctionType)(P0, P1); + + TypedMethodInfo2(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo2(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo3: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2) const; + typedef void (C::*FunctionType)(P0, P1, P2); + + TypedMethodInfo3(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo3(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo4: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3); + + TypedMethodInfo4(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo4(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo5: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4); + + TypedMethodInfo5(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo5(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo6: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5); + + TypedMethodInfo6(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo6(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo7: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6); + + TypedMethodInfo7(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo7(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo8: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7); + + TypedMethodInfo8(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo8(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo9: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + + TypedMethodInfo9(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo9(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo10: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + + TypedMethodInfo10(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo10(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo11: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + + TypedMethodInfo11(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo11(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo12: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + + TypedMethodInfo12(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo12(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo13: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + + TypedMethodInfo13(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo13(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo14: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + + TypedMethodInfo14(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo14(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo15: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + + TypedMethodInfo15(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo15(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + + template + class TypedMethodInfo16: public MethodInfo + { + public: + typedef void (C::*ConstFunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) const; + typedef void (C::*FunctionType)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + + TypedMethodInfo16(const std::string &qname, ConstFunctionType cf, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(cf), f_(0) + { + } + + TypedMethodInfo16(const std::string &qname, FunctionType f, const ParameterInfoList &plist) + : MethodInfo(qname, typeof(C), typeof(void), plist), cf_(0), f_(f) + { + } + + bool isConst() const { return cf_; } + + Value invoke(const Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + + Value invoke(Value &instance, ValueList &args) const + { + const Type &type = instance.getType(); + if (type.isPointer()) + { + if (type.isConstPointer()) + { + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + if (f_) throw ConstIsConstException(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance)->*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + if (f_) return (variant_cast(instance)->*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + throw InvalidFunctionPointerException(); + } + if (cf_) return (variant_cast(instance).*cf_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + if (f_) return (variant_cast(instance).*f_)(variant_cast(args[0]), variant_cast(args[1]), variant_cast(args[2]), variant_cast(args[3]), variant_cast(args[4]), variant_cast(args[5]), variant_cast(args[6]), variant_cast(args[7]), variant_cast(args[8]), variant_cast(args[9]), variant_cast(args[10]), variant_cast(args[11]), variant_cast(args[12]), variant_cast(args[13]), variant_cast(args[14]), variant_cast(args[15])), Value(); + throw InvalidFunctionPointerException(); + } + + private: + ConstFunctionType cf_; + FunctionType f_; + }; + + +} + +#endif diff --git a/include/osgIntrospection/Value b/include/osgIntrospection/Value new file mode 100644 index 000000000..9f929cf7f --- /dev/null +++ b/include/osgIntrospection/Value @@ -0,0 +1,427 @@ +#ifndef OSGINTROSPECTION_VALUE_ +#define OSGINTROSPECTION_VALUE_ + +#include +#include + +#include +#include +#include + +namespace osgIntrospection +{ + + class Type; + + class OSGINTROSPECTION_EXPORT Value + { + public: + /// Default constructor. Initializes internal structures + /// so that the Type returned by getType() is typeof(void), + /// and the value is empty so that isEmpty() returns true. + /// Be careful when using empty values, as some operations + /// on them may throw an exception. + inline Value(); + + /// Direct initialization constructor for void pointers. + /// Although one of the constructor templates below could + /// certainly handle void pointers as well, we need to treat + /// them separately because void* can't be dereferenced. + inline Value(void *v); + + /// Direct initialization constructor for const void pointers. + /// Although one of the constructor templates below could + /// certainly handle void pointers as well, we need to treat + /// them separately because void* can't be dereferenced. + inline Value(const void *v); + + /// Direct initialization constructor template for non-const + /// pointers. By initializing an instance of Value through + /// this constructor, internal structures will be configured + /// to handle polymorphic types. This means you'll be able to + /// call getInstanceType() to get the actual type of the + /// dereferenced value. + template Value(T *v); + + /// Direct initialization constructor template for non-const + /// pointers. By initializing an instance of Value through + /// this constructor, internal structures will be configured + /// to handle polymorphic types. This means you'll be able to + /// call getInstanceType() to get the actual type of the + /// dereferenced value. + template Value(const T *v); + + /// Direct initialization constructor template for all types + /// that are not handled by any of the constructors above. + /// Calling getInstanceType() on an instance constructed + /// this way returns the same as getType(). + template Value(const T &v); + + /// Copy constructor. The underlying value's type must have + /// consistent copy semantics. + inline Value(const Value ©); + + /// Destructor. Frees internal resources but it does NOT delete + /// the value held. For example, this function will produce a + /// memory leak: void f() { Value v(new int); } + inline ~Value(); + + /// Assignment operator. Behaves like the copy constructor. + inline Value &operator=(const Value ©); + + /// Returns whether the value is a pointer and it points to + /// something whose type is different than void. + inline bool isTypedPointer() const; + + /// Returns whether this Value is empty. + inline bool isEmpty() const; + + /// Returns whether the value is a null pointer. + inline bool isNullPointer() const; + + /// Returns the exact type of the value held. + inline const Type &getType() const; + + /// If the value is a pointer to a non-void type, this method + /// returns the actual type of the dereferenced pointer. Please + /// note it is not the same as getType().getPointedType(), + /// because the latter would return the non-polymorphic type. + /// If the value is not a pointer, this method behaves like + /// getType(). + inline const Type &getInstanceType() const; + + /// Equality test operator. Returns true if the value passed + /// as parameter is equal to this instance. The compare() method + /// is used to perform the actual comparison. + inline bool operator==(const Value &other) const; + + /// Inequality test operator. Returns !operator==(other). + inline bool operator!=(const Value &other) const; + + /// Conversion to bool operator. Returns true if the value is + /// not empty, false otherwise. + inline operator bool() const; + + /// Tries to convert this instance to a Value of the given type. + /// The conversion is performed by rendering to a temporary stream + /// in the source format and trying to read back from the stream + /// in the destination format. If either the source or destination + /// types, or both, don't have a ReaderWriter object, the conversion + /// fails and an exception is thrown. If the conversion can't be + /// completed for other reasons, other exceptions may be thrown. + Value convertTo(const Type &outtype) const; + + /// Tries to convert this instance to a Value of the given type. + /// The conversion is performed by rendering to a temporary stream + /// in the source format and trying to read back from the stream + /// in the destination format. If either the source or destination + /// types, or both, don't have a ReaderWriter object, the conversion + /// fails and an empty Value is returned. + /// Please note that unlike convertTo(), this method does not + /// intentionally throw any exceptions. + Value tryConvertTo(const Type &outtype) const; + + /// Tries to get a string representation of the underlying value. + /// This requires the value's type to have a ReaderWriter object + /// associated to it. If the conversion can't be completed, an + /// exception is thrown. + std::string toString() const; + + /// Compares two values for equality. Two empty values are considered + /// equal. If the two values' types are different, a conversion is + /// attempted and then the equality test is performed again. + static bool compare(const Value &v1, const Value &v2); + + private: + // It's good to have friends! + template friend T variant_cast(const Value &v); + template friend T *extract_raw_data(Value &v); + template friend const T *extract_raw_data(const Value &v); + + // throw an exception if the value is empty + void check_empty() const; + + // Base class for holding values. Provides a clone() method + // which must be overriden in descendant classes. + struct Instance_base + { + virtual Instance_base *clone() const = 0; + virtual ~Instance_base() {} + }; + + // Generic descendant of Instance_base for holding values of + // type T. Note that values are created on the stack. + template + struct Instance: Instance_base + { + Instance(T data): data_(data) {} + virtual Instance_base *clone() const { return new Instance(*this); } + virtual ~Instance() {} + T data_; + }; + + // Base class for storage of Instance objects. Actually three + // instances are created: the main instance which keeps the + // desired value, an additional instance that keeps a reference + // to that value, and another instance that keeps a const + // reference to that value. These additional instances are queried + // when casting the Value to a reference type. + struct Instance_box_base + { + Instance_box_base() + : inst_(0), + ref_inst_(0), + const_ref_inst_(0) + { + } + + virtual ~Instance_box_base() + { + delete inst_; + delete ref_inst_; + delete const_ref_inst_; + } + + // clones the instance box + virtual Instance_box_base *clone() const = 0; + // returns the type of the value held + virtual const Type *type() const = 0; + // returns the actual pointed type if applicable + virtual const Type *ptype() const { return 0; } + // tests for equality + virtual bool equal(const Value &v) const = 0; + // returns whether the data is a null pointer + virtual bool nullptr() const = 0; + + Instance_base *inst_; + Instance_base *ref_inst_; + Instance_base *const_ref_inst_; + }; + + // Generic instance box for non-pointer values. + template + struct Instance_box: Instance_box_base + { + Instance_box(): Instance_box_base(), nullptr_(false) {} + + Instance_box(const T &d, bool nullptr = false) + : Instance_box_base(), + nullptr_(nullptr) + { + Instance *vl = new Instance(d); + inst_ = vl; + ref_inst_ = new Instance(vl->data_); + const_ref_inst_ = new Instance(vl->data_); + } + + virtual Instance_box_base *clone() const + { + Instance_box *new_inbox = new Instance_box(); + + // ??? this static_cast<> shouldn't be necessary, but the + // MSVC++ compiler complains about invalid casting without it! + Instance *vl = static_cast *>(inst_->clone()); + + new_inbox->inst_ = vl; + new_inbox->ref_inst_ = new Instance(vl->data_); + new_inbox->const_ref_inst_ = new Instance(vl->data_); + new_inbox->nullptr_ = nullptr_; + return new_inbox; + } + + virtual const Type *type() const + { + return &typeof(static_cast *>(inst_)->data_); + } + + virtual bool equal(const Value &v) const + { + return static_cast *>(static_cast *>(v.inbox_)->inst_)->data_ == + static_cast *>(inst_)->data_; + } + + virtual bool nullptr() const + { + return nullptr_; + } + + private: + bool nullptr_; + }; + + // Generic instance box for pointer values. Unlike Instance_box<>, + // this struct template provides a ptype() method that unreferences + // the pointer (T is supposed to be a pointer) and gets its actual + // type. + template + struct Ptr_instance_box: Instance_box_base + { + Ptr_instance_box(): Instance_box_base() {} + + Ptr_instance_box(const T &d) + : Instance_box_base() + { + Instance *vl = new Instance(d); + inst_ = vl; + ref_inst_ = new Instance(vl->data_); + const_ref_inst_ = new Instance(vl->data_); + } + + virtual Instance_box_base *clone() const + { + Ptr_instance_box *new_inbox = new Ptr_instance_box(); + + // ??? this static_cast<> shouldn't be necessary, but the + // MSVC++ compiler complains about invalid casting without it! + Instance *vl = static_cast *>(inst_->clone()); + + new_inbox->inst_ = vl; + new_inbox->ref_inst_ = new Instance(vl->data_); + new_inbox->const_ref_inst_ = new Instance(vl->data_); + return new_inbox; + } + + virtual const Type *type() const + { + return &typeof(static_cast *>(inst_)->data_); + } + + virtual const Type *ptype() const + { + if (!static_cast *>(inst_)->data_) return 0; + return &typeof(*static_cast *>(inst_)->data_); + } + + virtual bool equal(const Value &v) const + { + return static_cast *>(static_cast *>(v.inbox_)->inst_)->data_ == + static_cast *>(inst_)->data_; + } + + virtual bool nullptr() const + { + return static_cast *>(inst_)->data_ == 0; + } + + }; + + Instance_box_base *inbox_; + const Type *type_; + const Type *ptype_; + }; + + /// A vector of values. + typedef std::vector ValueList; + + + // INLINE METHODS + + inline Value::Value() + : inbox_(0), + type_(&Reflection::type_void()), + ptype_(0) + { + } + + template Value::Value(const T &v) + : ptype_(0) + { + inbox_ = new Instance_box(v); + type_ = inbox_->type(); + } + + inline Value::Value(const void *v) + : ptype_(0) + { + inbox_ = new Instance_box(v, v == 0); + type_ = inbox_->type(); + } + + inline Value::Value(void *v) + : ptype_(0) + { + inbox_ = new Instance_box(v, v == 0); + type_ = inbox_->type(); + } + + template Value::Value(const T *v) + { + inbox_ = new Ptr_instance_box(v); + type_ = inbox_->type(); + ptype_ = inbox_->ptype(); + } + + template Value::Value(T *v) + { + inbox_ = new Ptr_instance_box(v); + type_ = inbox_->type(); + ptype_ = inbox_->ptype(); + } + + inline Value::Value(const Value ©) + : inbox_(copy.inbox_? copy.inbox_->clone(): 0), + type_(copy.type_), + ptype_(copy.ptype_) + { + } + + inline Value &Value::operator=(const Value ©) + { + std::auto_ptr new_inbox(copy.inbox_? copy.inbox_->clone(): 0); + delete inbox_; + inbox_ = new_inbox.release(); + type_ = copy.type_; + ptype_ = copy.ptype_; + return *this; + } + + inline bool Value::operator==(const Value &other) const + { + return compare(*this, other); + } + + inline bool Value::operator!=(const Value &other) const + { + return !compare(*this, other); + } + + inline Value::operator bool() const + { + return !isEmpty(); + } + + inline Value::~Value() + { + delete inbox_; + } + + inline const Type &Value::getType() const + { + return *type_; + } + + inline const Type &Value::getInstanceType() const + { + if (ptype_) + return *ptype_; + return *type_; + } + + inline bool Value::isTypedPointer() const + { + return ptype_ != 0; + } + + inline bool Value::isEmpty() const + { + return inbox_ == 0; + } + + inline bool Value::isNullPointer() const + { + return inbox_->nullptr(); + } + +} + +#endif diff --git a/include/osgIntrospection/variant_cast b/include/osgIntrospection/variant_cast new file mode 100644 index 000000000..b7938faa2 --- /dev/null +++ b/include/osgIntrospection/variant_cast @@ -0,0 +1,63 @@ +#ifndef OSGINTROSPECTION_VARIANT_CAST_ +#define OSGINTROSPECTION_VARIANT_CAST_ + +#include +#include + +#include + +namespace osgIntrospection +{ + + /// Tries to convert an instance of Value to an object of type T. + /// If T is a plain type or a pointer type (either const or non-const), + /// and it matches the type of the value contained in v, then the actual + /// value of type T is returned. If T is a [const] reference type, and + /// its base (non reference) type matches the internal value's type, + /// then a [const] reference to the internal value is returned. + /// If none of the above conditions are met, a conversion is attempted + /// as described in Value::convert() and then variant_cast is called again + /// with the converted value as parameter. + /// If the conversion can't be completed, an exception is thrown. + /// Conversions that attempt to make a const pointer non-const will fail. + template T variant_cast(const Value &v) + { + // return value + Value::Instance *i = dynamic_cast *>(v.inbox_->inst_); + if (i) return i->data_; + + // return reference to value + i = dynamic_cast *>(v.inbox_->ref_inst_); + if (i) return i->data_; + + // return const reference to value + i = dynamic_cast *>(v.inbox_->const_ref_inst_); + if (i) return i->data_; + + // try to convert v to type T and restart + return variant_cast(v.convertTo(typeof(T))); + } + + /// Returns a typed pointer to the data contained in a Value + /// instance. If the value's type is not identical to type T, + /// a null pointer is returned. + template T *extract_raw_data(Value &v) + { + Value::Instance *i = dynamic_cast *>(v.inbox_->inst_); + if (i) return &i->data_; + return 0; + } + + /// Returns a typed pointer to the data contained in a const Value + /// instance. If the value's type is not identical to type T, a + /// null pointer is returned. + template const T *extract_raw_data(const Value &v) + { + Value::Instance *i = dynamic_cast *>(v.inbox_->inst_); + if (i) return &i->data_; + return 0; + } + +} + +#endif diff --git a/src/osgIntrospection/CustomAttributeProvider.cpp b/src/osgIntrospection/CustomAttributeProvider.cpp new file mode 100644 index 000000000..90f31dd26 --- /dev/null +++ b/src/osgIntrospection/CustomAttributeProvider.cpp @@ -0,0 +1,43 @@ +#include +#include + +using namespace osgIntrospection; + +bool CustomAttributeProvider::isDefined(const Type &type, bool inherit) const +{ + for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i) + if (typeid(**i) == type.getStdTypeInfo()) return true; + + if (inherit) + { + CustomAttributeProviderList providers; + getInheritedProviders(providers); + + for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i) + { + if ((*i)->isDefined(type, true)) return true; + } + } + + return false; +} + +const CustomAttribute *CustomAttributeProvider::getAttribute(const Type &type, bool inherit) const +{ + for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i) + if (typeid(**i) == type.getStdTypeInfo()) return *i; + + if (inherit) + { + CustomAttributeProviderList providers; + getInheritedProviders(providers); + + for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i) + { + const CustomAttribute *ca = (*i)->getAttribute(type, true); + if (ca) return ca; + } + } + + return 0; +} diff --git a/src/osgIntrospection/DefaultReflectors.cpp b/src/osgIntrospection/DefaultReflectors.cpp new file mode 100644 index 000000000..a20ca0de6 --- /dev/null +++ b/src/osgIntrospection/DefaultReflectors.cpp @@ -0,0 +1,33 @@ +#include +#include + +#include + +// Built-in types + +ABSTRACT_OBJECT_REFLECTOR(void) + +STD_VALUE_REFLECTOR(char) +STD_VALUE_REFLECTOR(signed char) +STD_VALUE_REFLECTOR(unsigned char) + +STD_VALUE_REFLECTOR(int) +STD_VALUE_REFLECTOR(unsigned int) +STD_VALUE_REFLECTOR(long int) +STD_VALUE_REFLECTOR(long long int) +STD_VALUE_REFLECTOR(unsigned long int) +STD_VALUE_REFLECTOR(short int) +STD_VALUE_REFLECTOR(unsigned short int) + +STD_VALUE_REFLECTOR(bool) + +STD_VALUE_REFLECTOR(float) + +STD_VALUE_REFLECTOR(double) +STD_VALUE_REFLECTOR(long double) + + +// STL types + +STD_VALUE_REFLECTOR(std::string) + diff --git a/src/osgIntrospection/GNUmakefile b/src/osgIntrospection/GNUmakefile new file mode 100644 index 000000000..514e187a4 --- /dev/null +++ b/src/osgIntrospection/GNUmakefile @@ -0,0 +1,20 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + CustomAttributeProvider.cpp\ + DefaultReflectors.cpp\ + MethodInfo.cpp\ + PropertyInfo.cpp\ + Reflection.cpp\ + Type.cpp\ + Value.cpp\ + + +LIBS += $(OTHER_LIBS) $(DYNAMICLIBRARYLIB) +DEF += -DOSGINTROSPECTION_LIBRARY + +TARGET_BASENAME = osgIntrospection +LIB = $(LIB_PREFIX)$(TARGET_BASENAME).$(LIB_EXT) + +include $(TOPDIR)/Make/makerules diff --git a/src/osgIntrospection/MethodInfo.cpp b/src/osgIntrospection/MethodInfo.cpp new file mode 100644 index 000000000..d5832732c --- /dev/null +++ b/src/osgIntrospection/MethodInfo.cpp @@ -0,0 +1,15 @@ +#include + +using namespace osgIntrospection; + +void MethodInfo::getInheritedProviders(CustomAttributeProviderList &providers) const +{ + for (int i=0; i +#include +#include + +using namespace osgIntrospection; + +void PropertyInfo::getInheritedProviders(CustomAttributeProviderList &providers) const +{ + for (int i=0; i(false); + const CustomPropertyGetAttribute *cget = getAttribute(false); + + if (cget) + { + if (pta) + return cget->getGetter()->get(instance).convertTo(pta->getPropertyType()); + return cget->getGetter()->get(instance); + } + + if (!getm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::GET); + + if (pta) + return getm_->invoke(instance).convertTo(pta->getPropertyType()); + return getm_->invoke(instance); +} + +void PropertyInfo::setValue(Value &instance, const Value &value) const +{ + const CustomPropertySetAttribute *cset = getAttribute(false); + + if (cset) + { + cset->getSetter()->set(instance, value); + return; + } + + if (!setm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::SET); + + ValueList args; + args.push_back(value); + setm_->invoke(instance, args); +} + +Value PropertyInfo::getIndexedValue(const Value &instance, ValueList &args) const +{ + const PropertyTypeAttribute *pta = getAttribute(false); + const CustomPropertyGetAttribute *cget = getAttribute(false); + + if (cget) + { + if (pta) + return cget->getGetter()->get(instance, args).convertTo(pta->getPropertyType()); + return cget->getGetter()->get(instance, args); + } + + if (!getm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::IGET); + + if (pta) + return getm_->invoke(instance, args).convertTo(pta->getPropertyType()); + return getm_->invoke(instance, args); +} + +void PropertyInfo::setIndexedValue(Value &instance, ValueList &args, const Value &value) const +{ + const CustomPropertySetAttribute *cset = getAttribute(false); + if (cset) + { + cset->getSetter()->set(instance, args, value); + return; + } + + if (!setm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ISET); + + args.push_back(value); + setm_->invoke(instance, args); + args.pop_back(); +} + +int PropertyInfo::getNumArrayItems(const Value &instance) const +{ + const CustomPropertyCountAttribute *ccount = getAttribute(false); + if (ccount) return ccount->getCounter()->count(instance); + + if (!numm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::COUNT); + + return variant_cast(numm_->invoke(instance)); +} + +Value PropertyInfo::getArrayItem(const Value &instance, int i) const +{ + const PropertyTypeAttribute *pta = getAttribute(false); + const CustomPropertyGetAttribute *cget = getAttribute(false); + + if (cget) + { + if (pta) + return cget->getGetter()->get(instance, i).convertTo(pta->getPropertyType()); + return cget->getGetter()->get(instance, i); + } + + if (!getm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::AGET); + + ValueList args; + args.push_back(i); + + if (pta) + return getm_->invoke(instance, args).convertTo(pta->getPropertyType()); + return getm_->invoke(instance, args); +} + +void PropertyInfo::setArrayItem(Value &instance, int i, const Value &value) const +{ + const CustomPropertySetAttribute *cset = getAttribute(false); + if (cset) + { + cset->getSetter()->set(instance, i, value); + return; + } + + if (!setm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ASET); + + ValueList args; + args.push_back(i); + args.push_back(value); + setm_->invoke(instance, args); +} + +void PropertyInfo::addArrayItem(Value &instance, const Value &value) const +{ + const CustomPropertyAddAttribute *cadd = getAttribute(false); + if (cadd) + { + cadd->getAdder()->add(instance, value); + return; + } + + if (!addm_) + throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ADD); + + ValueList args; + args.push_back(value); + addm_->invoke(instance, args); +} + +Value PropertyInfo::getDefaultValue() const +{ + if (isArray() || isIndexed()) return Value(); + + const CustomAttributeList &cal = getCustomAttributes(); + for (CustomAttributeList::const_iterator i=cal.begin(); i!=cal.end(); ++i) + { + if (dynamic_cast(*i) != 0) + return Value(); + + const DefaultValueAttribute *dv = dynamic_cast(*i); + if (dv) + { + return dv->getDefaultValue(); + } + } + + if (decltype_.isAbstract()) + { + if (ptype_.isAbstract() || !ptype_.isDefined()) + return Value(); + return ptype_.createInstance(); + } + + // auto default value + Value instance = decltype_.createInstance(); + return getValue(instance); +} + +void PropertyInfo::getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const +{ + const CustomIndexAttribute *cia = getAttribute(false); + if (cia) + { + cia->getIndexInfo()->getIndexValueSet(whichindex, instance, values); + } + else + { + std::map ita_map; + const CustomAttributeList &cal = getCustomAttributes(); + for (CustomAttributeList::const_iterator i=cal.begin(); i!=cal.end(); ++i) + { + const IndexTypeAttribute *ita = dynamic_cast(*i); + if (ita) + ita_map[ita->getWhichIndex()] = ita; + } + + const EnumLabelMap &elm = getIndexParameters().at(whichindex)->getParameterType().getEnumLabels(); + if (elm.empty()) + throw IndexValuesNotDefinedException(name_, getIndexParameters().at(whichindex)->getName()); + + for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i) + { + if (ita_map[whichindex]) + values.push_back(Value(i->first).convertTo(ita_map[whichindex]->getIndexType())); + else + values.push_back(Value(i->first).convertTo(indices_[whichindex]->getParameterType())); + } + } +} + +const ParameterInfoList &PropertyInfo::getIndexParameters() const +{ + const CustomIndexAttribute *cia = getAttribute(false); + if (cia) + { + return cia->getIndexInfo()->getIndexParameters(); + } + + return indices_; +} diff --git a/src/osgIntrospection/Reflection.cpp b/src/osgIntrospection/Reflection.cpp new file mode 100644 index 000000000..57643bc29 --- /dev/null +++ b/src/osgIntrospection/Reflection.cpp @@ -0,0 +1,78 @@ +#include +#include +#include + +#include +#include + +#include + +using namespace osgIntrospection; + +Reflection::StaticData *Reflection::staticdata__ = 0; + +const TypeMap &Reflection::getTypes() +{ + return getOrCreateStaticData().typemap; +} + +Reflection::StaticData &Reflection::getOrCreateStaticData() +{ + static OpenThreads::Mutex access_mtx; + OpenThreads::ScopedLock lock(access_mtx); + + if (!staticdata__) + { + staticdata__ = new StaticData; + std::auto_ptr tvoid(new Type(typeid(void))); + staticdata__->typemap.insert(std::make_pair(&typeid(void), tvoid.get())); + staticdata__->type_void = tvoid.release(); + } + return *staticdata__; +} + +const Type &Reflection::getType(const std::type_info &ti) +{ + const TypeMap &types = getTypes(); + + TypeMap::const_iterator i = types.find(&ti); + if (i == types.end()) + { + return *registerType(ti); + } + return *i->second; +} + +const Type &Reflection::getType(const std::string &qname) +{ + const TypeMap &types = getTypes(); + + for (TypeMap::const_iterator i=types.begin(); i!=types.end(); ++i) + if (i->second->isDefined() && i->second->getQualifiedName().compare(qname) == 0) + return *i->second; + + throw TypeNotFoundException(qname); +} + +const Type &Reflection::type_void() +{ + return *getOrCreateStaticData().type_void; +} + +Type *Reflection::registerType(const std::type_info &ti) +{ + std::auto_ptr type(new Type(ti)); + getOrCreateStaticData().typemap.insert(std::make_pair(&ti, type.get())); + return type.release(); +} + +Type *Reflection::registerOrReplaceType(const std::type_info &ti) +{ + TypeMap &tm = getOrCreateStaticData().typemap; + TypeMap::iterator i = tm.find(&ti); + + if (i != tm.end()) + return new (i->second) Type(ti); + + return registerType(ti); +} diff --git a/src/osgIntrospection/Type.cpp b/src/osgIntrospection/Type.cpp new file mode 100644 index 000000000..17147425c --- /dev/null +++ b/src/osgIntrospection/Type.cpp @@ -0,0 +1,247 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace osgIntrospection; + +namespace +{ + + struct MethodMatch + { + int list_pos; + int exact_args; + const MethodInfo *method; + + bool operator < (const MethodMatch &m) const + { + if (exact_args > m.exact_args) return true; + if (exact_args < m.exact_args) return false; + if (list_pos < m.list_pos) return true; + return false; + } + }; + +} + +Type::~Type() +{ + for (PropertyInfoList::const_iterator i=props_.begin(); i!=props_.end(); ++i) + delete *i; + for (MethodInfoList::const_iterator i=methods_.begin(); i!=methods_.end(); ++i) + delete *i; + delete icb_; + delete rw_; +} + +bool Type::isSubclassOf(const Type &type) const +{ + check_defined(); + for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i) + { + if (**i == type.getStdTypeInfo()) + return true; + if ((*i)->isSubclassOf(type)) + return true; + } + return false; +} + +const MethodInfo *Type::getCompatibleMethod(const std::string &name, const ValueList &values, bool inherit) const +{ + check_defined(); + + MethodInfoList allmethods; + const MethodInfoList *methods; + if (inherit) + { + getAllMethods(allmethods); + methods = &allmethods; + } + else + methods = &methods_; + + typedef std::vector MatchList; + MatchList matches; + + int pos = 0; + for (MethodInfoList::const_iterator j=methods->begin(); j!=methods->end(); ++j, ++pos) + { + const MethodInfo *mi = *j; + if (mi->getName().compare(name) == 0) + { + const ParameterInfoList &other_params = mi->getParameters(); + if (values.size() == other_params.size()) + { + if (values.empty()) + return mi; + ParameterInfoList::const_iterator i1 = other_params.begin(); + ValueList::const_iterator i2 = values.begin(); + bool candidate = true; + int exact_args = 0; + for (; i1getParameterType() != i2->getType()) + { + if (i2->tryConvertTo((*i1)->getParameterType()).isEmpty()) + { + candidate = false; + break; + } + } + else + ++exact_args; + } + if (candidate) + { + MethodMatch mm; + mm.list_pos = pos; + mm.exact_args = exact_args; + mm.method = mi; + matches.push_back(mm); + } + } + } + } + + if (!matches.empty()) + { + std::sort(matches.begin(), matches.end()); + return matches.front().method; + } + + return 0; +} + +const MethodInfo *Type::getMethod(const std::string &name, const ParameterInfoList ¶ms, bool inherit) const +{ + check_defined(); + for (MethodInfoList::const_iterator j=methods_.begin(); j!=methods_.end(); ++j) + { + const MethodInfo &mi = **j; + if (mi.getName().compare(name) == 0) + { + const ParameterInfoList &other_params = mi.getParameters(); + if (params.size() == other_params.size()) + { + if (params.empty()) + return &mi; + ParameterInfoList::const_iterator i1 = params.begin(); + ParameterInfoList::const_iterator i2 = other_params.begin(); + for (; i1getMethod(name, params, true); + if (mi) return mi; + } + } + + return 0; +} + +void Type::getInheritedProviders(CustomAttributeProviderList &providers) const +{ + check_defined(); + providers.assign(base_.begin(), base_.end()); +} + +const PropertyInfo *Type::getProperty(const std::string &name, const Type &ptype, const ParameterInfoList &indices, bool inherit) const +{ + check_defined(); + for (PropertyInfoList::const_iterator i=props_.begin(); i!=props_.end(); ++i) + { + const PropertyInfo &pi = **i; + if (pi.getName() == name && pi.getPropertyType() == ptype) + { + const ParameterInfoList &other_indices = pi.getIndexParameters(); + if (indices.size() == other_indices.size()) + { + if (indices.empty()) + return π + ParameterInfoList::const_iterator i1 = indices.begin(); + ParameterInfoList::const_iterator i2 = other_indices.begin(); + for (; i1getProperty(name, ptype, indices, true); + if (pi) return pi; + } + } + + return 0; +} + +Value Type::invokeMethod(const std::string &name, const Value &instance, ValueList &args, bool inherit) const +{ + check_defined(); + const MethodInfo *mi = getCompatibleMethod(name, args, inherit); + if (!mi) throw MethodNotFoundException(name, name_); + return mi->invoke(instance, args); +} + +Value Type::invokeMethod(const std::string &name, Value &instance, ValueList &args, bool inherit) const +{ + check_defined(); + const MethodInfo *mi = getCompatibleMethod(name, args, inherit); + if (!mi) throw MethodNotFoundException(name, name_); + return mi->invoke(instance, args); +} + + +void Type::getAllProperties(PropertyInfoList &props) const +{ + check_defined(); + std::copy(props_.begin(), props_.end(), std::back_inserter(props)); + for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i) + { + (*i)->getAllProperties(props); + } +} + +void Type::getAllMethods(MethodInfoList &methods) const +{ + check_defined(); + std::copy(methods_.begin(), methods_.end(), std::back_inserter(methods)); + for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i) + { + (*i)->getAllMethods(methods); + } +} diff --git a/src/osgIntrospection/Value.cpp b/src/osgIntrospection/Value.cpp new file mode 100644 index 000000000..333f4a4b9 --- /dev/null +++ b/src/osgIntrospection/Value.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#include +#include + +using namespace osgIntrospection; + +Value Value::convertTo(const Type &outtype) const +{ + Value v = tryConvertTo(outtype); + if (v.isEmpty()) + throw TypeConversionException(type_->getStdTypeInfo(), outtype.getStdTypeInfo()); + return v; +} + +Value Value::tryConvertTo(const Type &outtype) const +{ + check_empty(); + + if (type_ == &outtype) + return *this; + + if (type_->isConstPointer() && outtype.isNonConstPointer()) + return Value(); + + std::auto_ptr wopt; + + if (type_->isEnum() && (outtype.getQualifiedName() == "int" || outtype.getQualifiedName() == "unsigned int")) + { + wopt.reset(new ReaderWriter::Options); + wopt->setForceNumericOutput(true); + } + + const ReaderWriter *src_rw = type_->getReaderWriter(); + if (src_rw) + { + const ReaderWriter *dst_rw = outtype.getReaderWriter(); + if (dst_rw) + { + std::ostringstream oss; + if (src_rw->writeTextValue(oss, *this, wopt.get())) + { + Value v; + std::istringstream iss(oss.str()); + if (dst_rw->readTextValue(iss, v)) + { + return v; + } + } + } + } + + return Value(); +} + +std::string Value::toString() const +{ + check_empty(); + + const ReaderWriter *rw = type_->getReaderWriter(); + if (rw) + { + std::ostringstream oss; + if (!rw->writeTextValue(oss, *this)) + throw StreamWriteErrorException(); + return oss.str(); + } + throw StreamingNotSupportedException(StreamingNotSupportedException::ANY, type_->getStdTypeInfo()); +} + +bool Value::compare(const Value &v1, const Value &v2) +{ + if (v1.isEmpty() && v2.isEmpty()) return true; + if (v1.isEmpty() || v2.isEmpty()) return false; + if (v1.type_ == v2.type_) return v1.inbox_->equal(v2); + Value temp(v2.convertTo(v1.getType())); + return compare(v1, temp); +} + +void Value::check_empty() const +{ + if (!type_ || !inbox_) + throw EmptyValueException(); +} diff --git a/src/osgWrappers/GNUmakefile b/src/osgWrappers/GNUmakefile new file mode 100644 index 000000000..bfd1aaa1f --- /dev/null +++ b/src/osgWrappers/GNUmakefile @@ -0,0 +1,7 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs +include $(TOPDIR)/Make/makedirdefs + +DIRS = $(WRAPPER_DIRS) + +include $(TOPDIR)/Make/makedirrules diff --git a/src/osgWrappers/osg/BlendFunc.cpp b/src/osgWrappers/osg/BlendFunc.cpp new file mode 100644 index 000000000..7f7b33c5f --- /dev/null +++ b/src/osgWrappers/osg/BlendFunc.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +BEGIN_ENUM_REFLECTOR(osg::BlendFunc::BlendFuncMode) + EnumLabel(osg::BlendFunc::DST_ALPHA); + EnumLabel(osg::BlendFunc::DST_COLOR); + EnumLabel(osg::BlendFunc::ONE); + EnumLabel(osg::BlendFunc::ONE_MINUS_DST_ALPHA); + EnumLabel(osg::BlendFunc::ONE_MINUS_DST_COLOR); + EnumLabel(osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + EnumLabel(osg::BlendFunc::ONE_MINUS_SRC_COLOR); + EnumLabel(osg::BlendFunc::SRC_ALPHA); + EnumLabel(osg::BlendFunc::SRC_ALPHA_SATURATE); + EnumLabel(osg::BlendFunc::SRC_COLOR); + EnumLabel(osg::BlendFunc::CONSTANT_COLOR); + EnumLabel(osg::BlendFunc::ONE_MINUS_CONSTANT_COLOR); + EnumLabel(osg::BlendFunc::CONSTANT_ALPHA); + EnumLabel(osg::BlendFunc::ONE_MINUS_CONSTANT_ALPHA); + EnumLabel(osg::BlendFunc::ZERO); +END_REFLECTOR + +BEGIN_OBJECT_REFLECTOR(osg::BlendFunc) + BaseType(osg::StateAttribute) + Method2(void, setFunction, IN, GLenum, source, IN, GLenum, destination); + + Property(GLenum, Source); + Attribute(PropertyTypeAttribute(typeof(osg::BlendFunc::BlendFuncMode))); + + Property(GLenum, Destination); + Attribute(PropertyTypeAttribute(typeof(osg::BlendFunc::BlendFuncMode))); + +END_REFLECTOR diff --git a/src/osgWrappers/osg/Drawable.cpp b/src/osgWrappers/osg/Drawable.cpp new file mode 100644 index 000000000..52a2a0c69 --- /dev/null +++ b/src/osgWrappers/osg/Drawable.cpp @@ -0,0 +1,13 @@ +#include +#include +#include + +#include + +BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::Drawable) + BaseType(osg::Object); + Property(osg::StateSet *, StateSet); + ReadOnlyProperty(osg::Drawable::ParentList, Parents); +END_REFLECTOR + +STD_CONTAINER_REFLECTOR(osg::Drawable::ParentList); diff --git a/src/osgWrappers/osg/GNUmakefile b/src/osgWrappers/osg/GNUmakefile new file mode 100644 index 000000000..5f99d3239 --- /dev/null +++ b/src/osgWrappers/osg/GNUmakefile @@ -0,0 +1,24 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + BlendFunc.cpp\ + Drawable.cpp\ + Geode.cpp\ + Geometry.cpp\ + Group.cpp\ + Material.cpp\ + Node.cpp\ + Object.cpp\ + StateAttribute.cpp\ + StateSet.cpp\ + Vec2.cpp\ + + +LIBS += -losg -losgIntrospection $(OTHER_LIBS) + +TARGET_BASENAME = osg +include $(TOPDIR)/Make/cygwin_wrapper_def +WRAPPER = $(WRAPPER_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT) + +include $(TOPDIR)/Make/makerules diff --git a/src/osgWrappers/osg/Geode.cpp b/src/osgWrappers/osg/Geode.cpp new file mode 100644 index 000000000..7258773dd --- /dev/null +++ b/src/osgWrappers/osg/Geode.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +BEGIN_OBJECT_REFLECTOR(osg::Geode) + BaseType(osg::Node); + ArrayPropertyWithReturnType(osg::Drawable *, Drawable, Drawables, bool); +END_REFLECTOR diff --git a/src/osgWrappers/osg/Geometry.cpp b/src/osgWrappers/osg/Geometry.cpp new file mode 100644 index 000000000..4bf36bac2 --- /dev/null +++ b/src/osgWrappers/osg/Geometry.cpp @@ -0,0 +1,16 @@ +#include +#include +#include + +#include +#include + +BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::Drawable) + BaseType(osg::Object); + Property(osg::StateSet *, StateSet); + ReadOnlyProperty(osg::Drawable::ParentList, Parents); +END_REFLECTOR + +BEGIN_OBJECT_REFLECTOR(osg::Geometry) + BaseType(osg::Drawable); +END_REFLECTOR diff --git a/src/osgWrappers/osg/Group.cpp b/src/osgWrappers/osg/Group.cpp new file mode 100644 index 000000000..c700c1ed4 --- /dev/null +++ b/src/osgWrappers/osg/Group.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +BEGIN_OBJECT_REFLECTOR(osg::Group) + BaseType(osg::Node); + ArrayPropertyWithReturnType(osg::Node *, Child, Children, bool); +END_REFLECTOR diff --git a/src/osgWrappers/osg/Material.cpp b/src/osgWrappers/osg/Material.cpp new file mode 100644 index 000000000..b7d5acc53 --- /dev/null +++ b/src/osgWrappers/osg/Material.cpp @@ -0,0 +1,31 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +BEGIN_ENUM_REFLECTOR(osg::Material::Face) + EnumLabel(osg::Material::FRONT); + EnumLabel(osg::Material::BACK); + EnumLabel(osg::Material::FRONT_AND_BACK); +END_REFLECTOR + +BEGIN_ENUM_REFLECTOR(osg::Material::ColorMode) + EnumLabel(osg::Material::AMBIENT); + EnumLabel(osg::Material::SPECULAR); + EnumLabel(osg::Material::DIFFUSE); + EnumLabel(osg::Material::EMISSION); + EnumLabel(osg::Material::AMBIENT_AND_DIFFUSE); + EnumLabel(osg::Material::OFF); +END_REFLECTOR + +BEGIN_OBJECT_REFLECTOR(osg::Material) + BaseType(osg::StateAttribute); + Property(osg::Material::ColorMode, ColorMode); + IndexedProperty(const osg::Vec4 &, Ambient, osg::Material::Face, face); + IndexedProperty(const osg::Vec4 &, Diffuse, osg::Material::Face, face); + IndexedProperty(const osg::Vec4 &, Specular, osg::Material::Face, face); +END_REFLECTOR + diff --git a/src/osgWrappers/osg/Node.cpp b/src/osgWrappers/osg/Node.cpp new file mode 100644 index 000000000..7bef6414e --- /dev/null +++ b/src/osgWrappers/osg/Node.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +#include +#include + +using namespace osgIntrospection; + +BEGIN_OBJECT_REFLECTOR(osg::NodeCallback) + BaseType(osg::Object); + Property(osg::NodeCallback *, NestedCallback); +END_REFLECTOR + +BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::Node) + BaseType(osg::Object); + Property(const std::string &, Name); + Property(osg::NodeCallback *, UpdateCallback); + Property(osg::StateSet *, StateSet); + ReadOnlyProperty(osg::Node::ParentList, Parents); +END_REFLECTOR + +STD_CONTAINER_REFLECTOR(osg::Node::ParentList); diff --git a/src/osgWrappers/osg/Object.cpp b/src/osgWrappers/osg/Object.cpp new file mode 100644 index 000000000..e0c58987a --- /dev/null +++ b/src/osgWrappers/osg/Object.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +// simple reflectors for types that are considered 'atomic' +ABSTRACT_OBJECT_REFLECTOR(osg::Referenced) + +BEGIN_ENUM_REFLECTOR(osg::Object::DataVariance) + EnumLabel(osg::Object::STATIC); + EnumLabel(osg::Object::DYNAMIC); +END_REFLECTOR + +BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::Object) + BaseType(osg::Referenced); + Property(osg::Object::DataVariance, DataVariance); + + Property(osg::Referenced *, UserData); + Attribute(DefaultValueAttribute(0)); +END_REFLECTOR diff --git a/src/osgWrappers/osg/StateAttribute.cpp b/src/osgWrappers/osg/StateAttribute.cpp new file mode 100644 index 000000000..9e8d1ab2e --- /dev/null +++ b/src/osgWrappers/osg/StateAttribute.cpp @@ -0,0 +1,65 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::StateAttribute) + BaseType(osg::Object); +END_REFLECTOR + +BEGIN_ENUM_REFLECTOR(osg::StateAttribute::Values) + EnumLabel(osg::StateAttribute::OFF); + EnumLabel(osg::StateAttribute::ON); + EnumLabel(osg::StateAttribute::OVERRIDE); + EnumLabel(osg::StateAttribute::PROTECTED); + EnumLabel(osg::StateAttribute::INHERIT); +END_REFLECTOR + + +BEGIN_ENUM_REFLECTOR(osg::StateAttribute::Type) + EnumLabel(osg::StateAttribute::TEXTURE); + EnumLabel(osg::StateAttribute::POLYGONMODE); + EnumLabel(osg::StateAttribute::POLYGONOFFSET); + EnumLabel(osg::StateAttribute::MATERIAL); + EnumLabel(osg::StateAttribute::ALPHAFUNC); + EnumLabel(osg::StateAttribute::ANTIALIAS); + EnumLabel(osg::StateAttribute::COLORTABLE); + EnumLabel(osg::StateAttribute::CULLFACE); + EnumLabel(osg::StateAttribute::FOG); + EnumLabel(osg::StateAttribute::FRONTFACE); + EnumLabel(osg::StateAttribute::LIGHT); + EnumLabel(osg::StateAttribute::POINT); + EnumLabel(osg::StateAttribute::LINEWIDTH); + EnumLabel(osg::StateAttribute::LINESTIPPLE); + EnumLabel(osg::StateAttribute::POLYGONSTIPPLE); + EnumLabel(osg::StateAttribute::SHADEMODEL); + EnumLabel(osg::StateAttribute::TEXENV); + EnumLabel(osg::StateAttribute::TEXENVFILTER); + EnumLabel(osg::StateAttribute::TEXGEN); + EnumLabel(osg::StateAttribute::TEXMAT); + EnumLabel(osg::StateAttribute::LIGHTMODEL); + EnumLabel(osg::StateAttribute::BLENDFUNC); + EnumLabel(osg::StateAttribute::STENCIL); + EnumLabel(osg::StateAttribute::COLORMASK); + EnumLabel(osg::StateAttribute::DEPTH); + EnumLabel(osg::StateAttribute::VIEWPORT); + EnumLabel(osg::StateAttribute::BLENDCOLOR); + EnumLabel(osg::StateAttribute::MULTISAMPLE); + EnumLabel(osg::StateAttribute::CLIPPLANE); + EnumLabel(osg::StateAttribute::COLORMATRIX); + EnumLabel(osg::StateAttribute::VERTEXPROGRAM); + EnumLabel(osg::StateAttribute::FRAGMENTPROGRAM); + EnumLabel(osg::StateAttribute::POINTSPRITE); + EnumLabel(osg::StateAttribute::PROGRAMOBJECT); + EnumLabel(osg::StateAttribute::VALIDATOR); + EnumLabel(osg::StateAttribute::VIEWMATRIXEXTRACTOR); + EnumLabel(osg::StateAttribute::PARAMETER_BLOCK); + EnumLabel(osg::StateAttribute::TEXTURE_SHADER); + EnumLabel(osg::StateAttribute::VERTEX_PROGRAM); + EnumLabel(osg::StateAttribute::REGISTER_COMBINERS); + EnumLabel(osg::StateAttribute::PROGRAM); + EnumLabel(osg::StateAttribute::PROGRAM_PARSER); +END_REFLECTOR diff --git a/src/osgWrappers/osg/StateSet.cpp b/src/osgWrappers/osg/StateSet.cpp new file mode 100644 index 000000000..54393b2cd --- /dev/null +++ b/src/osgWrappers/osg/StateSet.cpp @@ -0,0 +1,53 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::StateAttribute) + BaseType(osg::Object); +END_REFLECTOR + +BEGIN_OBJECT_REFLECTOR(osg::StateSet) + BaseType(osg::Object) +END_REFLECTOR + +BEGIN_ENUM_REFLECTOR(osg::StateSet::RenderingHint) + EnumLabel(osg::StateSet::DEFAULT_BIN); + EnumLabel(osg::StateSet::OPAQUE_BIN); + EnumLabel(osg::StateSet::TRANSPARENT_BIN); +END_REFLECTOR + +BEGIN_ENUM_REFLECTOR(osg::StateSet::RenderBinMode) + EnumLabel(osg::StateSet::ENCLOSE_RENDERBIN_DETAILS); + EnumLabel(osg::StateSet::INHERIT_RENDERBIN_DETAILS); + EnumLabel(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); + EnumLabel(osg::StateSet::USE_RENDERBIN_DETAILS); +END_REFLECTOR + +STD_MAP_REFLECTOR_WITH_TYPES(osg::StateSet::ModeList, unsigned int, osg::StateAttribute::Values); +STD_MAP_REFLECTOR(osg::StateSet::AttributeList); +STD_CONTAINER_REFLECTOR(osg::StateSet::TextureAttributeList); +STD_CONTAINER_REFLECTOR(osg::StateSet::TextureModeList); + +BEGIN_OBJECT_REFLECTOR(osg::StateSet) + BaseType(osg::Object) + Property(int, RenderingHint); + Attribute(PropertyTypeAttribute(typeof(osg::StateSet::RenderingHint))); + + ReadOnlyProperty(const osg::StateSet::ModeList &, ModeList); + ReadOnlyProperty(const osg::StateSet::AttributeList &, AttributeList); + ReadOnlyProperty(const osg::StateSet::TextureModeList &, TextureModeList); + ReadOnlyProperty(const osg::StateSet::TextureAttributeList &, TextureAttributeList); + +END_REFLECTOR + + +typedef osg::ref_ptr RefStateAttribute; +STD_VALUE_REFLECTOR(RefStateAttribute); + +STD_PAIR_REFLECTOR(osg::StateAttribute::TypeMemberPair) +STD_PAIR_REFLECTOR_WITH_TYPES(osg::StateSet::RefAttributePair, osg::StateAttribute *, osg::StateAttribute::Values) + diff --git a/src/osgWrappers/osg/Vec2.cpp b/src/osgWrappers/osg/Vec2.cpp new file mode 100644 index 000000000..7b277d2bc --- /dev/null +++ b/src/osgWrappers/osg/Vec2.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +#include + +using namespace osgIntrospection; + +// simple reflectors for types that are considered 'atomic' +STD_VALUE_REFLECTOR(osg::Vec2)