cppbind: automatic conversion of SGReferenced derived pointers.

This commit is contained in:
Thomas Geymayer 2013-10-26 00:40:52 +02:00
parent d896e71ae9
commit 7cbfa76be4
3 changed files with 52 additions and 13 deletions

View File

@ -898,10 +898,10 @@ namespace nasal
} // namespace nasal
// Needs to be outside any namespace to make ADL work
/**
* Convert every shared pointer to a ghost.
*/
// Needs to be outside any namespace to mark ADL work
template<class T>
typename boost::enable_if<
nasal::internal::has_element_type<
@ -915,7 +915,7 @@ to_nasal_helper(naContext c, T ptr)
}
/**
* Convert nasal ghosts/hashes to shared pointer (of a ghost)
* Convert nasal ghosts/hashes to shared pointer (of a ghost).
*/
template<class T>
typename boost::enable_if<
@ -929,4 +929,28 @@ from_nasal_helper(naContext c, naRef ref, const T*)
return nasal::Ghost<T>::fromNasal(c, ref);
}
/**
* Convert any pointer to a SGReference based object to a ghost.
*/
template<class T>
typename boost::enable_if<boost::is_base_of<SGReferenced, T>, naRef>::type
to_nasal_helper(naContext c, T* ptr)
{
return nasal::Ghost<SGSharedPtr<T> >::create(c, SGSharedPtr<T>(ptr));
}
/**
* Convert nasal ghosts/hashes to pointer (of a SGReference based ghost).
*/
template<class T>
typename boost::enable_if<
boost::is_base_of<SGReferenced, typename boost::remove_pointer<T>::type>,
T
>::type
from_nasal_helper(naContext c, naRef ref, const T*)
{
typedef SGSharedPtr<typename boost::remove_pointer<T>::type> TypeRef;
return nasal::Ghost<TypeRef>::fromNasal(c, ref).release();
}
#endif /* SG_NASAL_GHOST_HXX_ */

View File

@ -69,9 +69,16 @@ struct DoubleDerived2:
BaseVec doSomeBaseWork(const BaseVec& v) { return v; }
};
class SGReferenceBasedClass:
public SGReferenced
{
};
typedef boost::shared_ptr<Derived> DerivedPtr;
typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr;
typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr;
typedef SGSharedPtr<SGReferenceBasedClass> SGRefBasedPtr;
typedef boost::weak_ptr<Derived> DerivedWeakPtr;
@ -198,36 +205,44 @@ int main(int argc, char* argv[])
.method("doIt", &DoubleDerived2::doSomeBaseWork);
Ghost<DerivedWeakPtr>::init("DerivedWeakPtr");
Ghost<SGRefBasedPtr>::init("SGRefBasedPtr");
VERIFY( Ghost<BasePtr>::isInit() );
nasal::to_nasal(c, DoubleDerived2Ptr());
BasePtr d( new Derived );
naRef derived = Ghost<BasePtr>::create(c, d);
naRef derived = to_nasal(c, d);
VERIFY( naIsGhost(derived) );
VERIFY( std::string("DerivedPtr") == naGhost_type(derived)->name );
BasePtr d2( new DoubleDerived );
derived = Ghost<BasePtr>::create(c, d2);
derived = to_nasal(c, d2);
VERIFY( naIsGhost(derived) );
VERIFY( std::string("DoubleDerivedPtr") == naGhost_type(derived)->name );
BasePtr d3( new DoubleDerived2 );
derived = Ghost<BasePtr>::create(c, d3);
derived = to_nasal(c, d3);
VERIFY( naIsGhost(derived) );
VERIFY( std::string("DoubleDerived2Ptr") == naGhost_type(derived)->name );
SGRefBasedPtr ref_based( new SGReferenceBasedClass );
naRef na_ref_based = to_nasal(c, ref_based.get());
VERIFY( naIsGhost(na_ref_based) );
VERIFY( from_nasal<SGReferenceBasedClass*>(c, na_ref_based)
== ref_based.get() );
VERIFY( from_nasal<SGRefBasedPtr>(c, na_ref_based) == ref_based );
VERIFY( Ghost<BasePtr>::isBaseOf(derived) );
VERIFY( Ghost<DerivedPtr>::isBaseOf(derived) );
VERIFY( Ghost<DoubleDerived2Ptr>::isBaseOf(derived) );
VERIFY( Ghost<BasePtr>::fromNasal(c, derived) == d3 );
VERIFY( Ghost<BasePtr>::fromNasal(c, derived) != d2 );
VERIFY( Ghost<DerivedPtr>::fromNasal(c, derived)
VERIFY( from_nasal<BasePtr>(c, derived) == d3 );
VERIFY( from_nasal<BasePtr>(c, derived) != d2 );
VERIFY( from_nasal<DerivedPtr>(c, derived)
== boost::dynamic_pointer_cast<Derived>(d3) );
VERIFY( Ghost<DoubleDerived2Ptr>::fromNasal(c, derived)
VERIFY( from_nasal<DoubleDerived2Ptr>(c, derived)
== boost::dynamic_pointer_cast<DoubleDerived2>(d3) );
VERIFY( !Ghost<DoubleDerivedPtr>::fromNasal(c, derived) );
VERIFY( !from_nasal<DoubleDerivedPtr>(c, derived) );
std::map<std::string, BasePtr> instances;
VERIFY( naIsHash(to_nasal(c, instances)) );
@ -249,14 +264,14 @@ int main(int argc, char* argv[])
Hash obj(c);
obj.set("parents", parents);
VERIFY( Ghost<BasePtr>::fromNasal(c, obj.get_naRef()) == d3 );
VERIFY( from_nasal<BasePtr>(c, obj.get_naRef()) == d3 );
// Check recursive parents (aka parent-of-parent)
std::vector<naRef> parents2;
parents2.push_back(obj.get_naRef());
Hash derived_obj(c);
derived_obj.set("parents", parents2);
VERIFY( Ghost<BasePtr>::fromNasal(c, derived_obj.get_naRef()) == d3 );
VERIFY( from_nasal<BasePtr>(c, derived_obj.get_naRef()) == d3 );
std::vector<naRef> nasal_objects;
nasal_objects.push_back( Ghost<BasePtr>::create(c, d) );

View File

@ -8,7 +8,7 @@
# define SG_CALL_TRAITS_PARAM(z, n, dummy)\
typename boost::call_traits<A##n>::param_type a##n
# define SG_CALL_ARG(z, n, dummy)\
to_nasal(ctx, a##n)
to_nasal<typename boost::call_traits<A##n>::param_type>(ctx, a##n)
template<
class Ret