| // This tests intrusive_ptr is working okay. It also checks that there are no memory leaks in the |
| // class that intrusive_ptr is pointing via a counting mechanism in the constructors and destructor of Klass. |
| // In order to test that there are no leaks of the intrusive_ptr class itself (as it is created on the heap) |
| // the runtime tests can be run for a long time to monitor memory leaks using memory monitor tools |
| // like 'top'. There is a wrapper for intrusive_ptr in intrusive_ptr_wrapper.h which enables one to |
| // count the instances of intrusive_ptr. Uncomment the INTRUSIVE_PTR_WRAPPER macro to turn this on. |
| // |
| // Also note the debug_shared flag which can be set from the target language. |
| // |
| // Usage of intrusive_ptr_add_ref and intrusive_ptr_release based on boost testing: |
| // http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/test/intrusive_ptr_test.cpp |
| |
| %module li_boost_intrusive_ptr |
| |
| %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK); |
| %warnfilter(SWIGWARN_LANG_SMARTPTR_MISSING) KlassDerived; |
| %warnfilter(SWIGWARN_LANG_SMARTPTR_MISSING) KlassDerivedDerived; |
| |
| %ignore intrusive_ptr_add_ref; |
| %ignore intrusive_ptr_release; |
| |
| %{ |
| #include <boost/shared_ptr.hpp> |
| #include <boost/intrusive_ptr.hpp> |
| #include <boost/detail/atomic_count.hpp> |
| |
| // Uncomment macro below to turn on intrusive_ptr memory leak checking as described above |
| //#define INTRUSIVE_PTR_WRAPPER |
| |
| #ifdef INTRUSIVE_PTR_WRAPPER |
| # include "intrusive_ptr_wrapper.h" |
| # include "shared_ptr_wrapper.h" |
| #endif |
| %} |
| |
| %{ |
| #ifndef INTRUSIVE_PTR_WRAPPER |
| # define SwigBoost boost |
| #endif |
| %} |
| |
| %include "std_string.i" |
| #ifndef INTRUSIVE_PTR_WRAPPER |
| # define SWIG_INTRUSIVE_PTR_NAMESPACE SwigBoost |
| # define SWIG_SHARED_PTR_NAMESPACE SwigBoost |
| #endif |
| |
| #if defined(SWIGJAVA) || defined(SWIGCSHARP) |
| #define INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED |
| #endif |
| |
| #if defined(INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED) |
| |
| %include <boost_intrusive_ptr.i> |
| %intrusive_ptr(Space::Klass) |
| %intrusive_ptr_no_wrap(Space::KlassWithoutRefCount) |
| %intrusive_ptr(Space::KlassDerived) |
| %intrusive_ptr(Space::KlassDerivedDerived) |
| |
| //For the use_count shared_ptr functions |
| #if defined(SWIGJAVA) |
| %typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & ($*1_ltype tempnull) %{ |
| $1 = $input ? *($&1_ltype)&$input : &tempnull; |
| %} |
| %typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "jlong" |
| %typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "long" |
| %typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "Klass" |
| %typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & "Klass.getCPtr($javainput)" |
| |
| %typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & ($*1_ltype tempnull) %{ |
| $1 = $input ? *($&1_ltype)&$input : &tempnull; |
| %} |
| %typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "jlong" |
| %typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "long" |
| %typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "KlassDerived" |
| %typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerived > & "KlassDerived.getCPtr($javainput)" |
| |
| %typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & ($*1_ltype tempnull) %{ |
| $1 = $input ? *($&1_ltype)&$input : &tempnull; |
| %} |
| %typemap (jni) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "jlong" |
| %typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "long" |
| %typemap (jstype) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "KlassDerivedDerived" |
| %typemap(javain) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::KlassDerivedDerived > & "KlassDerivedDerived.getCPtr($javainput)" |
| |
| #elif defined(SWIGCSHARP) |
| // TODO! |
| #endif |
| |
| #endif |
| |
| // TODO: |
| // const intrusive_ptr |
| // std::vector |
| // Add in generic %extend for the Upcast function for derived classes |
| // Remove proxy upcast method - implement %feature("shadow") ??? which replaces the proxy method |
| |
| %exception { |
| if (debug_shared) { |
| cout << "++++++" << endl << flush; |
| cout << "calling $name" << endl << flush; |
| } |
| $action |
| if (debug_shared) { |
| cout << "------" << endl << flush; |
| } |
| } |
| |
| %ignore IgnoredRefCountingBase; |
| %ignore *::operator=; |
| %newobject pointerownertest(); |
| %newobject smartpointerpointerownertest(); |
| |
| %inline %{ |
| #include <iostream> |
| using namespace std; |
| |
| static bool debug_shared = false; |
| |
| namespace Space { |
| |
| struct Klass { |
| Klass() : value("EMPTY"), count(0) { if (debug_shared) cout << "Klass() [" << value << "]" << endl << flush; increment(); } |
| |
| Klass(const std::string &val) : value(val), count(0) { if (debug_shared) cout << "Klass(string) [" << value << "]" << endl << flush; increment(); } |
| |
| virtual ~Klass() { if (debug_shared) cout << "~Klass() [" << value << "]" << endl << flush; decrement(); } |
| virtual std::string getValue() const { return value; } |
| void append(const std::string &s) { value += s; } |
| Klass(const Klass &other) : value(other.value), count(0) { if (debug_shared) cout << "Klass(const Klass&) [" << value << "]" << endl << flush; increment(); } |
| |
| Klass &operator=(const Klass &other) { value = other.value; return *this; } |
| |
| void addref(void) const { ++count; } |
| void release(void) const { if (--count == 0) delete this; } |
| int use_count(void) const { return count; } |
| static long getTotal_count() { return total_count; } |
| friend void intrusive_ptr_add_ref(const Klass* r) { r->addref(); } |
| friend void intrusive_ptr_release(const Klass* r) { r->release(); } |
| |
| private: |
| static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx Klass::increment tot: " << total_count << endl;} |
| static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx Klass::decrement tot: " << total_count << endl;} |
| static boost::detail::atomic_count total_count; |
| std::string value; |
| int array[1024]; |
| mutable boost::detail::atomic_count count; |
| }; |
| |
| struct KlassWithoutRefCount { |
| KlassWithoutRefCount() : value("EMPTY") { if (debug_shared) cout << "KlassWithoutRefCount() [" << value << "]" << endl << flush; increment(); } |
| |
| KlassWithoutRefCount(const std::string &val) : value(val) { if (debug_shared) cout << "KlassWithoutRefCount(string) [" << value << "]" << endl << flush; increment(); } |
| |
| virtual ~KlassWithoutRefCount() { if (debug_shared) cout << "~KlassWithoutRefCount() [" << value << "]" << endl << flush; decrement(); } |
| virtual std::string getValue() const { return value; } |
| void append(const std::string &s) { value += s; } |
| KlassWithoutRefCount(const KlassWithoutRefCount &other) : value(other.value) { if (debug_shared) cout << "KlassWithoutRefCount(const KlassWithoutRefCount&) [" << value << "]" << endl << flush; increment(); } |
| std::string getSpecialValueFromUnwrappableClass() { return "this class cannot be wrapped by intrusive_ptrs but we can still use it"; } |
| KlassWithoutRefCount &operator=(const KlassWithoutRefCount &other) { value = other.value; return *this; } |
| static long getTotal_count() { return total_count; } |
| |
| private: |
| static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassWithoutRefCount::increment tot: " << total_count << endl;} |
| static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassWithoutRefCount::decrement tot: " << total_count << endl;} |
| static boost::detail::atomic_count total_count; |
| std::string value; |
| int array[1024]; |
| }; |
| |
| struct IgnoredRefCountingBase { |
| IgnoredRefCountingBase() : count(0) { if (debug_shared) cout << "IgnoredRefCountingBase()" << endl << flush; increment(); } |
| |
| IgnoredRefCountingBase(const IgnoredRefCountingBase &other) : count(0) { if (debug_shared) cout << "IgnoredRefCountingBase(const IgnoredRefCountingBase&)" << endl << flush; increment(); } |
| |
| IgnoredRefCountingBase &operator=(const IgnoredRefCountingBase& other) { |
| return *this; |
| } |
| |
| virtual ~IgnoredRefCountingBase() { if (debug_shared) cout << "~IgnoredRefCountingBase()" << endl << flush; decrement(); } |
| |
| void addref(void) const { ++count; } |
| void release(void) const { if (--count == 0) delete this; } |
| int use_count(void) const { return count; } |
| inline friend void intrusive_ptr_add_ref(const IgnoredRefCountingBase* r) { r->addref(); } |
| inline friend void intrusive_ptr_release(const IgnoredRefCountingBase* r) { r->release(); } |
| static long getTotal_count() { return total_count; } |
| |
| private: |
| static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx IgnoredRefCountingBase::increment tot: " << total_count << endl;} |
| static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx IgnoredRefCountingBase::decrement tot: " << total_count << endl;} |
| static boost::detail::atomic_count total_count; |
| double d; |
| double e; |
| mutable boost::detail::atomic_count count; |
| }; |
| |
| long getTotal_IgnoredRefCountingBase_count() { |
| return IgnoredRefCountingBase::getTotal_count(); |
| } |
| |
| // For most compilers, this use of multiple inheritance results in different derived and base class |
| // pointer values ... for some more challenging tests :) |
| struct KlassDerived : IgnoredRefCountingBase, KlassWithoutRefCount { |
| KlassDerived() : KlassWithoutRefCount() { if (debug_shared) cout << "KlassDerived()" << endl << flush; increment(); } |
| KlassDerived(const std::string &val) : KlassWithoutRefCount(val) { if (debug_shared) cout << "KlassDerived(string) [" << val << "]" << endl << flush; increment(); } |
| KlassDerived(const KlassDerived &other) : KlassWithoutRefCount(other) { if (debug_shared) cout << "KlassDerived(const KlassDerived&))" << endl << flush; increment(); } |
| virtual ~KlassDerived() { if (debug_shared) cout << "~KlassDerived()" << endl << flush; decrement(); } |
| virtual std::string getValue() const { return KlassWithoutRefCount::getValue() + "-Derived"; } |
| int use_count(void) const { return IgnoredRefCountingBase::use_count(); } |
| static long getTotal_count() { return total_count; } |
| |
| private: |
| static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassDerived::increment tot: " << total_count << endl;} |
| static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassDerived::decrement tot: " << total_count << endl;} |
| static boost::detail::atomic_count total_count; |
| }; |
| struct KlassDerivedDerived : KlassDerived { |
| KlassDerivedDerived() : KlassDerived() { if (debug_shared) cout << "KlassDerivedDerived()" << endl << flush; increment(); } |
| KlassDerivedDerived(const std::string &val) : KlassDerived(val) { if (debug_shared) cout << "KlassDerivedDerived(string) [" << val << "]" << endl << flush; increment(); } |
| KlassDerivedDerived(const KlassDerived &other) : KlassDerived(other) { if (debug_shared) cout << "KlassDerivedDerived(const KlassDerivedDerived&))" << endl << flush; increment(); } |
| virtual ~KlassDerivedDerived() { if (debug_shared) cout << "~KlassDerivedDerived()" << endl << flush; decrement(); } |
| virtual std::string getValue() const { return KlassWithoutRefCount::getValue() + "-DerivedDerived"; } |
| static long getTotal_count() { return total_count; } |
| |
| private: |
| static void increment() { ++total_count; if (debug_shared) cout << " ++xxxxx KlassDerivedDerived::increment tot: " << total_count << endl;} |
| static void decrement() { --total_count; if (debug_shared) cout << " --xxxxx KlassDerivedDerived::decrement tot: " << total_count << endl;} |
| static boost::detail::atomic_count total_count; |
| }; |
| KlassDerived* derivedpointertest(KlassDerived* kd) { |
| if (kd) |
| kd->append(" derivedpointertest"); |
| return kd; |
| } |
| KlassDerived derivedvaluetest(KlassDerived kd) { |
| kd.append(" derivedvaluetest"); |
| return kd; |
| } |
| KlassDerived& derivedreftest(KlassDerived& kd) { |
| kd.append(" derivedreftest"); |
| return kd; |
| } |
| SwigBoost::intrusive_ptr<KlassDerived> derivedsmartptrtest(SwigBoost::intrusive_ptr<KlassDerived> kd) { |
| if (kd) |
| kd->append(" derivedsmartptrtest"); |
| return kd; |
| } |
| SwigBoost::intrusive_ptr<KlassDerived>* derivedsmartptrpointertest(SwigBoost::intrusive_ptr<KlassDerived>* kd) { |
| if (kd && *kd) |
| (*kd)->append(" derivedsmartptrpointertest"); |
| return kd; |
| } |
| SwigBoost::intrusive_ptr<KlassDerived>* derivedsmartptrreftest(SwigBoost::intrusive_ptr<KlassDerived>* kd) { |
| if (kd && *kd) |
| (*kd)->append(" derivedsmartptrreftest"); |
| return kd; |
| } |
| SwigBoost::intrusive_ptr<KlassDerived>*& derivedsmartptrpointerreftest(SwigBoost::intrusive_ptr<KlassDerived>*& kd) { |
| if (kd && *kd) |
| (*kd)->append(" derivedsmartptrpointerreftest"); |
| return kd; |
| } |
| |
| SwigBoost::intrusive_ptr<Klass> factorycreate() { |
| return SwigBoost::intrusive_ptr<Klass>(new Klass("factorycreate")); |
| } |
| // smart pointer |
| SwigBoost::intrusive_ptr<Klass> smartpointertest(SwigBoost::intrusive_ptr<Klass> k) { |
| if (k) |
| k->append(" smartpointertest"); |
| return SwigBoost::intrusive_ptr<Klass>(k); |
| } |
| SwigBoost::intrusive_ptr<Klass>* smartpointerpointertest(SwigBoost::intrusive_ptr<Klass>* k) { |
| if (k && *k) |
| (*k)->append(" smartpointerpointertest"); |
| return k; |
| } |
| SwigBoost::intrusive_ptr<Klass>& smartpointerreftest(SwigBoost::intrusive_ptr<Klass>& k) { |
| if (k) |
| k->append(" smartpointerreftest"); |
| return k; |
| } |
| SwigBoost::intrusive_ptr<Klass>*& smartpointerpointerreftest(SwigBoost::intrusive_ptr<Klass>*& k) { |
| if (k && *k) |
| (*k)->append(" smartpointerpointerreftest"); |
| return k; |
| } |
| // const |
| SwigBoost::intrusive_ptr<const Klass> constsmartpointertest(SwigBoost::intrusive_ptr<const Klass> k) { |
| return SwigBoost::intrusive_ptr<const Klass>(k); |
| } |
| SwigBoost::intrusive_ptr<const Klass>* constsmartpointerpointertest(SwigBoost::intrusive_ptr<const Klass>* k) { |
| return k; |
| } |
| SwigBoost::intrusive_ptr<const Klass>& constsmartpointerreftest(SwigBoost::intrusive_ptr<const Klass>& k) { |
| return k; |
| } |
| // plain pointer |
| Klass valuetest(Klass k) { |
| k.append(" valuetest"); |
| return k; |
| } |
| Klass *pointertest(Klass *k) { |
| if (k) |
| k->append(" pointertest"); |
| return k; |
| } |
| Klass& reftest(Klass& k) { |
| k.append(" reftest"); |
| return k; |
| } |
| Klass *const& pointerreftest(Klass *const& k) { |
| k->append(" pointerreftest"); |
| return k; |
| } |
| // null |
| std::string nullsmartpointerpointertest(SwigBoost::intrusive_ptr<Klass>* k) { |
| if (k && *k) |
| return "not null"; |
| else if (!k) |
| return "null smartpointer pointer"; |
| else if (!*k) |
| return "null pointer"; |
| else |
| return "also not null"; |
| } |
| // $owner |
| Klass *pointerownertest() { |
| return new Klass("pointerownertest"); |
| } |
| SwigBoost::intrusive_ptr<Klass>* smartpointerpointerownertest() { |
| return new SwigBoost::intrusive_ptr<Klass>(new Klass("smartpointerpointerownertest")); |
| } |
| |
| const SwigBoost::intrusive_ptr<Klass>& ref_1() { |
| static SwigBoost::intrusive_ptr<Klass> sptr; |
| return sptr; |
| } |
| |
| // overloading tests |
| std::string overload_rawbyval(int i) { return "int"; } |
| std::string overload_rawbyval(Klass k) { return "rawbyval"; } |
| |
| std::string overload_rawbyref(int i) { return "int"; } |
| std::string overload_rawbyref(Klass &k) { return "rawbyref"; } |
| |
| std::string overload_rawbyptr(int i) { return "int"; } |
| std::string overload_rawbyptr(Klass *k) { return "rawbyptr"; } |
| |
| std::string overload_rawbyptrref(int i) { return "int"; } |
| std::string overload_rawbyptrref(Klass *const&k) { return "rawbyptrref"; } |
| |
| |
| |
| std::string overload_smartbyval(int i) { return "int"; } |
| std::string overload_smartbyval(SwigBoost::intrusive_ptr<Klass> k) { return "smartbyval"; } |
| |
| std::string overload_smartbyref(int i) { return "int"; } |
| std::string overload_smartbyref(SwigBoost::intrusive_ptr<Klass> &k) { return "smartbyref"; } |
| |
| std::string overload_smartbyptr(int i) { return "int"; } |
| std::string overload_smartbyptr(SwigBoost::intrusive_ptr<Klass> *k) { return "smartbyptr"; } |
| |
| std::string overload_smartbyptrref(int i) { return "int"; } |
| std::string overload_smartbyptrref(SwigBoost::intrusive_ptr<Klass> *&k) { return "smartbyptrref"; } |
| |
| } // namespace Space |
| |
| %} |
| %{ |
| boost::detail::atomic_count Space::Klass::total_count(0); |
| boost::detail::atomic_count Space::KlassWithoutRefCount::total_count(0); |
| boost::detail::atomic_count Space::IgnoredRefCountingBase::total_count(0); |
| boost::detail::atomic_count Space::KlassDerived::total_count(0); |
| boost::detail::atomic_count Space::KlassDerivedDerived::total_count(0); |
| %} |
| |
| // Member variables |
| |
| %inline %{ |
| struct MemberVariables { |
| MemberVariables() : SmartMemberPointer(new SwigBoost::intrusive_ptr<Space::Klass>()), SmartMemberReference(*(new SwigBoost::intrusive_ptr<Space::Klass>())), MemberPointer(0), MemberReference(MemberValue) {} |
| virtual ~MemberVariables() { |
| delete SmartMemberPointer; |
| delete &SmartMemberReference; |
| } |
| SwigBoost::intrusive_ptr<Space::Klass> SmartMemberValue; |
| SwigBoost::intrusive_ptr<Space::Klass> * SmartMemberPointer; |
| SwigBoost::intrusive_ptr<Space::Klass> & SmartMemberReference; |
| Space::Klass MemberValue; |
| Space::Klass * MemberPointer; |
| Space::Klass & MemberReference; |
| }; |
| |
| // Global variables |
| SwigBoost::intrusive_ptr<Space::Klass> GlobalSmartValue; |
| Space::Klass GlobalValue; |
| Space::Klass * GlobalPointer = 0; |
| Space::Klass & GlobalReference = GlobalValue; |
| |
| %} |
| |
| #if defined(INTRUSIVE_PTR_WRAPPERS_IMPLEMENTED) |
| |
| // Note: %template after the intrusive_ptr typemaps |
| %intrusive_ptr(Base<int, double>) |
| %intrusive_ptr(Pair<int, double>) |
| |
| #endif |
| |
| // Templates |
| %inline %{ |
| template <class T1, class T2> struct Base { |
| Space::Klass klassBase; |
| T1 baseVal1; |
| T2 baseVal2; |
| Base(T1 t1, T2 t2) : baseVal1(t1*2), baseVal2(t2*2) {} |
| virtual std::string getValue() const { return "Base<>"; }; |
| mutable int count; |
| void addref(void) const { count++; } |
| void release(void) const { if (--count == 0) delete this; } |
| int use_count(void) const { return count; } |
| inline friend void intrusive_ptr_add_ref(const Base<T1, T2>* r) { r->addref(); } |
| inline friend void intrusive_ptr_release(const Base<T1, T2>* r) { r->release(); } |
| }; |
| %} |
| |
| %template(BaseIntDouble) Base<int, double>; |
| |
| %inline %{ |
| template <class T1, class T2> struct Pair : Base<T1, T2> { |
| Space::Klass klassPair; |
| T1 val1; |
| T2 val2; |
| Pair(T1 t1, T2 t2) : Base<T1, T2>(t1, t2), val1(t1), val2(t2) {} |
| virtual std::string getValue() const { return "Pair<>"; }; |
| }; |
| |
| Pair<int, double> pair_id2(Pair<int, double> p) { return p; } |
| SwigBoost::intrusive_ptr< Pair<int, double> > pair_id1(SwigBoost::intrusive_ptr< Pair<int, double> > p) { return p; } |
| |
| long use_count(const SwigBoost::shared_ptr<Space::Klass>& sptr) { |
| return sptr.use_count(); |
| } |
| long use_count(const SwigBoost::shared_ptr<Space::KlassDerived>& sptr) { |
| return sptr.use_count(); |
| } |
| long use_count(const SwigBoost::shared_ptr<Space::KlassDerivedDerived>& sptr) { |
| return sptr.use_count(); |
| } |
| %} |
| |
| %template(PairIntDouble) Pair<int, double>; |
| |
| // For counting the instances of intrusive_ptr (all of which are created on the heap) |
| // intrusive_ptr_wrapper_count() gives overall count |
| %inline %{ |
| namespace SwigBoost { |
| const int NOT_COUNTING = -123456; |
| int intrusive_ptr_wrapper_count() { |
| #ifdef INTRUSIVE_PTR_WRAPPER |
| return SwigBoost::IntrusivePtrWrapper::getTotalCount(); |
| #else |
| return NOT_COUNTING; |
| #endif |
| } |
| #ifdef INTRUSIVE_PTR_WRAPPER |
| template<> std::string show_message(boost::intrusive_ptr<Space::Klass >*t) { |
| if (!t) |
| return "null intrusive_ptr!!!"; |
| if (*t) |
| return "Klass: " + (*t)->getValue(); |
| else |
| return "Klass: NULL"; |
| } |
| template<> std::string show_message(boost::intrusive_ptr<const Space::Klass >*t) { |
| if (!t) |
| return "null intrusive_ptr!!!"; |
| if (*t) |
| return "Klass: " + (*t)->getValue(); |
| else |
| return "Klass: NULL"; |
| } |
| template<> std::string show_message(boost::intrusive_ptr<Space::KlassDerived >*t) { |
| if (!t) |
| return "null intrusive_ptr!!!"; |
| if (*t) |
| return "KlassDerived: " + (*t)->getValue(); |
| else |
| return "KlassDerived: NULL"; |
| } |
| template<> std::string show_message(boost::intrusive_ptr<const Space::KlassDerived >*t) { |
| if (!t) |
| return "null intrusive_ptr!!!"; |
| if (*t) |
| return "KlassDerived: " + (*t)->getValue(); |
| else |
| return "KlassDerived: NULL"; |
| } |
| #endif |
| } |
| %} |
| |