cppbind: fix Ghost casting/storage in polymorphic class hierarchies.
This commit is contained in:
parent
f6b16e2ba8
commit
6af8d32078
@ -3,6 +3,7 @@ include (SimGearComponent)
|
||||
set(HEADERS
|
||||
Ghost.hxx
|
||||
NasalCallContext.hxx
|
||||
NasalContext.hxx
|
||||
NasalHash.hxx
|
||||
NasalObject.hxx
|
||||
NasalObjectHolder.hxx
|
||||
@ -21,6 +22,7 @@ set(DETAIL_HEADERS
|
||||
|
||||
set(SOURCES
|
||||
Ghost.cxx
|
||||
NasalContext.cxx
|
||||
NasalHash.cxx
|
||||
NasalString.cxx
|
||||
NasalObject.cxx
|
||||
|
@ -33,7 +33,7 @@ namespace nasal
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool GhostMetadata::isBaseOf(naGhostType* ghost_type, bool& is_weak) const
|
||||
bool GhostMetadata::isInstance(naGhostType* ghost_type, bool& is_weak) const
|
||||
{
|
||||
if( ghost_type == _ghost_type_strong_ptr )
|
||||
{
|
||||
@ -47,14 +47,6 @@ namespace nasal
|
||||
return true;
|
||||
}
|
||||
|
||||
for( DerivedList::const_iterator derived = _derived_classes.begin();
|
||||
derived != _derived_classes.end();
|
||||
++derived )
|
||||
{
|
||||
if( (*derived)->isBaseOf(ghost_type, is_weak) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -74,7 +66,6 @@ namespace nasal
|
||||
void GhostMetadata::addDerived(const GhostMetadata* derived)
|
||||
{
|
||||
assert(derived);
|
||||
_derived_classes.push_back(derived);
|
||||
|
||||
SG_LOG
|
||||
(
|
||||
|
@ -107,17 +107,14 @@ namespace nasal
|
||||
*/
|
||||
void addNasalBase(const naRef& parent);
|
||||
|
||||
bool isBaseOf(naGhostType* ghost_type, bool& is_weak) const;
|
||||
bool isInstance(naGhostType* ghost_type, bool& is_weak) const;
|
||||
|
||||
protected:
|
||||
|
||||
typedef std::vector<const GhostMetadata*> DerivedList;
|
||||
|
||||
const std::string _name_strong,
|
||||
_name_weak;
|
||||
const naGhostType *_ghost_type_strong_ptr,
|
||||
*_ghost_type_weak_ptr;
|
||||
DerivedList _derived_classes;
|
||||
std::vector<naRef> _parents;
|
||||
|
||||
GhostMetadata( const std::string& name,
|
||||
@ -307,7 +304,7 @@ namespace nasal
|
||||
|
||||
// Keep reference for duration of call to prevent expiring
|
||||
// TODO not needed for strong referenced ghost
|
||||
strong_ref ref = fromNasal<strong_ref>(c, me);
|
||||
strong_ref ref = fromNasal(c, me);
|
||||
if( !ref )
|
||||
{
|
||||
naGhostType* ghost_type = naGhost_type(me);
|
||||
@ -416,10 +413,13 @@ namespace nasal
|
||||
boost::is_base_of<typename BaseGhost::raw_type, raw_type>::value
|
||||
));
|
||||
|
||||
typedef typename BaseGhost::strong_ref base_ref;
|
||||
|
||||
BaseGhost* base = BaseGhost::getSingletonPtr();
|
||||
base->addDerived(
|
||||
this,
|
||||
SG_GET_TEMPLATE_MEMBER(Ghost, getTypeFor<BaseGhost>)
|
||||
SG_GET_TEMPLATE_MEMBER(Ghost, toNasal<BaseGhost>),
|
||||
SG_GET_TEMPLATE_MEMBER(Ghost, fromNasalWithCast<base_ref>)
|
||||
);
|
||||
|
||||
// Replace any getter that is not available in the current class.
|
||||
@ -809,7 +809,7 @@ namespace nasal
|
||||
makeGhost(naContext c, RefType const& ref_ptr)
|
||||
{
|
||||
strong_ref ref(ref_ptr);
|
||||
raw_type* ptr = get_pointer(ref_ptr);
|
||||
raw_type* ptr = get_pointer(ref);
|
||||
if( !ptr )
|
||||
return naNil();
|
||||
|
||||
@ -817,15 +817,11 @@ namespace nasal
|
||||
// will then be hold be a new shared pointer. We therefore have to
|
||||
// check for the dynamic type of the object as it might differ from
|
||||
// the passed static type.
|
||||
naGhostType* ghost_type =
|
||||
getTypeFor<Ghost>(ptr, shared_ptr_traits<RefType>::is_strong::value);
|
||||
|
||||
if( !ghost_type )
|
||||
return naNil();
|
||||
|
||||
return naNewGhost2( c,
|
||||
ghost_type,
|
||||
shared_ptr_storage<RefType>::ref(ref_ptr) );
|
||||
return toNasal<Ghost>(
|
||||
c,
|
||||
ref,
|
||||
shared_ptr_traits<RefType>::is_strong::value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -833,25 +829,36 @@ namespace nasal
|
||||
* Nasal objects has to be derived class of the target class (Either
|
||||
* derived in C++ or in Nasal using a 'parents' vector)
|
||||
*/
|
||||
template<class Type>
|
||||
static Type fromNasal(naContext c, naRef me)
|
||||
static strong_ref fromNasal(naContext c, naRef me)
|
||||
{
|
||||
bool is_weak = false;
|
||||
|
||||
// Check if it's a ghost and if it can be converted
|
||||
if( isBaseOf(naGhost_type(me), is_weak) )
|
||||
naGhostType* ghost_type = naGhost_type(me);
|
||||
if( ghost_type )
|
||||
{
|
||||
void* ghost = naGhost_ptr(me);
|
||||
return is_weak ? getPtr<Type, true>(ghost)
|
||||
: getPtr<Type, false>(ghost);
|
||||
}
|
||||
// Check if we got an instance of this class
|
||||
bool is_weak = false;
|
||||
if( isInstance(ghost_type, is_weak) )
|
||||
{
|
||||
return is_weak ? getPtr<strong_ref, true>(naGhost_ptr(me))
|
||||
: getPtr<strong_ref, false>(naGhost_ptr(me));
|
||||
}
|
||||
|
||||
// Now if it is derived from a ghost (hash with ghost in parent vector)
|
||||
// otherwise try the derived classes
|
||||
for( typename DerivedList::reverse_iterator
|
||||
derived = getSingletonPtr()->_derived_types.rbegin();
|
||||
derived != getSingletonPtr()->_derived_types.rend();
|
||||
++derived )
|
||||
{
|
||||
strong_ref ref = (derived->from_nasal)(c, me);
|
||||
|
||||
if( get_pointer(ref) )
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
else if( naIsHash(me) )
|
||||
{
|
||||
naRef na_parents = naHash_cget(me, const_cast<char*>("parents"));
|
||||
if( !naIsVector(na_parents) )
|
||||
return Type();
|
||||
return strong_ref();
|
||||
|
||||
typedef std::vector<naRef> naRefs;
|
||||
naRefs parents = from_nasal<naRefs>(c, na_parents);
|
||||
@ -859,19 +866,13 @@ namespace nasal
|
||||
parent != parents.end();
|
||||
++parent )
|
||||
{
|
||||
Type ptr = fromNasal<Type>(c, *parent);
|
||||
if( get_pointer(ptr) )
|
||||
return ptr;
|
||||
strong_ref ref = fromNasal(c, *parent);
|
||||
if( get_pointer(ref) )
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
return Type();
|
||||
}
|
||||
|
||||
static bool isBaseOf(naRef obj)
|
||||
{
|
||||
bool is_weak;
|
||||
return isBaseOf(naGhost_type(obj), is_weak);
|
||||
return strong_ref();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -882,21 +883,30 @@ namespace nasal
|
||||
static naGhostType _ghost_type_strong, //!< Stored as shared pointer
|
||||
_ghost_type_weak; //!< Stored as weak shared pointer
|
||||
|
||||
typedef naGhostType* (*type_checker_t)(const raw_type*, bool);
|
||||
typedef std::vector<type_checker_t> DerivedList;
|
||||
typedef naRef (*to_nasal_t)(naContext, const strong_ref&, bool);
|
||||
typedef strong_ref (*from_nasal_t)(naContext, naRef);
|
||||
struct DerivedInfo
|
||||
{
|
||||
to_nasal_t to_nasal;
|
||||
from_nasal_t from_nasal;
|
||||
|
||||
DerivedInfo( to_nasal_t to_nasal_func,
|
||||
from_nasal_t from_nasal_func ):
|
||||
to_nasal(to_nasal_func),
|
||||
from_nasal(from_nasal_func)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef std::vector<DerivedInfo> DerivedList;
|
||||
DerivedList _derived_types;
|
||||
|
||||
static bool isBaseOf(naGhostType* ghost_type, bool& is_weak)
|
||||
static bool isInstance(naGhostType* ghost_type, bool& is_weak)
|
||||
{
|
||||
if( !ghost_type || !getSingletonPtr() )
|
||||
return false;
|
||||
|
||||
return getSingletonPtr()->GhostMetadata::isBaseOf(ghost_type, is_weak);
|
||||
}
|
||||
|
||||
static bool isBaseOf(naRef obj, bool& is_weak)
|
||||
{
|
||||
return isBaseOf(naGhost_type(obj), is_weak);
|
||||
return getSingletonPtr()->GhostMetadata::isInstance( ghost_type,
|
||||
is_weak );
|
||||
}
|
||||
|
||||
template<class RefPtr, bool is_weak>
|
||||
@ -945,28 +955,33 @@ namespace nasal
|
||||
}
|
||||
|
||||
void addDerived( const internal::GhostMetadata* derived_meta,
|
||||
type_checker_t derived_type_checker )
|
||||
to_nasal_t to_nasal_func,
|
||||
from_nasal_t from_nasal_func )
|
||||
{
|
||||
GhostMetadata::addDerived(derived_meta);
|
||||
_derived_types.push_back(derived_type_checker);
|
||||
_derived_types.push_back(DerivedInfo(to_nasal_func, from_nasal_func));
|
||||
}
|
||||
|
||||
template<class BaseGhost>
|
||||
static
|
||||
typename boost::enable_if
|
||||
< boost::is_polymorphic<typename BaseGhost::raw_type>,
|
||||
naGhostType*
|
||||
naRef
|
||||
>::type
|
||||
getTypeFor(const typename BaseGhost::raw_type* base, bool strong)
|
||||
toNasal( naContext c,
|
||||
const typename BaseGhost::strong_ref& base_ref,
|
||||
bool strong )
|
||||
{
|
||||
typename BaseGhost::raw_type* ptr = get_pointer(base_ref);
|
||||
|
||||
// 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;
|
||||
&& dynamic_cast<const typename Ghost::raw_type*>(ptr) != ptr )
|
||||
return naNil();
|
||||
|
||||
if( !getSingletonPtr() )
|
||||
{
|
||||
@ -976,45 +991,52 @@ namespace nasal
|
||||
SG_INFO,
|
||||
"Ghost::getTypeFor: can not get type for unregistered ghost"
|
||||
);
|
||||
return 0;
|
||||
return naNil();
|
||||
}
|
||||
|
||||
strong_ref ref =
|
||||
static_pointer_cast<typename Ghost::raw_type>(base_ref);
|
||||
|
||||
// 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),
|
||||
strong
|
||||
);
|
||||
naRef ghost = (derived->to_nasal)(c, ref, strong);
|
||||
|
||||
if( ghost_type )
|
||||
return ghost_type;
|
||||
if( !naIsNil(ghost) )
|
||||
return ghost;
|
||||
}
|
||||
|
||||
// If base is not an instance of any derived class, this class has to
|
||||
// be the dynamic type.
|
||||
return strong
|
||||
? &_ghost_type_strong
|
||||
: &_ghost_type_weak;
|
||||
? create<false>(c, ref)
|
||||
: create<true>(c, ref);
|
||||
}
|
||||
|
||||
template<class BaseGhost>
|
||||
static
|
||||
typename boost::disable_if
|
||||
< boost::is_polymorphic<typename BaseGhost::raw_type>,
|
||||
naGhostType*
|
||||
naRef
|
||||
>::type
|
||||
getTypeFor(const typename BaseGhost::raw_type* base, bool strong)
|
||||
toNasal( naContext c,
|
||||
const typename BaseGhost::strong_ref& ref,
|
||||
bool strong )
|
||||
{
|
||||
// For non polymorphic classes there is no possibility to get the actual
|
||||
// dynamic type, therefore we can only use its static type.
|
||||
return strong
|
||||
? &BaseGhost::_ghost_type_strong
|
||||
: &BaseGhost::_ghost_type_weak;
|
||||
? create<false>(c, ref)
|
||||
: create<true>(c, ref);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
static Type fromNasalWithCast(naContext c, naRef me)
|
||||
{
|
||||
return Type(fromNasal(c, me));
|
||||
}
|
||||
|
||||
static Ghost* getSingletonPtr()
|
||||
@ -1176,6 +1198,45 @@ namespace nasal
|
||||
return instance;
|
||||
}
|
||||
|
||||
template<bool is_weak>
|
||||
static
|
||||
typename boost::enable_if_c<
|
||||
!is_weak,
|
||||
naRef
|
||||
>::type
|
||||
create(naContext c, const strong_ref& ref_ptr)
|
||||
{
|
||||
typedef shared_ptr_storage<strong_ref> storage_type;
|
||||
return naNewGhost2( c,
|
||||
&Ghost::_ghost_type_strong,
|
||||
storage_type::ref(ref_ptr) );
|
||||
}
|
||||
|
||||
template<bool is_weak>
|
||||
static
|
||||
typename boost::enable_if_c<
|
||||
is_weak && supports_weak_ref<T>::value,
|
||||
naRef
|
||||
>::type
|
||||
create(naContext c, const strong_ref& ref_ptr)
|
||||
{
|
||||
typedef shared_ptr_storage<weak_ref> storage_type;
|
||||
return naNewGhost2( c,
|
||||
&Ghost::_ghost_type_weak,
|
||||
storage_type::ref(ref_ptr) );
|
||||
}
|
||||
|
||||
template<bool is_weak>
|
||||
static
|
||||
typename boost::enable_if_c<
|
||||
is_weak && !supports_weak_ref<T>::value,
|
||||
naRef
|
||||
>::type
|
||||
create(naContext, const strong_ref&)
|
||||
{
|
||||
return naNil();
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
static void destroy(void *ptr)
|
||||
{
|
||||
@ -1354,7 +1415,7 @@ typename boost::enable_if<
|
||||
from_nasal_helper(naContext c, naRef ref, const T*)
|
||||
{
|
||||
typedef typename nasal::shared_ptr_traits<T>::strong_ref strong_ref;
|
||||
return nasal::Ghost<strong_ref>::template fromNasal<T>(c, ref);
|
||||
return T(nasal::Ghost<strong_ref>::fromNasal(c, ref));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1389,7 +1450,7 @@ typename boost::enable_if_c<
|
||||
from_nasal_helper(naContext c, naRef ref, const T*)
|
||||
{
|
||||
typedef SGSharedPtr<typename boost::remove_pointer<T>::type> TypeRef;
|
||||
return nasal::Ghost<TypeRef>::template fromNasal<T>(c, ref);
|
||||
return T(nasal::Ghost<TypeRef>::fromNasal(c, ref));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1416,7 +1477,7 @@ typename boost::enable_if<
|
||||
from_nasal_helper(naContext c, naRef ref, const T*)
|
||||
{
|
||||
typedef osg::ref_ptr<typename boost::remove_pointer<T>::type> TypeRef;
|
||||
return nasal::Ghost<TypeRef>::template fromNasal<T>(c, ref);
|
||||
return T(nasal::Ghost<TypeRef>::fromNasal(c, ref));
|
||||
}
|
||||
|
||||
#endif /* SG_NASAL_GHOST_HXX_ */
|
||||
|
49
simgear/nasal/cppbind/NasalContext.cxx
Normal file
49
simgear/nasal/cppbind/NasalContext.cxx
Normal file
@ -0,0 +1,49 @@
|
||||
// Manage lifetime and encapsulate a Nasal context
|
||||
//
|
||||
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// 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 GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#include "NasalContext.hxx"
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Context::Context():
|
||||
_ctx(naNewContext())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Context::~Context()
|
||||
{
|
||||
naFreeContext(_ctx);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Context::operator naContext()
|
||||
{
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Hash Context::newHash()
|
||||
{
|
||||
return Hash(_ctx);
|
||||
}
|
||||
|
||||
} // namespace nasal
|
43
simgear/nasal/cppbind/NasalContext.hxx
Normal file
43
simgear/nasal/cppbind/NasalContext.hxx
Normal file
@ -0,0 +1,43 @@
|
||||
///@file Manage lifetime and encapsulate a Nasal context
|
||||
//
|
||||
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// 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 GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#ifndef SG_NASAL_CONTEXT_HXX_
|
||||
#define SG_NASAL_CONTEXT_HXX_
|
||||
|
||||
#include "NasalHash.hxx"
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context();
|
||||
~Context();
|
||||
|
||||
operator naContext();
|
||||
|
||||
Hash newHash();
|
||||
|
||||
protected:
|
||||
naContext _ctx;
|
||||
};
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#endif /* SG_NASAL_CONTEXT_HXX_ */
|
@ -322,10 +322,6 @@ int main(int argc, char* argv[])
|
||||
== 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( from_nasal<BasePtr>(c, derived) == d3 );
|
||||
VERIFY( from_nasal<BasePtr>(c, derived) != d2 );
|
||||
VERIFY( from_nasal<DerivedPtr>(c, derived)
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <BoostTestTargetConfig.h>
|
||||
|
||||
#include "Ghost.hxx"
|
||||
#include "NasalContext.hxx"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
@ -49,14 +51,19 @@ BOOST_STATIC_ASSERT(( nasal::supports_weak_ref<DerivedPtr>::value));
|
||||
BOOST_STATIC_ASSERT(( nasal::supports_weak_ref<DerivedWeakPtr>::value));
|
||||
BOOST_STATIC_ASSERT((!nasal::supports_weak_ref<SGReferencedPtr>::value));
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ghost_weak_strong_nasal_conversion )
|
||||
static void setupGhosts()
|
||||
{
|
||||
nasal::Ghost<Base1Ptr>::init("Base1");
|
||||
nasal::Ghost<Base2Ptr>::init("Base2");
|
||||
nasal::Ghost<DerivedPtr>::init("Derived")
|
||||
.bases<Base1Ptr>()
|
||||
.bases<Base2Ptr>();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOST_AUTO_TEST_CASE( ghost_weak_strong_nasal_conversion )
|
||||
{
|
||||
setupGhosts();
|
||||
naContext c = naNewContext();
|
||||
|
||||
DerivedPtr d = new Derived();
|
||||
@ -91,6 +98,45 @@ BOOST_AUTO_TEST_CASE( ghost_weak_strong_nasal_conversion )
|
||||
BOOST_REQUIRE( !weak.lock() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOST_AUTO_TEST_CASE( ghost_casting_storage )
|
||||
{
|
||||
setupGhosts();
|
||||
nasal::Context c;
|
||||
|
||||
// Check converting to and from every class in the hierarchy for an instance
|
||||
// of the leaf class
|
||||
DerivedPtr d = new Derived();
|
||||
|
||||
naRef na_d = nasal::to_nasal(c, d),
|
||||
na_b1 = nasal::to_nasal(c, Base1Ptr(d)),
|
||||
na_b2 = nasal::to_nasal(c, Base2Ptr(d));
|
||||
|
||||
Derived *d0 = nasal::from_nasal<Derived*>(c, na_d),
|
||||
*d1 = nasal::from_nasal<Derived*>(c, na_b1),
|
||||
*d2 = nasal::from_nasal<Derived*>(c, na_b2);
|
||||
|
||||
BOOST_CHECK_EQUAL(d0, d.get());
|
||||
BOOST_CHECK_EQUAL(d1, d.get());
|
||||
BOOST_CHECK_EQUAL(d2, d.get());
|
||||
|
||||
Base1 *b1 = nasal::from_nasal<Base1*>(c, na_b1);
|
||||
BOOST_CHECK_EQUAL(b1, static_cast<Base1*>(d.get()));
|
||||
|
||||
Base2 *b2 = nasal::from_nasal<Base2*>(c, na_b2);
|
||||
BOOST_CHECK_EQUAL(b2, static_cast<Base2*>(d.get()));
|
||||
|
||||
// Check converting from base class instance to derived classes is not
|
||||
// possible
|
||||
Base1Ptr b1_ref = new Base1();
|
||||
na_b1 = nasal::to_nasal(c, b1_ref);
|
||||
|
||||
BOOST_CHECK_EQUAL(nasal::from_nasal<Base1*>(c, na_b1), b1_ref.get());
|
||||
BOOST_CHECK(!nasal::from_nasal<Base2*>(c, na_b1));
|
||||
BOOST_CHECK(!nasal::from_nasal<Derived*>(c, na_b1));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#define CHECK_PTR_STORAGE_TRAIT_TYPE(ptr_t, storage)\
|
||||
BOOST_STATIC_ASSERT((boost::is_same<\
|
||||
nasal::shared_ptr_storage<ptr_t>::storage_type,\
|
||||
|
Loading…
Reference in New Issue
Block a user