+ typedef naGhostType* (*type_checker_t)(const raw_type*);
+ typedef std::vector<type_checker_t> DerivedList;
+ DerivedList _derived_types;
+
+ void addDerived( const internal::GhostMetadata* derived_meta,
+ const type_checker_t& derived_info )
+ {
+ GhostMetadata::addDerived(derived_meta);
+ _derived_types.push_back(derived_info);
+ }
+
+ template<class BaseGhost>
+ static
+ typename boost::enable_if
+ < boost::is_polymorphic<typename BaseGhost::raw_type>,
+ naGhostType*
+ >::type
+ getTypeFor(const typename BaseGhost::raw_type* base)
+ {
+ // Check first if passed pointer can by converted to instance of class
+ // this ghost wraps.
+ if( !boost::is_same
+ < typename BaseGhost::raw_type,
+ typename Ghost::raw_type
+ >::value
+ && dynamic_cast<const typename Ghost::raw_type*>(base) != base )
+ return 0;
+
+ // Now check if we can further downcast to one of our derived classes.
+ for( typename DerivedList::reverse_iterator
+ derived = getSingletonPtr()->_derived_types.rbegin();
+ derived != getSingletonPtr()->_derived_types.rend();
+ ++derived )
+ {
+ naGhostType* ghost_type =
+ (*derived)( static_cast<const typename Ghost::raw_type*>(base) );
+ if( ghost_type )
+ return ghost_type;
+ }
+
+ // If base is not an instance of any derived class, this class has to
+ // be the dynamic type.
+ return &getSingletonPtr()->_ghost_type;
+ }
+
+ template<class BaseGhost>
+ static
+ typename boost::disable_if
+ < boost::is_polymorphic<typename BaseGhost::raw_type>,
+ naGhostType*
+ >::type
+ getTypeFor(const typename BaseGhost::raw_type* base)
+ {
+ // For non polymorphic classes there is no possibility to get the actual
+ // dynamic type, therefore we can only use its static type.
+ return &BaseGhost::getSingletonPtr()->_ghost_type;
+ }
+