2fbbbca1a0
the declaring file for a given type via the new member function osgIntrospection::Type::getDeclaringFile. This information is useful in order to know what header to include when auto-generating wrappers for a given type. During the C# wrapper generator development I've been keeping the declaring file configuration state up-to-date manually with changes to OSG, and it's proven to require substantial effort. So it would be extremely valuable to get this change in before 2.0 to reduce maintenance during the lifetime of the release. It'll also be equally useful to others looking to create wrapper generators using osgIntrospection. This is a fairly simple change and was tested with a fresh rebuild of the entire suite of osgWrapper libraries, so it should be relatively low risk (fingers crossed)."
978 lines
34 KiB
C++
978 lines
34 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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.
|
|
*/
|
|
//osgIntrospection - Copyright (C) 2005 Marco Jez
|
|
|
|
#ifndef OSGINTROSPECTION_REFLECTOR_
|
|
#define OSGINTROSPECTION_REFLECTOR_
|
|
|
|
#include <osgIntrospection/Reflection>
|
|
#include <osgIntrospection/Type>
|
|
#include <osgIntrospection/Value>
|
|
#include <osgIntrospection/PropertyInfo>
|
|
#include <osgIntrospection/MethodInfo>
|
|
#include <osgIntrospection/ConstructorInfo>
|
|
#include <osgIntrospection/InstanceCreator>
|
|
#include <osgIntrospection/ReaderWriter>
|
|
#include <osgIntrospection/TypedConstructorInfo>
|
|
#include <osgIntrospection/Comparator>
|
|
#include <osgIntrospection/Utility>
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <iterator>
|
|
|
|
namespace osgIntrospection
|
|
{
|
|
|
|
class CustomAttribute;
|
|
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*, const T*, T&, and const T&. You
|
|
/// should NEVER create reflectors for pointer or reference types
|
|
/// explicitly.
|
|
///
|
|
template<typename T>
|
|
class Reflector
|
|
{
|
|
public:
|
|
typedef T reflected_type;
|
|
typedef Reflector<T> inherited;
|
|
|
|
/// Virtual destructor.
|
|
virtual ~Reflector() {}
|
|
|
|
protected:
|
|
/// Direct initialization constructor. Parameter 'name' is the name
|
|
/// of the type being reflected and 'ns' is its namespace.
|
|
Reflector(const std::string& name, const std::string& ns, bool abstract = false);
|
|
|
|
/// 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 "::").
|
|
Reflector(const std::string& qname, bool abstract = false);
|
|
|
|
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);
|
|
|
|
/// Sets the comparator object for the current type.
|
|
void setComparator(const Comparator* cmp);
|
|
|
|
/// 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 a protected method description to the current type.
|
|
MethodInfo* addProtectedMethod(MethodInfo* mi);
|
|
|
|
/// Adds an enumeration label to the current type.
|
|
void addEnumLabel(int v, const std::string& label, bool strip_namespace = true);
|
|
|
|
/// Adds a constructor description to the current type.
|
|
/// As soon as a constructor is added through this method,
|
|
/// the automatically-generated default constructor is
|
|
/// removed.
|
|
ConstructorInfo* addConstructor(ConstructorInfo* ci);
|
|
|
|
/// Adds a protected constructor description to the current
|
|
/// type.
|
|
ConstructorInfo* addProtectedConstructor(ConstructorInfo* ci);
|
|
|
|
/// 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);
|
|
|
|
/// Sets the current type's declaring file.
|
|
void setDeclaringFile(const std::string& file) const;
|
|
|
|
private:
|
|
struct PtrConstructor: ConstructorInfo
|
|
{
|
|
PtrConstructor(const Type* pt)
|
|
: ConstructorInfo(*pt, ParameterInfoList())
|
|
{
|
|
}
|
|
|
|
Value createInstance(ValueList& ) const { T* x = 0; return x; }
|
|
};
|
|
|
|
struct ConstPtrConstructor: ConstructorInfo
|
|
{
|
|
ConstPtrConstructor(const Type* pt)
|
|
: ConstructorInfo(*pt, ParameterInfoList())
|
|
{
|
|
}
|
|
|
|
Value createInstance(ValueList& ) const { const T *x = 0; return x; }
|
|
};
|
|
|
|
void init();
|
|
void init_reference_types();
|
|
static std::string purify(const std::string& s);
|
|
static void split_qualified_name(const std::string& q, std::string& n, std::string& ns);
|
|
|
|
typedef std::vector<MethodInfo* > TempMethodList;
|
|
TempMethodList _temp_methods;
|
|
TempMethodList _temp_protected_methods;
|
|
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<typename T>
|
|
struct ValueReflector: Reflector<T>
|
|
{
|
|
typedef ValueReflector<T> inherited;
|
|
typedef ValueInstanceCreator<typename Reflector<T>::reflected_type> instance_creator_type;
|
|
typedef ProtectedConstructorInstanceCreator<typename Reflector<T>::reflected_type> invalid_instance_creator_type;
|
|
|
|
ValueReflector(const std::string& name, const std::string& ns)
|
|
: Reflector<T>(name, ns, false)
|
|
{
|
|
}
|
|
|
|
ValueReflector(const std::string& qname)
|
|
: Reflector<T>(qname, false)
|
|
{
|
|
}
|
|
};
|
|
|
|
/// This reflector is to be used to describe abstract types that can't
|
|
/// be instantiated. For this reason a DummyInstanceCreator is used in
|
|
/// order to avoid compiler errors.
|
|
template<typename T>
|
|
struct AbstractObjectReflector: Reflector<T>
|
|
{
|
|
typedef AbstractObjectReflector<T> inherited;
|
|
typedef DummyInstanceCreator<typename Reflector<T>::reflected_type> instance_creator_type;
|
|
typedef ProtectedConstructorInstanceCreator<typename Reflector<T>::reflected_type> invalid_instance_creator_type;
|
|
|
|
AbstractObjectReflector(const std::string& name, const std::string& ns)
|
|
: Reflector<T>(name, ns, true)
|
|
{
|
|
}
|
|
|
|
AbstractObjectReflector(const std::string& qname)
|
|
: Reflector<T>(qname, true)
|
|
{
|
|
}
|
|
};
|
|
|
|
/// 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<typename T>
|
|
struct ObjectReflector: Reflector<T>
|
|
{
|
|
typedef ObjectReflector<T> inherited;
|
|
typedef ObjectInstanceCreator<typename Reflector<T>::reflected_type> instance_creator_type;
|
|
typedef ProtectedConstructorInstanceCreator<typename Reflector<T>::reflected_type> invalid_instance_creator_type;
|
|
|
|
ObjectReflector(const std::string& name, const std::string& ns)
|
|
: Reflector<T>(name, ns, false)
|
|
{
|
|
}
|
|
|
|
ObjectReflector(const std::string& qname)
|
|
: Reflector<T>(qname, false)
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
/// 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<typename T>
|
|
struct AtomicValueReflector: ValueReflector<T>
|
|
{
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
AtomicValueReflector(const std::string& name, const std::string& ns)
|
|
: ValueReflector<T>(name, ns)
|
|
{
|
|
setReaderWriter(new StdReaderWriter<T>);
|
|
setComparator(new PartialOrderComparator<T>);
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
}
|
|
|
|
AtomicValueReflector(const std::string& qname)
|
|
: ValueReflector<T>(qname)
|
|
{
|
|
setReaderWriter(new StdReaderWriter<T>);
|
|
setComparator(new PartialOrderComparator<T>);
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct WAtomicValueReflector: ValueReflector<T>
|
|
{
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
WAtomicValueReflector(const std::string& name, const std::string& ns)
|
|
: ValueReflector<T>(name, ns)
|
|
{
|
|
setReaderWriter(new StdWReaderWriter<T>);
|
|
setComparator(new PartialOrderComparator<T>);
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
}
|
|
|
|
WAtomicValueReflector(const std::string& qname)
|
|
: ValueReflector<T>(qname)
|
|
{
|
|
setReaderWriter(new StdWReaderWriter<T>);
|
|
setComparator(new PartialOrderComparator<T>);
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
}
|
|
};
|
|
|
|
|
|
/// This reflector is a ValueReflector that should be used to define
|
|
/// enumerations. It assigns an EnumReaderWriter by default.
|
|
template<typename T>
|
|
struct EnumReflector: ValueReflector<T>
|
|
{
|
|
typedef EnumReflector<T> inherited;
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
EnumReflector(const std::string& name, const std::string& ns)
|
|
: ValueReflector<T>(name, ns)
|
|
{
|
|
setReaderWriter(new EnumReaderWriter<T>);
|
|
setComparator(new TotalOrderComparator<T>);
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
}
|
|
|
|
EnumReflector(const std::string& qname)
|
|
: ValueReflector<T>(qname)
|
|
{
|
|
setReaderWriter(new EnumReaderWriter<T>);
|
|
setComparator(new TotalOrderComparator<T>);
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
}
|
|
};
|
|
|
|
|
|
/// This class allows to define the means for reflecting STL containers
|
|
/// such as std::deque and std::vector.
|
|
template<typename T, typename VT>
|
|
struct StdVectorReflector: ValueReflector<T>
|
|
{
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
struct Getter: PropertyGetter
|
|
{
|
|
virtual Value get(Value& instance, int i) const
|
|
{
|
|
return getInstance<T>(instance).at(i);
|
|
}
|
|
|
|
virtual Value get(const Value& instance, int i) const
|
|
{
|
|
return getInstance<T>(instance).at(i);
|
|
}
|
|
};
|
|
|
|
struct Setter: PropertySetter
|
|
{
|
|
virtual void set(Value& instance, int i, const Value& v) const
|
|
{
|
|
getInstance<T>(instance).at(i) = variant_cast<const typename T::value_type& >(v);
|
|
}
|
|
};
|
|
|
|
struct Counter: PropertyCounter
|
|
{
|
|
virtual int count(const Value& instance) const
|
|
{
|
|
return static_cast<int>(getInstance<T>(instance).size());
|
|
}
|
|
};
|
|
|
|
struct Adder: PropertyAdder
|
|
{
|
|
virtual void add(Value& instance, const Value& v) const
|
|
{
|
|
getInstance<T>(instance).push_back(variant_cast<const typename T::value_type& >(v));
|
|
}
|
|
};
|
|
|
|
struct Remover: PropertyRemover
|
|
{
|
|
virtual void remove(Value& instance, int i) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
ctr.erase(j);
|
|
}
|
|
};
|
|
|
|
struct Inserter: PropertyInserter
|
|
{
|
|
virtual void insert(Value& instance, int i, const Value& v) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
ctr.insert(j, variant_cast<const typename T::value_type& >(v));
|
|
}
|
|
};
|
|
|
|
StdVectorReflector(const std::string& name): ValueReflector<T>(name)
|
|
{
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
|
|
PropertyInfo* pi = new PropertyInfo(typeof(T), typeof(typename T::value_type), "Item", 0, 0, 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));
|
|
pi->addAttribute(new CustomPropertyRemoveAttribute(new Remover));
|
|
pi->addAttribute(new CustomPropertyInsertAttribute(new Inserter));
|
|
|
|
if (typeid(VT).before(typeid(typename T::value_type)) ||
|
|
typeid(typename T::value_type).before(typeid(VT)))
|
|
{
|
|
pi->addAttribute(new PropertyTypeAttribute(typeof(VT)));
|
|
}
|
|
|
|
this->addProperty(pi);
|
|
}
|
|
};
|
|
|
|
/// This class allows to define the means for reflecting STL containers
|
|
/// such as std::set and std::multiset.
|
|
template<typename T, typename VT>
|
|
struct StdSetReflector: ValueReflector<T>
|
|
{
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
struct Getter: PropertyGetter
|
|
{
|
|
virtual Value get(Value& instance, int i) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
return *j;
|
|
}
|
|
|
|
virtual Value get(const Value& instance, int i) const
|
|
{
|
|
const T& ctr = getInstance<T>(instance);
|
|
typename T::const_iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
return *j;
|
|
}
|
|
};
|
|
|
|
struct Counter: PropertyCounter
|
|
{
|
|
virtual int count(const Value& instance) const
|
|
{
|
|
return static_cast<int>(getInstance<T>(instance).size());
|
|
}
|
|
};
|
|
|
|
struct Adder: PropertyAdder
|
|
{
|
|
virtual void add(Value& instance, const Value& v) const
|
|
{
|
|
getInstance<T>(instance).insert(variant_cast<const typename T::value_type& >(v));
|
|
}
|
|
};
|
|
|
|
struct Remover: PropertyRemover
|
|
{
|
|
virtual void remove(Value& instance, int i) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
ctr.erase(j);
|
|
}
|
|
};
|
|
|
|
StdSetReflector(const std::string& name): ValueReflector<T>(name)
|
|
{
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
|
|
PropertyInfo* pi = new PropertyInfo(typeof(T), typeof(typename T::value_type), "Item", 0, 0, 0, 0, 0, 0);
|
|
pi->addAttribute(new CustomPropertyGetAttribute(new Getter));
|
|
pi->addAttribute(new CustomPropertyCountAttribute(new Counter));
|
|
pi->addAttribute(new CustomPropertyAddAttribute(new Adder));
|
|
pi->addAttribute(new CustomPropertyRemoveAttribute(new Remover));
|
|
|
|
if (typeid(VT).before(typeid(typename T::value_type)) ||
|
|
typeid(typename T::value_type).before(typeid(VT)))
|
|
{
|
|
pi->addAttribute(new PropertyTypeAttribute(typeof(VT)));
|
|
}
|
|
|
|
this->addProperty(pi);
|
|
}
|
|
};
|
|
|
|
/// This class allows to define the means for reflecting STL containers
|
|
/// that cannot be indexed directly, such as std::list.
|
|
template<typename T, typename VT>
|
|
struct StdListReflector: ValueReflector<T>
|
|
{
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
struct Getter: PropertyGetter
|
|
{
|
|
virtual Value get(Value& instance, int i) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
return *j;
|
|
}
|
|
|
|
virtual Value get(const Value& instance, int i) const
|
|
{
|
|
const T& ctr = getInstance<T>(instance);
|
|
typename T::const_iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
return *j;
|
|
}
|
|
};
|
|
|
|
struct Setter: PropertySetter
|
|
{
|
|
virtual void set(Value& instance, int i, const Value& v) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
*j = variant_cast<const typename T::value_type& >(v);
|
|
}
|
|
};
|
|
|
|
struct Counter: PropertyCounter
|
|
{
|
|
virtual int count(const Value& instance) const
|
|
{
|
|
return static_cast<int>(getInstance<T>(instance).size());
|
|
}
|
|
};
|
|
|
|
struct Adder: PropertyAdder
|
|
{
|
|
virtual void add(Value& instance, const Value& v) const
|
|
{
|
|
getInstance<T>(instance).push_back(variant_cast<const typename T::value_type& >(v));
|
|
}
|
|
};
|
|
|
|
struct Remover: PropertyRemover
|
|
{
|
|
virtual void remove(Value& instance, int i) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
ctr.erase(j);
|
|
}
|
|
};
|
|
|
|
struct Inserter: PropertyInserter
|
|
{
|
|
virtual void insert(Value& instance, int i, const Value& v) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
typename T::iterator j=ctr.begin();
|
|
std::advance(j, i);
|
|
ctr.insert(j, variant_cast<const typename T::value_type& >(v));
|
|
}
|
|
};
|
|
|
|
StdListReflector(const std::string& name): ValueReflector<T>(name)
|
|
{
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
|
|
PropertyInfo* pi = new PropertyInfo(typeof(T), typeof(typename T::value_type), "Item", 0, 0, 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));
|
|
pi->addAttribute(new CustomPropertyRemoveAttribute(new Remover));
|
|
pi->addAttribute(new CustomPropertyInsertAttribute(new Inserter));
|
|
|
|
if (typeid(VT).before(typeid(typename T::value_type)) ||
|
|
typeid(typename T::value_type).before(typeid(VT)))
|
|
{
|
|
pi->addAttribute(new PropertyTypeAttribute(typeof(VT)));
|
|
}
|
|
|
|
this->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<typename T, typename IT, typename VT>
|
|
struct StdMapReflector: ValueReflector<T>
|
|
{
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
typedef typename T::iterator iterator;
|
|
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(Value& instance, const ValueList& indices) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
const key_type& key = variant_cast<const key_type& >(indices.front());
|
|
|
|
iterator i = ctr.find(key);
|
|
if (i == ctr.end()) return Value();
|
|
return i->second;
|
|
}
|
|
|
|
virtual Value get(const Value& instance, const ValueList& indices) const
|
|
{
|
|
const T& ctr = getInstance<T>(instance);
|
|
const key_type& key = variant_cast<const key_type& >(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
|
|
{
|
|
getInstance<T>(instance).insert(std::make_pair(variant_cast<const key_type& >(indices.front()),
|
|
variant_cast<const mapped_type& >(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 = getInstance<T>(instance);
|
|
for (const_iterator i=ctr.begin();
|
|
i!=ctr.end();
|
|
++i)
|
|
{
|
|
values.push_back(Value(i->first).convertTo(_itype));
|
|
}
|
|
}
|
|
};
|
|
|
|
struct Remover: PropertyRemover
|
|
{
|
|
virtual void remove(Value& instance, ValueList& values) const
|
|
{
|
|
getInstance<T>(instance).erase(getInstance<key_type>(values.front()));
|
|
}
|
|
};
|
|
|
|
StdMapReflector(const std::string& name): ValueReflector<T>(name)
|
|
{
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
|
|
PropertyInfo* pi = new PropertyInfo(typeof(T), typeof(typename T::mapped_type), "Item", 0, 0, 0);
|
|
pi->addAttribute(new CustomPropertyGetAttribute(new Getter));
|
|
pi->addAttribute(new CustomPropertySetAttribute(new Setter));
|
|
pi->addAttribute(new CustomIndexAttribute(new Indexer));
|
|
pi->addAttribute(new CustomPropertyRemoveAttribute(new Remover));
|
|
|
|
if (typeid(VT).before(typeid(typename T::mapped_type)) ||
|
|
typeid(typename T::mapped_type).before(typeid(VT)))
|
|
{
|
|
pi->addAttribute(new PropertyTypeAttribute(typeof(VT)));
|
|
}
|
|
|
|
this->addProperty(pi);
|
|
}
|
|
};
|
|
|
|
template<typename T, typename PT1, typename PT2>
|
|
struct StdPairReflector: ValueReflector<T>
|
|
{
|
|
typedef typename ValueReflector<T>::instance_creator_type instance_creator_type;
|
|
|
|
struct Accessor: PropertyGetter, PropertySetter
|
|
{
|
|
Accessor(int i): _i(i) {}
|
|
|
|
virtual Value get(const Value& instance) const
|
|
{
|
|
switch (_i)
|
|
{
|
|
case 0: return getInstance<T>(instance).first;
|
|
case 1: return getInstance<T>(instance).second;
|
|
default: return Value();
|
|
}
|
|
}
|
|
|
|
virtual Value get(Value& instance) const
|
|
{
|
|
switch (_i)
|
|
{
|
|
case 0: return getInstance<T>(instance).first;
|
|
case 1: return getInstance<T>(instance).second;
|
|
default: return Value();
|
|
}
|
|
}
|
|
|
|
virtual void set(Value& instance, const Value& v) const
|
|
{
|
|
T& ctr = getInstance<T>(instance);
|
|
|
|
switch (_i)
|
|
{
|
|
case 0: ctr.first = variant_cast<const typename T::first_type& >(v); break;
|
|
case 1: ctr.second = variant_cast<const typename T::second_type& >(v); break;
|
|
}
|
|
}
|
|
|
|
int _i;
|
|
};
|
|
|
|
StdPairReflector(const std::string& name): ValueReflector<T>(name)
|
|
{
|
|
addConstructor(new TypedConstructorInfo0<T, instance_creator_type>(ParameterInfoList()));
|
|
|
|
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)));
|
|
|
|
this->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)));
|
|
|
|
this->addProperty(pi2);
|
|
}
|
|
};
|
|
|
|
|
|
// TEMPLATE METHODS
|
|
|
|
template<typename T>
|
|
Reflector<T>::Reflector(const std::string& name, const std::string& ns, bool abstract)
|
|
: _type(Reflection::getOrRegisterType(extended_typeid<T>(), true))
|
|
{
|
|
if (!_type->_name.empty())
|
|
_type->_aliases.push_back(ns.empty()? purify(name): purify(ns+"::"+name));
|
|
else
|
|
{
|
|
_type->_name = purify(name);
|
|
_type->_namespace = purify(ns);
|
|
}
|
|
_type->_is_abstract = abstract;
|
|
init();
|
|
}
|
|
|
|
template<typename T>
|
|
Reflector<T>::Reflector(const std::string& qname, bool abstract)
|
|
: _type(Reflection::getOrRegisterType(extended_typeid<T>(), true))
|
|
{
|
|
if (!_type->_name.empty())
|
|
_type->_aliases.push_back(purify(qname));
|
|
else
|
|
{
|
|
split_qualified_name(purify(qname), _type->_name, _type->_namespace);
|
|
}
|
|
_type->_is_abstract = abstract;
|
|
init();
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::init()
|
|
{
|
|
// pointer type
|
|
if (!_type->_pointed_type)
|
|
{
|
|
Type* ptype = Reflection::getOrRegisterType(extended_typeid<T*>(), true);
|
|
ptype->_name = _type->_name;
|
|
ptype->_namespace = _type->_namespace;
|
|
ptype->_pointed_type = _type;
|
|
ptype->_is_defined = true;
|
|
ptype->_cons.push_back(new PtrConstructor(ptype));
|
|
ptype->_rw = new PtrReaderWriter<T*>();
|
|
ptype->_cmp = new TotalOrderComparator<T*>();
|
|
}
|
|
|
|
// const pointer type
|
|
if (!_type->_pointed_type || !_type->_is_const)
|
|
{
|
|
Type* cptype = Reflection::getOrRegisterType(extended_typeid<const T*>(), true);
|
|
cptype->_name = _type->_name;
|
|
cptype->_namespace = _type->_namespace;
|
|
cptype->_is_const = true;
|
|
cptype->_pointed_type = _type;
|
|
cptype->_is_defined = true;
|
|
cptype->_cons.push_back(new ConstPtrConstructor(cptype));
|
|
cptype->_rw = new PtrReaderWriter<const T*>();
|
|
cptype->_cmp = new TotalOrderComparator<const T*>();
|
|
}
|
|
|
|
init_reference_types();
|
|
|
|
_type->_is_defined = true;
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::init_reference_types()
|
|
{
|
|
// reference type
|
|
if (!_type->_referenced_type)
|
|
{
|
|
Type* ptype = Reflection::getOrRegisterType(extended_typeid<T&>(), true);
|
|
ptype->_name = _type->_name;
|
|
ptype->_namespace = _type->_namespace;
|
|
ptype->_referenced_type = _type;
|
|
ptype->_is_defined = true;
|
|
}
|
|
|
|
// const reference type
|
|
if (!_type->_referenced_type || !_type->_is_const)
|
|
{
|
|
Type* cptype = Reflection::getOrRegisterType(extended_typeid<const T&>(), true);
|
|
cptype->_name = _type->_name;
|
|
cptype->_namespace = _type->_namespace;
|
|
cptype->_is_const = true;
|
|
cptype->_referenced_type = _type;
|
|
cptype->_is_defined = true;
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void Reflector<void>::init_reference_types();
|
|
|
|
template<typename T>
|
|
std::string Reflector<T>::purify(const std::string& s)
|
|
{
|
|
std::string r(s);
|
|
while (true)
|
|
{
|
|
std::string::size_type p = r.find(" COMMA ");
|
|
if (p == std::string::npos) break;
|
|
r.replace(p, 7, ", ");
|
|
};
|
|
return r;
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::split_qualified_name(const std::string& q, std::string& n, std::string& ns)
|
|
{
|
|
int templ = 0;
|
|
std::string::size_type split_point = std::string::npos;
|
|
std::string::size_type j = 0;
|
|
for (std::string::const_iterator i=q.begin(); i!=q.end(); ++i, ++j)
|
|
{
|
|
if (*i == '<') ++templ;
|
|
if (*i == '>') --templ;
|
|
if (templ == 0)
|
|
{
|
|
if (*i == ':' && (i+1)!=q.end() && *(i+1) == ':')
|
|
split_point = j;
|
|
}
|
|
}
|
|
if (split_point == std::string::npos)
|
|
{
|
|
ns.clear();
|
|
n = q;
|
|
}
|
|
else
|
|
{
|
|
n = q.substr(split_point+2);
|
|
ns = q.substr(0, split_point);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::addBaseType(const Type& type)
|
|
{
|
|
_type->_base.push_back(&type);
|
|
}
|
|
|
|
template<typename T>
|
|
PropertyInfo* Reflector<T>::addProperty(PropertyInfo* pi)
|
|
{
|
|
_type->_props.push_back(pi);
|
|
return pi;
|
|
}
|
|
|
|
template<typename T>
|
|
MethodInfo* Reflector<T>::addMethod(MethodInfo* mi)
|
|
{
|
|
for (TempMethodList::iterator i=_temp_methods.begin(); i!=_temp_methods.end(); ++i)
|
|
{
|
|
if (mi->overrides(*i))
|
|
return *i;
|
|
}
|
|
|
|
_temp_methods.push_back(mi);
|
|
_type->_methods.push_back(mi);
|
|
return mi;
|
|
}
|
|
|
|
template<typename T>
|
|
MethodInfo* Reflector<T>::addProtectedMethod(MethodInfo* mi)
|
|
{
|
|
for (TempMethodList::iterator i=_temp_protected_methods.begin(); i!=_temp_protected_methods.end(); ++i)
|
|
{
|
|
if (mi->overrides(*i))
|
|
return *i;
|
|
}
|
|
|
|
_temp_protected_methods.push_back(mi);
|
|
_type->_protected_methods.push_back(mi);
|
|
return mi;
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::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<typename T>
|
|
ConstructorInfo* Reflector<T>::addConstructor(ConstructorInfo* ci)
|
|
{
|
|
_type->_cons.push_back(ci);
|
|
return ci;
|
|
}
|
|
|
|
template<typename T>
|
|
ConstructorInfo* Reflector<T>::addProtectedConstructor(ConstructorInfo* ci)
|
|
{
|
|
_type->_protected_cons.push_back(ci);
|
|
return ci;
|
|
}
|
|
|
|
template<typename T>
|
|
std::string Reflector<T>::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<typename T>
|
|
CustomAttributeProvider *Reflector<T>::addAttribute(const CustomAttribute* attrib)
|
|
{
|
|
return _type->addAttribute(attrib);
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::setReaderWriter(const ReaderWriter* rw)
|
|
{
|
|
_type->_rw = rw;
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::setComparator(const Comparator* cmp)
|
|
{
|
|
_type->_cmp = cmp;
|
|
}
|
|
|
|
template<typename T>
|
|
void Reflector<T>::setDeclaringFile(const std::string& file) const
|
|
{
|
|
_type->_declaringFile = file;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|