customizing boost::function

Hi, I would like to get some feedback on some changes that I would like to make to boost::function for my own use only and I figured that this would be the best place for it. I basically want to detect if there is a NULL "this" bound to a member function. I want to do this so that i can prevent dereferencing a NULL pointer when calling a member function. I hope the following code example will clarify. /////////////////////////////////////////////////////////////////////// // example code: /////////////////////////////////////////////////////////////////////// struct X { void f() { assert(this != NULL); } }; my_smart_ptr<X> sp_x = new X(); my_weak_ptr<X> wp_x = sp_x; boost::function0<void> _f = bind(&X::f,wp_x); assert(!_f.empty()); sp_x.reset(); // wp_x == NULL if(!_f.empty()) { _f(); // This will fail } //////////////////////////////////////////////////////////////////////// I can't use exceptions because the code size would be too great on my embedded arm platform. Therefore I would like to have a member of boost::function that would tell me if i could call the function. I was thinking empty() but that may not be a good choice. I am just looking for a little guidance and also any general feedback. Thanks -- Theodore Witkamp CTO RiffWare LLC 107 S Holliston Ave Apt 308 Pasadena, CA 91106 Mb. 626-372-0931

Theodore Witkamp wrote:
Hi, I would like to get some feedback on some changes that I would like to make to boost::function for my own use only and I figured that this would be the best place for it.
I basically want to detect if there is a NULL "this" bound to a member function. I want to do this so that i can prevent dereferencing a NULL pointer when calling a member function. I hope the following code example will clarify. /////////////////////////////////////////////////////////////////////// // example code: /////////////////////////////////////////////////////////////////////// struct X { void f() { assert(this != NULL); } };
my_smart_ptr<X> sp_x = new X(); my_weak_ptr<X> wp_x = sp_x; boost::function0<void> _f = bind(&X::f,wp_x); assert(!_f.empty()); sp_x.reset(); // wp_x == NULL
if(!_f.empty()) { _f(); // This will fail } ////////////////////////////////////////////////////////////////////////
I don't see how that code can work anyway, since you can't use a weak_ptr to directly invoke X::f. -- Jonathan Biggar jon@levanta.com

If you notice it's my_weak_ptr not boost::weak_ptr. Which can be used in this way due to the implementation of get_pointer for that type. I am using my own smart pointer classes. Thanks On 12/13/06, Jonathan Biggar <jon@levanta.com> wrote:
Theodore Witkamp wrote:
Hi, I would like to get some feedback on some changes that I would like to make to boost::function for my own use only and I figured that this would be the best place for it.
I basically want to detect if there is a NULL "this" bound to a member function. I want to do this so that i can prevent dereferencing a NULL pointer when calling a member function. I hope the following code example will clarify. /////////////////////////////////////////////////////////////////////// // example code: /////////////////////////////////////////////////////////////////////// struct X { void f() { assert(this != NULL); } };
my_smart_ptr<X> sp_x = new X(); my_weak_ptr<X> wp_x = sp_x; boost::function0<void> _f = bind(&X::f,wp_x); assert(!_f.empty()); sp_x.reset(); // wp_x == NULL
if(!_f.empty()) { _f(); // This will fail } ////////////////////////////////////////////////////////////////////////
I don't see how that code can work anyway, since you can't use a weak_ptr to directly invoke X::f.
-- Jonathan Biggar jon@levanta.com
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Theodore Witkamp CTO RiffWare LLC 107 S Holliston Ave Apt 308 Pasadena, CA 91106 Mb. 626-372-0931

Theodore Witkamp wrote:
If you notice it's my_weak_ptr not boost::weak_ptr. Which can be used in this way due to the implementation of get_pointer for that type.
This is dangerous since you may be left with a dangling this if something invalidates the weak pointer while you're inside f, but you probably knew that. (This is the reason why boost::weak_ptr can't be used in this way.) The "no exceptions" constraint makes it harder than it needs to be. In this situation I would probably use a null X object: struct Xb { virtual void f() = 0; }; struct Xn: Xb { void f() {} // stub }; Xn nx; struct X: Xb { void f(); // do real work }; Xb * lock( my_weak_ptr<Xb> px ) { return px? get_pointer( px ): &nx; } int main() { my_shared_ptr<Xb> px( new X ); my_weak_ptr<Xb> wp( px ); function<void()> f = bind( &Xb::f, bind( lock, wp ) ); f(); px.reset(); f(); } or something like that. Obviously untested. :-)

I thought about using a Null object but I think that would be too much of a burden. Given that the stub functions would need to be non-trivial in may cases because of the return types. And because my platform support cooperative multi threading not preemptive multi threading i can get away only locking when I call the function. I have my own non-boost smart pointers and function objects and i can call Func<>.isNull() on them and it does what I want. However I long for the convenience of bind. So I am left with a dilemma should I add more functionality to Func or add what I need to boost::function. Thanks On 12/13/06, Peter Dimov <pdimov@mmltd.net> wrote:
Theodore Witkamp wrote:
If you notice it's my_weak_ptr not boost::weak_ptr. Which can be used in this way due to the implementation of get_pointer for that type.
This is dangerous since you may be left with a dangling this if something invalidates the weak pointer while you're inside f, but you probably knew that. (This is the reason why boost::weak_ptr can't be used in this way.)
The "no exceptions" constraint makes it harder than it needs to be. In this situation I would probably use a null X object:
struct Xb { virtual void f() = 0; };
struct Xn: Xb { void f() {} // stub };
Xn nx;
struct X: Xb { void f(); // do real work };
Xb * lock( my_weak_ptr<Xb> px ) { return px? get_pointer( px ): &nx; }
int main() { my_shared_ptr<Xb> px( new X ); my_weak_ptr<Xb> wp( px );
function<void()> f = bind( &Xb::f, bind( lock, wp ) );
f();
px.reset();
f(); }
or something like that. Obviously untested. :-)
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Theodore Witkamp CTO RiffWare LLC 107 S Holliston Ave Apt 308 Pasadena, CA 91106 Mb. 626-372-0931

Theodore Witkamp wrote:
I have my own non-boost smart pointers and function objects and i can call Func<>.isNull() on them and it does what I want. However I long for the convenience of bind. So I am left with a dilemma should I add more functionality to Func or add what I need to boost::function.
boost::bind supports visit_each so you can find your weak pointer and test it for NULL, but you'll have to add this check to boost::function. boost::signal uses visit_each to peek inside bind and discover "trackable" pointers, but it seems to use its own logic for that, boost::function hasn't been modified to call visit_each.
participants (3)
-
Jonathan Biggar
-
Peter Dimov
-
Theodore Witkamp