cppbind: automatic conversion of SGReferenced derived pointers.

This commit is contained in:
Thomas Geymayer
2013-10-26 01:04:16 +02:00
parent d896e71ae9
commit 7cbfa76be4
3 changed files with 52 additions and 13 deletions
+26 -2
View File
@@ -898,10 +898,10 @@ namespace nasal
} // namespace nasal } // namespace nasal
// Needs to be outside any namespace to make ADL work
/** /**
* Convert every shared pointer to a ghost. * Convert every shared pointer to a ghost.
*/ */
// Needs to be outside any namespace to mark ADL work
template<class T> template<class T>
typename boost::enable_if< typename boost::enable_if<
nasal::internal::has_element_type< 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> template<class T>
typename boost::enable_if< typename boost::enable_if<
@@ -929,4 +929,28 @@ from_nasal_helper(naContext c, naRef ref, const T*)
return nasal::Ghost<T>::fromNasal(c, ref); 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_ */ #endif /* SG_NASAL_GHOST_HXX_ */
+25 -10
View File
@@ -69,9 +69,16 @@ struct DoubleDerived2:
BaseVec doSomeBaseWork(const BaseVec& v) { return v; } BaseVec doSomeBaseWork(const BaseVec& v) { return v; }
}; };
class SGReferenceBasedClass:
public SGReferenced
{
};
typedef boost::shared_ptr<Derived> DerivedPtr; typedef boost::shared_ptr<Derived> DerivedPtr;
typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr; typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr;
typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr; typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr;
typedef SGSharedPtr<SGReferenceBasedClass> SGRefBasedPtr;
typedef boost::weak_ptr<Derived> DerivedWeakPtr; typedef boost::weak_ptr<Derived> DerivedWeakPtr;
@@ -198,36 +205,44 @@ int main(int argc, char* argv[])
.method("doIt", &DoubleDerived2::doSomeBaseWork); .method("doIt", &DoubleDerived2::doSomeBaseWork);
Ghost<DerivedWeakPtr>::init("DerivedWeakPtr"); Ghost<DerivedWeakPtr>::init("DerivedWeakPtr");
Ghost<SGRefBasedPtr>::init("SGRefBasedPtr");
VERIFY( Ghost<BasePtr>::isInit() ); VERIFY( Ghost<BasePtr>::isInit() );
nasal::to_nasal(c, DoubleDerived2Ptr()); nasal::to_nasal(c, DoubleDerived2Ptr());
BasePtr d( new Derived ); BasePtr d( new Derived );
naRef derived = Ghost<BasePtr>::create(c, d); naRef derived = to_nasal(c, d);
VERIFY( naIsGhost(derived) ); VERIFY( naIsGhost(derived) );
VERIFY( std::string("DerivedPtr") == naGhost_type(derived)->name ); VERIFY( std::string("DerivedPtr") == naGhost_type(derived)->name );
BasePtr d2( new DoubleDerived ); BasePtr d2( new DoubleDerived );
derived = Ghost<BasePtr>::create(c, d2); derived = to_nasal(c, d2);
VERIFY( naIsGhost(derived) ); VERIFY( naIsGhost(derived) );
VERIFY( std::string("DoubleDerivedPtr") == naGhost_type(derived)->name ); VERIFY( std::string("DoubleDerivedPtr") == naGhost_type(derived)->name );
BasePtr d3( new DoubleDerived2 ); BasePtr d3( new DoubleDerived2 );
derived = Ghost<BasePtr>::create(c, d3); derived = to_nasal(c, d3);
VERIFY( naIsGhost(derived) ); VERIFY( naIsGhost(derived) );
VERIFY( std::string("DoubleDerived2Ptr") == naGhost_type(derived)->name ); 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<BasePtr>::isBaseOf(derived) );
VERIFY( Ghost<DerivedPtr>::isBaseOf(derived) ); VERIFY( Ghost<DerivedPtr>::isBaseOf(derived) );
VERIFY( Ghost<DoubleDerived2Ptr>::isBaseOf(derived) ); VERIFY( Ghost<DoubleDerived2Ptr>::isBaseOf(derived) );
VERIFY( Ghost<BasePtr>::fromNasal(c, derived) == d3 ); VERIFY( from_nasal<BasePtr>(c, derived) == d3 );
VERIFY( Ghost<BasePtr>::fromNasal(c, derived) != d2 ); VERIFY( from_nasal<BasePtr>(c, derived) != d2 );
VERIFY( Ghost<DerivedPtr>::fromNasal(c, derived) VERIFY( from_nasal<DerivedPtr>(c, derived)
== boost::dynamic_pointer_cast<Derived>(d3) ); == boost::dynamic_pointer_cast<Derived>(d3) );
VERIFY( Ghost<DoubleDerived2Ptr>::fromNasal(c, derived) VERIFY( from_nasal<DoubleDerived2Ptr>(c, derived)
== boost::dynamic_pointer_cast<DoubleDerived2>(d3) ); == boost::dynamic_pointer_cast<DoubleDerived2>(d3) );
VERIFY( !Ghost<DoubleDerivedPtr>::fromNasal(c, derived) ); VERIFY( !from_nasal<DoubleDerivedPtr>(c, derived) );
std::map<std::string, BasePtr> instances; std::map<std::string, BasePtr> instances;
VERIFY( naIsHash(to_nasal(c, instances)) ); VERIFY( naIsHash(to_nasal(c, instances)) );
@@ -249,14 +264,14 @@ int main(int argc, char* argv[])
Hash obj(c); Hash obj(c);
obj.set("parents", parents); 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) // Check recursive parents (aka parent-of-parent)
std::vector<naRef> parents2; std::vector<naRef> parents2;
parents2.push_back(obj.get_naRef()); parents2.push_back(obj.get_naRef());
Hash derived_obj(c); Hash derived_obj(c);
derived_obj.set("parents", parents2); 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; std::vector<naRef> nasal_objects;
nasal_objects.push_back( Ghost<BasePtr>::create(c, d) ); nasal_objects.push_back( Ghost<BasePtr>::create(c, d) );
@@ -8,7 +8,7 @@
# define SG_CALL_TRAITS_PARAM(z, n, dummy)\ # define SG_CALL_TRAITS_PARAM(z, n, dummy)\
typename boost::call_traits<A##n>::param_type a##n typename boost::call_traits<A##n>::param_type a##n
# define SG_CALL_ARG(z, n, dummy)\ # 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< template<
class Ret class Ret