BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_pointercastutil.h
Go to the documentation of this file.
1/// @file bsls_pointercastutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_pointercastutil.h -*-C++-*-
8#ifndef INCLUDED_BSLS_POINTERCASTUTIL
9#define INCLUDED_BSLS_POINTERCASTUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_pointercastutil bsls_pointercastutil
15/// @brief Provide function to cast between function and data pointers.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_pointercastutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_pointercastutil-purpose"> Purpose</a>
25/// * <a href="#bsls_pointercastutil-classes"> Classes </a>
26/// * <a href="#bsls_pointercastutil-description"> Description </a>
27/// * <a href="#bsls_pointercastutil-usage"> Usage </a>
28/// * <a href="#bsls_pointercastutil-example-1-using-a-function-pointer-as-a-closure-parameter"> Example 1: Using a function pointer as a closure parameter </a>
29///
30/// # Purpose {#bsls_pointercastutil-purpose}
31/// Provide function to cast between function and data pointers.
32///
33/// # Classes {#bsls_pointercastutil-classes}
34///
35/// - bsls::PointerCastUtil: namespace for pointer-casting function
36///
37/// # Description {#bsls_pointercastutil-description}
38/// This component, `bsls::PointerCastUtil`, provides a utility
39/// function to allow casting between function and data pointers without
40/// triggering compiler warnings. Such casts are legal in the latest C++
41/// standard, but were not always so.
42///
43/// ## Usage {#bsls_pointercastutil-usage}
44///
45///
46/// This section illustrates intended use of this component.
47///
48/// ### Example 1: Using a function pointer as a closure parameter {#bsls_pointercastutil-example-1-using-a-function-pointer-as-a-closure-parameter}
49///
50///
51/// Suppose there is an event-handling service that requires registration of a
52/// combination of object and closure value, and that invokes a method on the
53/// object, passing back the closure.
54///
55/// First we define the service and its handler:
56/// @code
57/// struct Handler { virtual void handle(void *closure) = 0; };
58/// class Service {
59/// Handler *d_handler_p;
60/// void *d_closure_p;
61/// public:
62/// void registerHandler(Handler *handler, void *closure = 0) {
63/// d_handler_p = handler;
64/// d_closure_p = closure;
65/// }
66/// void eventOccurred() { d_handler_p->handle(d_closure_p); }
67/// };
68/// @endcode
69/// Then, we want to define a handler that will receive a function pointer as
70/// the closure object and invoke it. In order to do that, we must cast it to a
71/// function pointer, but some compilers may not allow it. We can use
72/// `bsls::PointerCastUtil::cast` to accomplish this:
73/// @code
74/// struct MyHandler : Handler {
75/// void handle(void *closure) {
76/// bsls::PointerCastUtil::cast<void(*)()>(closure)();
77/// }
78/// };
79/// @endcode
80/// Next, we will set up a sample service and our handler function:
81/// @code
82/// Service aService;
83/// static int counter = 0;
84/// void event() { ++counter; }
85/// @endcode
86/// Finally, we will register our handler and then trigger events to verify that
87/// our handler is recording them correctly. To register the function pointer
88/// as a closure object, we must cast it to a data pointer. Again, we can use
89/// `bsls::PointerCastUtil::cast` to accomplish this:
90/// @code
91/// MyHandler ah;
92/// aService.registerHandler(&ah, bsls::PointerCastUtil::cast<void *>(event));
93/// aService.eventOccurred();
94/// aService.eventOccurred();
95/// assert(counter == 2);
96/// @endcode
97/// @}
98/** @} */
99/** @} */
100
101/** @addtogroup bsl
102 * @{
103 */
104/** @addtogroup bsls
105 * @{
106 */
107/** @addtogroup bsls_pointercastutil
108 * @{
109 */
110
111#include <bsls_annotation.h>
112#include <bsls_types.h>
113
114
115namespace bsls {
116
117 //=======================
118 // struct PointerCastUtil
119 //=======================
120
121/// This `struct` provides a namespace for a `static` utility function that
122/// allows casting between function and data pointers.
124
125 // CLASS METHODS
126
127 /// Return the specified `from` value cast to `TO_TYPE`, casting it in
128 /// two steps, first to an integer type the size of a pointer and then
129 /// to the target type. This function is intended to be used to cast
130 /// between function and data pointers, as doing such a cast directly
131 /// was once illegal. The behavior is undefined unless both `FROM_TYPE`
132 /// and `TO_TYPE` are not larger than the intermediate integer type.
133 template <class TO_TYPE, class FROM_TYPE>
134 static TO_TYPE cast(FROM_TYPE from);
135};
136
137} // close package namespace
138
139template <class TO_TYPE, class FROM_TYPE>
140inline
141TO_TYPE bsls::PointerCastUtil::cast(FROM_TYPE from)
142{
143 BSLS_ANNOTATION_UNUSED typedef char FROM_TYPE_SizeCheck[
144 sizeof(bsls::Types::IntPtr) >= sizeof(FROM_TYPE) ? 1 : -1];
145
146 /// Static asserts ensuring that neither `FROM_TYPE` nor `TO_TYPE` is
147 /// larger than the intermediate integer type. Note that @ref bslmf_assert
148 /// cannot be used here because of package dependency rules.
149 BSLS_ANNOTATION_UNUSED typedef char TO_TYPE_SizeCheck[
150 sizeof(bsls::Types::IntPtr) >= sizeof(TO_TYPE) ? 1 : -1];
151
152 return reinterpret_cast<TO_TYPE>(
153 reinterpret_cast<bsls::Types::IntPtr>(from));
154}
155
156
157
158#endif
159
160// ----------------------------------------------------------------------------
161// Copyright 2016 Bloomberg Finance L.P.
162//
163// Licensed under the Apache License, Version 2.0 (the "License");
164// you may not use this file except in compliance with the License.
165// You may obtain a copy of the License at
166//
167// http://www.apache.org/licenses/LICENSE-2.0
168//
169// Unless required by applicable law or agreed to in writing, software
170// distributed under the License is distributed on an "AS IS" BASIS,
171// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
172// See the License for the specific language governing permissions and
173// limitations under the License.
174// ----------------------------- END-OF-FILE ----------------------------------
175
176/** @} */
177/** @} */
178/** @} */
#define BSLS_ANNOTATION_UNUSED
Definition bsls_annotation.h:287
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
static TO_TYPE cast(FROM_TYPE from)
Definition bsls_pointercastutil.h:141
Definition bdlt_iso8601util.h:691
Definition bsls_pointercastutil.h:123
std::ptrdiff_t IntPtr
Definition bsls_types.h:130