BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_util.h
Go to the documentation of this file.
1/// @file bsls_util.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_util.h -*-C++-*-
8#ifndef INCLUDED_BSLS_UTIL
9#define INCLUDED_BSLS_UTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_util bsls_util
15/// @brief Provide essential, low-level support for portable generic code.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_util
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_util-purpose"> Purpose</a>
25/// * <a href="#bsls_util-classes"> Classes </a>
26/// * <a href="#bsls_util-macros"> Macros </a>
27/// * <a href="#bsls_util-description"> Description </a>
28/// * <a href="#bsls_util-usage"> Usage </a>
29/// * <a href="#bsls_util-example-1-obtain-the-address-of-a-class-that-defines-operator&"> Example 1: Obtain the Address of a class That Defines operator&. </a>
30///
31/// # Purpose {#bsls_util-purpose}
32/// Provide essential, low-level support for portable generic code.
33///
34/// # Classes {#bsls_util-classes}
35///
36/// - bsls::Util: utility class supplying essential, low-level functionality
37///
38/// # Macros {#bsls_util-macros}
39///
40/// - BSLS_UTIL_ADDRESSOF(OBJ): address of `OBJ`, even if `operator&` overloaded
41///
42/// # Description {#bsls_util-description}
43/// This component defines a utility `struct`, `bsls::Util`, that
44/// serves as a namespace for a suite of pure functions that supply essential
45/// low-level support for implementing portable generic facilities such as might
46/// be found in the C++ standard library.
47///
48/// ## Usage {#bsls_util-usage}
49///
50///
51/// This section illustrates intended use of this component.
52///
53/// ### Example 1: Obtain the Address of a class That Defines operator&. {#bsls_util-example-1-obtain-the-address-of-a-class-that-defines-operator&}
54///
55///
56/// There are times, especially within low-level library functions, where it is
57/// necessary to obtain the address of an object even if that object's class
58/// overloads `operator&` to return something other than the object's address.
59///
60/// First, we create a special reference-like type that can refer to a single
61/// bit within a byte (inline implementations are provided in class scope for
62/// ease of exposition):
63/// @code
64/// class BitReference {
65///
66/// // DATA
67/// char *d_byte_p;
68/// int d_bitpos;
69///
70/// public:
71/// // CREATORS
72/// BitReference(char *byteptr = 0, int bitpos = 0) // IMPLICIT
73/// : d_byte_p(byteptr)
74/// , d_bitpos(bitpos)
75/// {
76/// }
77///
78/// // ACCESSORS
79/// operator bool() const { return (*d_byte_p >> d_bitpos) & 1; }
80///
81/// char *byteptr() const { return d_byte_p; }
82/// int bitpos() const { return d_bitpos; }
83/// };
84/// @endcode
85/// Then, we create a pointer-like type that can point to a single bit:
86/// @code
87/// class BitPointer {
88///
89/// // DATA
90/// char *d_byte_p;
91/// int d_bitpos;
92///
93/// public:
94/// // CREATORS
95/// BitPointer(char *byteptr = 0, int bitpos = 0) // IMPLICIT
96/// : d_byte_p(byteptr)
97/// , d_bitpos(bitpos)
98/// {
99/// }
100///
101/// // ACCESSORS
102/// BitReference operator*() const
103/// {
104/// return BitReference(d_byte_p, d_bitpos);
105/// }
106///
107/// // etc.
108/// };
109/// @endcode
110/// Next, we overload `operator&` for `BitReference` to return a `BitPointer`
111/// instead of a raw pointer, completing the setup:
112/// @code
113/// inline BitPointer operator&(const BitReference& ref)
114/// {
115/// return BitPointer(ref.byteptr(), ref.bitpos());
116/// }
117/// @endcode
118/// Then, we note that there are times when it might be desirable to get the
119/// true address of a `BitReference`. Since the above overload prevents the
120/// obvious syntax from working, we use `bsls::Util::addressOf` to accomplish
121/// this task.
122///
123/// Next, we create a `BitReference` object:
124/// @code
125/// char c[4];
126/// BitReference br(c, 3);
127/// @endcode
128/// Now, we invoke `bsls::Util::addressOf` to obtain and save the address of
129/// `br`:
130/// @code
131/// BitReference *p = bsls::Util::addressOf(br); // OK
132/// // BitReference *p = &br; // Won't compile
133/// @endcode
134/// Notice that the commented line illustrates canonical use of `operator&` that
135/// would not compile in this example.
136///
137/// Finally, we verify that address obtained is the correct one, running some
138/// sanity checks:
139/// @code
140/// assert(0 != p);
141/// assert(c == p->byteptr());
142/// assert(3 == p->bitpos());
143/// @endcode
144/// @}
145/** @} */
146/** @} */
147
148/** @addtogroup bsl
149 * @{
150 */
151/** @addtogroup bsls
152 * @{
153 */
154/** @addtogroup bsls_util
155 * @{
156 */
157
158#include <bsls_compilerfeatures.h>
159#include <bsls_keyword.h>
160#include <bsls_platform.h>
161
162
163
164namespace bsls {
165
166/// This class template provides an easy way to alias a function pointer
167/// type when used as the return type of a function. The syntax for a
168/// function returning a function pointer is otherwise quite obscure, and
169/// difficult to read. As we want to return function pointers taking
170/// parameters and returning a result specified by template parameters
171/// below, it is not possible to define a simple typedef to the function
172/// type outside the function template itself.
173template <class TYPE>
175
176 typedef TYPE type; // alias of the template parameter 'TYPE'.
177};
178
179#ifdef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
180template <class TYPE>
181struct Util_RemoveReference {
182 typedef TYPE type;
183};
184
185template <class TYPE>
186struct Util_RemoveReference<TYPE&> {
187 typedef TYPE type;
188};
189
190template <class TYPE>
191struct Util_RemoveReference<TYPE&&> {
192 typedef TYPE type;
193};
194
195template <class TYPE>
196struct Util_AssertNotLvalue {
197 typedef int type;
198};
199
200template <class TYPE>
201struct Util_AssertNotLvalue<TYPE&> {
202 static_assert(sizeof(typename Util_Identity<TYPE>::type) == 0,
203 "Cannot forward an rvalue as an lvalue.");
204 typedef int type;
205};
206#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
207
208 // ===========
209 // struct Util
210 // ===========
211
212/// This `struct` provides a namespace for essential low-level functions for
213/// implementing portable generic facilities such as the C++ standard
214/// library.
215struct Util {
216
217 // CLASS METHODS
218
219 /// Return the address of the specified `obj`, even if `operator&` is
220 /// overloaded for objects of type `BSLS_TYPE`. Behavior is undefined
221 /// unless `BSLS_TYPE` is an object type. Note that this function
222 /// conforms to the C++11 definition for `addressof` as specified in the
223 /// section [specialized.addressof] (20.6.12.1) of the C++11 standard,
224 /// except that function types, which are not object types, are
225 /// supported by `std::addressof` in C++11.
226 template <class TYPE>
227 static TYPE *addressOf(TYPE& obj);
228
229 /// Return the address of the specified function `fn`. Note that this
230 /// implementation supports functions of only a limited number of
231 /// parameters, determined by the current needs of the BDE software. A
232 /// more general form that will support an arbitrary number of function
233 /// parameters will be available with C++11.
234 template <class RESULT>
235 static
236 typename Util_Identity<RESULT()>::type *addressOf(RESULT (&fn)());
237 template <class RESULT, class ARG>
238 static
239 typename Util_Identity<RESULT(ARG)>::type *addressOf(RESULT (&fn)(ARG));
240 template <class RESULT, class ARG1, class ARG2>
241 static
242 typename Util_Identity<RESULT(ARG1, ARG2)>::type *addressOf(
243 RESULT (&fn)(ARG1, ARG2));
244
245#ifdef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
246 template <class TYPE>
247 static
249 TYPE&& forward(typename Util_RemoveReference<TYPE>::type& t)
251
252 /// Return a reference to the specified `t` of non-deduced `TYPE`. If
253 /// `TYPE` is an lvalue-reference type, then the result will be an
254 /// lvalue-reference, and an rvalue-refernce otherwise. Note that as
255 /// `TYPE` is not deduced, it must be explicitly specified by the caller
256 /// of this function. Also note that while this function may return an
257 /// rvalue-reference, it cannot extend the lifetime of temporaries
258 /// beyond the expression that calls this function; storing an rvalue
259 /// reference to the result will lead to undefined behavior.
260 template <class TYPE>
261 static
263 TYPE&& forward(typename Util_RemoveReference<TYPE>::type&& t)
265#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
266};
267
268} // close package namespace
269
270 // ======
271 // MACROS
272 // ======
273
274// The following macros are private to the BDE implementation and not intended
275// for widespread use. They support the BDE STL decision for the standard
276// containers to support types that overload 'operator&' only on the Microsoft
277// platform. This support is provided on Microsoft to enable containers
278// holding the 'CComPtr' type from the Microsoft Foundation Class library
279// (which overloads 'operator&'), but is not provided on UNIX platforms to
280// avoid additional template bloat in the 'big' only to support a class design
281// that is almost certainly an error.
282#ifdef BSLS_PLATFORM_CMP_MSVC
283# define BSLS_UTIL_ADDRESSOF(OBJ) ::BloombergLP::bsls::Util::addressOf(OBJ)
284
285# if !defined(BDE_USE_ADDRESSOF)
286# define BDE_USE_ADDRESSOF
287# endif
288#else
289# define BSLS_UTIL_ADDRESSOF(OBJ) (&(OBJ))
290#endif
291
292namespace bsls {
293
294// This macro takes the address of an object by calling 'Util::addressOf' on
295// Windows, and simply taking the address with the '&' operator on all other
296// platforms.
297
298// ============================================================================
299// INLINE FUNCTION DEFINITIONS
300// ============================================================================
301
302// CLASS METHODS
303template <class TYPE>
304inline
305TYPE *Util::addressOf(TYPE& obj)
306{
307 return static_cast<TYPE *>(
308 static_cast<void *>(
309 const_cast<char *>(&reinterpret_cast<const volatile char&>(obj))));
310}
311
312template <class RESULT>
313inline
314typename Util_Identity<RESULT()>::type *
315Util::addressOf(RESULT (&fn)())
316{
317 return fn;
318}
319
320template <class RESULT, class ARG>
321inline
322typename Util_Identity<RESULT(ARG)>::type *
323Util::addressOf(RESULT (&fn)(ARG))
324{
325 return fn;
326}
327
328template <class RESULT, class ARG1, class ARG2>
329inline
330typename Util_Identity<RESULT(ARG1, ARG2)>::type *
331Util::addressOf(RESULT (&fn)(ARG1, ARG2))
332{
333 return fn;
334}
335
336#ifdef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
337template <class TYPE>
339TYPE&& Util::forward(typename Util_RemoveReference<TYPE>::type& t)
341{
342 return static_cast<TYPE&&>(t);
343}
344
345template <class TYPE>
347TYPE&& Util::forward(typename Util_RemoveReference<TYPE>::type&& t)
349{
350 static_assert(sizeof(typename Util_AssertNotLvalue<TYPE>::type) > 0,
351 "Just to trigger instantiation of the checker template.");
352 return static_cast<TYPE&&>(t);
353}
354#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
355
356} // close package namespace
357
358
359#endif
360
361// ----------------------------------------------------------------------------
362// Copyright 2013 Bloomberg Finance L.P.
363//
364// Licensed under the Apache License, Version 2.0 (the "License");
365// you may not use this file except in compliance with the License.
366// You may obtain a copy of the License at
367//
368// http://www.apache.org/licenses/LICENSE-2.0
369//
370// Unless required by applicable law or agreed to in writing, software
371// distributed under the License is distributed on an "AS IS" BASIS,
372// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
373// See the License for the specific language governing permissions and
374// limitations under the License.
375// ----------------------------- END-OF-FILE ----------------------------------
376
377/** @} */
378/** @} */
379/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
Definition bdlt_iso8601util.h:691
Definition bsls_util.h:174
TYPE type
Definition bsls_util.h:176
Definition bsls_util.h:215
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305