BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_pointercastutil

Functions

template<class TO_TYPE , class FROM_TYPE >
static TO_TYPE bsls::PointerCastUtil::cast (FROM_TYPE from)
 

Detailed Description

Outline

Purpose

Provide function to cast between function and data pointers.

Classes

Description

This component, bsls::PointerCastUtil, provides a utility function to allow casting between function and data pointers without triggering compiler warnings. Such casts are legal in the latest C++ standard, but were not always so.

Usage

This section illustrates intended use of this component.

Example 1: Using a function pointer as a closure parameter

Suppose there is an event-handling service that requires registration of a combination of object and closure value, and that invokes a method on the object, passing back the closure.

First we define the service and its handler:

struct Handler { virtual void handle(void *closure) = 0; };
class Service {
Handler *d_handler_p;
void *d_closure_p;
public:
void registerHandler(Handler *handler, void *closure = 0) {
d_handler_p = handler;
d_closure_p = closure;
}
void eventOccurred() { d_handler_p->handle(d_closure_p); }
};

Then, we want to define a handler that will receive a function pointer as the closure object and invoke it. In order to do that, we must cast it to a function pointer, but some compilers may not allow it. We can use bsls::PointerCastUtil::cast to accomplish this:

struct MyHandler : Handler {
void handle(void *closure) {
bsls::PointerCastUtil::cast<void(*)()>(closure)();
}
};

Next, we will set up a sample service and our handler function:

Service aService;
static int counter = 0;
void event() { ++counter; }

Finally, we will register our handler and then trigger events to verify that our handler is recording them correctly. To register the function pointer as a closure object, we must cast it to a data pointer. Again, we can use bsls::PointerCastUtil::cast to accomplish this:

MyHandler ah;
aService.registerHandler(&ah, bsls::PointerCastUtil::cast<void *>(event));
aService.eventOccurred();
aService.eventOccurred();
assert(counter == 2);

Function Documentation

◆ cast()

template<class TO_TYPE , class FROM_TYPE >
TO_TYPE bsls::PointerCastUtil::cast ( FROM_TYPE  from)
inlinestatic

Return the specified from value cast to TO_TYPE, casting it in two steps, first to an integer type the size of a pointer and then to the target type. This function is intended to be used to cast between function and data pointers, as doing such a cast directly was once illegal. The behavior is undefined unless both FROM_TYPE and TO_TYPE are not larger than the intermediate integer type.

Static asserts ensuring that neither FROM_TYPE nor TO_TYPE is larger than the intermediate integer type. Note that bslmf_assert cannot be used here because of package dependency rules.