Boost logo

Boost Users :

From: Jean-François Brouillet (verec_at_[hidden])
Date: 2005-05-15 06:00:55


On 2005-05-15 00:49:54 +0100, "Peter Dimov" <pdimov_at_[hidden]> said:

> intrusive_ptr<T> is convertible to intrusive_ptr<U> when T*
> is convertibl e to U*.

It does, indeed! Many thanks. Not sure why I thought that the
guarantee given by shared_ptr somehow negatively implied that
such a guarantee wouldn't hold for intrusive_ptr. I was wrong.

in http://www.boost.org/libs/smart_ptr/smarttests.htm

there's a mention of a "cyclic" smart pointer implementation
that dealt with cycles "using a dequeue". Is this available
somewhere (I couldn't locate it in boost 1.32) ?

Anyway, here's my revised snippet that satisfies all my criteria:
- polymorphic covariance (for lack of a better name :)
- ad lib creation of the envelope from the base type
   without any concern about "lack of sharing"
- and, the icing on the cake: I haven't any qualm any more
   about passing intrusive_ptr<T> around by value since they're
   only the size of a pointer and thus should entirely fit in
   in a register.

Thanks again.

--
JFB
#include <iostream>
#include <boost/intrusive_ptr.hpp>
struct ObjectStruct {
     int refCount ;
     ObjectStruct() : refCount(0) {
         std::cout << std::hex << (int) this << " - I'm born" <<  
std::endl ;
     }
     void    refer()   {   ++refCount ;    }
     void    unrefer() {   if (--refCount == 0) delete this ; }
     virtual ~ObjectStruct() {
         std::cout << std::hex << (int) this << " - I'm gone" <<  
std::endl ;
     }
} ;
void    intrusive_ptr_add_ref(ObjectStruct * p) {   p->refer() ;      }
void    intrusive_ptr_release(ObjectStruct * p) {   p->unrefer() ;    }
struct TaskDoneStruct : public virtual ObjectStruct {
     virtual void    success() = 0 ;
     virtual void    failure() = 0 ;
} ;
typedef boost::intrusive_ptr<TaskDoneStruct> TaskDone ;
struct MyTaskDone : public TaskDoneStruct {
     virtual void success() {
         std::cout << "MyTaskDone::Done lengthy process ..." <<  
std::endl ;
     }
     virtual void failure() {
         std::cout << "MyTaskDone::Aborted lengthy process ..." <<  
std::endl ;
     }
} ;
struct LongTaskStruct : public virtual ObjectStruct {
     TaskDone    callback ;
     virtual void    setCallback(const TaskDone& td) {
         this->callback = td ;
     }
     virtual void run() {
         start() ;
         complete() ;
     }
     virtual void start() = 0 ;
     virtual void complete() {
         if (callback) {
             callback->success() ;
         }
     }
     virtual     ~LongTaskStruct() {}
} ;
struct MyTaskStruct : public LongTaskStruct
                         ,    TaskDoneStruct {
     MyTaskStruct() {
         setCallback(TaskDone(this)) ;
     }
     virtual void start() {
         std::cout << "Starting lengthy process ..." << std::endl ;
     }
     virtual void success() {
         std::cout << "Done lengthy process ..." << std::endl ;
     }
     virtual void failure() {
         std::cout << "Aborted lengthy process ..." << std::endl ;
     }
} ;
struct MyFailingTaskStruct : public MyTaskStruct {
     virtual void start() {
         std::cout << "Aborting lengthy process ..." << std::endl ;
         if (callback) {
             callback->failure() ;
         }
     }
} ;
typedef boost::intrusive_ptr<MyTaskStruct> MyTask ;
typedef boost::intrusive_ptr<MyFailingTaskStruct> MyFailingTask ;
void callTask(MyTask task) {
     task->run() ;
}
void
taskTest2() {
     MyTask  myTask(new MyTaskStruct) ;
     callTask(myTask) ;
     MyFailingTask myFailingTask(new MyFailingTaskStruct) ;
     callTask(myFailingTask) ;
}
void
taskTest() {
     MyTask  myTask(new MyTaskStruct) ;
     myTask->run() ;
     myTask->setCallback(myTask) ;
     myTask->run() ;
     myTask->setCallback(TaskDone(new MyTaskDone)) ;
     myTask->run() ;
}
int
main(
     int     argc
,   char *  argv[]) {
     std::cout << "Tests starting ..." << std::endl ;
     taskTest() ;
     taskTest2() ;
     std::cout << "Tests done ..." << std::endl ;
     return 0 ;
}
/*
Tests starting ...
30018c - I'm born
Starting lengthy process ...
Done lengthy process ...
Starting lengthy process ...
Done lengthy process ...
3001a4 - I'm born
Starting lengthy process ...
MyTaskDone::Done lengthy process ...
3001a4 - I'm gone
30018c - I'm gone
30018c - I'm born
Starting lengthy process ...
Done lengthy process ...
3001bc - I'm born
Aborting lengthy process ...
Aborted lengthy process ...
Done lengthy process ...
Tests done ...
*/
-- 
Do your users a favor: give them Style: http://www.uiwithstyle.org

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net