Quick Links:

bal | bbl | bdl | bsl

Namespaces | Functions

Component bsls_pointercastutil
[Package bsls]

Provide function to cast between function and data pointers. More...

Namespaces

namespace  bsls

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:
bsls::PointerCastUtil namespace for pointer-casting function
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

template<class TO_TYPE , class FROM_TYPE >
TO_TYPE bsls::PointerCastUtil::cast ( FROM_TYPE  from  )  [inline, static, inherited]

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.

References BSLS_ANNOTATION_UNUSED.