|
BDE 4.39.x Production Release
|
Provide utilities for pointer manipulation.
Provide utilities for pointer manipulation.
This component provides a utility struct, bslma::PointerUtil, that serves as a namespace for static functions that perform low-level pointer manipulations useful for implementing portable generic facilities. voidify returns a void * from a pointer to a potentially cv-qualified type, or from a function pointer on platforms that support the conversion. unqualify returns a pointer to the cv-unqualified version of the pointed-to type, or returns a function pointer unchanged.
Conversion from a pointer-to-function to void * requires a reinterpret_cast and is conditionally-supported behavior in C++17; prior to C++17 it is undefined behavior. In practice, this conversion is well-defined on all platforms that BDE is known to support, and is formally a part of the POSIX Standard.
This section illustrates intended use of this component.
Suppose we are implementing a simplified optional-like container that holds a value of (template parameter) TYPE in a raw buffer. TYPE may be const-qualified (e.g., MyOptional<const int>).
First, we define the class template with an aligned buffer and a flag:
Then we implement emplace. We declare a pointer of the correct type to the return value so that we can efficiently return a reference to the object we are about to create.
Now, we use voidify to provide the address at which to construct the new object. A placement-new expression requires a void * operand, but TYPE may be cv-qualified and static_cast alone cannot produce void * from a pointer to a cv-qualified type.
Finally, we can use MyOptional with a const-qualified type. Without voidify, the placement new inside emplace would not compile:
Suppose we are given a construction facility that constructs an object of (template parameter) TYPE at a specified address having its default value, and returns a pointer to the newly created object:
When forwarding to such a facility from our own generic code, we can strip any cv-qualification with unqualify so that the downstream facility is always invoked with the unqualified type, avoiding a redundant template instantiation for each cv-variant of the same underlying type across the entire program. Casting away const is well-defined when the underlying storage was not originally declared const – as is typical for raw buffers managed by containers and allocators. Observe that the int * returned by constructInPlace implicitly converts to const int * or volatile int * when assigned back, correctly preserving the original cv-qualification: