BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_nullptr.h
Go to the documentation of this file.
1/// @file bsls_nullptr.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_nullptr.h -*-C++-*-
8#ifndef INCLUDED_BSLS_NULLPTR
9#define INCLUDED_BSLS_NULLPTR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_nullptr bsls_nullptr
15/// @brief Provide a distinct type for null pointer literals.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_nullptr
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_nullptr-purpose"> Purpose</a>
25/// * <a href="#bsls_nullptr-classes"> Classes </a>
26/// * <a href="#bsls_nullptr-description"> Description </a>
27/// * <a href="#bsls_nullptr-limitations"> Limitations </a>
28/// * <a href="#bsls_nullptr-usage"> Usage </a>
29///
30/// # Purpose {#bsls_nullptr-purpose}
31/// Provide a distinct type for null pointer literals.
32///
33/// # Classes {#bsls_nullptr-classes}
34///
35/// - bsl::nullptr_t: type for function parameter to match null pointer literals
36///
37/// # Description {#bsls_nullptr-description}
38/// This component provides `bsl::nullptr_t` as a limited emulation
39/// of the C++11 type, `std::nullptr_t`, which can be used as a function
40/// parameter type to create an overload set where null pointer literals are
41/// handled specially. Note that this component will be deprecated, and
42/// ultimately removed, once BDE code can assume support for a C++11 compiler.
43/// On a platform that supports the language feature, a fully-conforming
44/// `typedef` is supplied rather than using the emulation layer.
45///
46/// ## Limitations {#bsls_nullptr-limitations}
47///
48///
49/// This component provides a simple emulation of the C++11 facility, which
50/// cannot be expressed with a pure library solution. As such it comes with a
51/// number of limitations. The most obvious is that C++11 provides a new null
52/// pointer literal, `nullptr`, which is not emulated by this component. The
53/// new null pointer literal is an object of a new type, expressed by the alias
54/// `nullptr_t`, which this component emulates. However, as this is a
55/// library-only emulation, it does not have any preference in the overloading
56/// rules, so will be an equal-rank ambiguous match. For example, given the
57/// following overload set, a call to `myFunction` with a null pointer literal
58/// would be ambiguous:
59/// @code
60/// void myFunction(void *p);
61/// void myFunction(bsl::nullptr_t);
62///
63/// int main() {
64/// myFunction(0); // ERROR, ambiguous function call
65/// }
66/// @endcode
67/// However, if the pointer-argument is a pointer whose type is deduced from the
68/// function call, then no pointer type can be deduced from the null pointer and
69/// this component becomes necessary.
70/// @code
71/// template<typename T>
72/// void myFunction(T *p);
73/// void myFunction(bsl::nullptr_t);
74///
75/// int main() {
76/// myFunction(0); // call the 'bsl::nullptr_t' method
77/// }
78/// @endcode
79/// Null pointer values can be created in C++11 by creating objects of type
80/// `std::nullptr_t`, and then used to initialize pointer and pointer-to-member
81/// objects:
82/// @code
83/// std::nullptr_t nullLiteral = std::nullptr_t();
84/// int *pI = nullLiteral;
85/// @endcode
86/// The type of a `bsl::nullptr_t` object cannot be used in such assignments or
87/// initializations, unless compiled on a platform that natively supports this
88/// C++11 language feature.
89///
90/// ## Usage {#bsls_nullptr-usage}
91///
92///
93/// This section illustrates intended use of this component.
94///
95/// Example 1: Constructing a "smart pointer"
96/// - - - - - - - - - - - - - - - - - - - - -
97/// First we define a smart pointer class template, as a guard to destroy a
98/// managed object as the smart pointer leaves scope. This class will have a
99/// constructor template taking a pointer to a type potentially derived from
100/// the parameterized type of the smart pointer, and also a deletion-policy
101/// function. By capturing the most-derived type through type-deduction when
102/// the smart pointer is constructed, we can ensure the correct destructor is
103/// called, even if the destructor of the base class has not been declared as
104/// `virtual`. However, relying on type-deduction means we cannot pass a null
105/// pointer to this constructor, as it is not possible to deduce what type a
106/// null pointer is supposed to refer to, therefore we must use a special null
107/// pointer type, such as `bsls::nullptr_t`. Note that in real code we would
108/// allocate and reclaim memory using a user-specified allocator, but defining
109/// such protocols in this low level component would further distract from the
110/// `nullptr` usage in this example.
111/// @code
112/// template<class TARGET_TYPE>
113/// class ScopedPointer {
114/// // This class template is a guard to manage a dynamically created
115/// // object of the parameterized 'TARGET_TYPE'.
116///
117/// private:
118/// typedef void DeleterFn(TARGET_TYPE *); // deleter type
119///
120/// // DATA
121/// TARGET_TYPE *d_target_p; // wrapped pointer
122/// DeleterFn *d_deleter_fn; // deleter function
123///
124/// template<class SOURCE_TYPE>
125/// static void defaultDeleteFn(TARGET_TYPE *ptr);
126/// // Destroy the specified '*ptr' by calling 'delete' on the pointer
127/// // cast to the parameterized 'SOURCE_TYPE*'. It is an error to
128/// // instantiate this template with a 'SOURCE_TYPE' that is not
129/// // derived from (and cv-compatible with) 'TARGET_TYPE'.
130///
131/// private:
132/// // NOT IMPLEMENTED
133/// ScopedPointer(const ScopedPointer&);
134/// ScopedPointer& operator=(const ScopedPointer&);
135/// // Objects of this type cannot be copied.
136///
137/// public:
138/// template<class SOURCE_TYPE>
139/// ScopedPointer(SOURCE_TYPE *pointer,
140/// DeleterFn *fn = &defaultDeleteFn<SOURCE_TYPE>);
141/// // Create a 'ScopedPointer' object owning the specified 'pointer'
142/// // and using the specified 'fn' to destroy the owned pointer when
143/// // this object is destroyed.
144///
145/// ScopedPointer(bsl::nullptr_t = 0);
146/// // Create an empty 'ScopedPointer' object that does not own a
147/// // pointer.
148///
149/// ~ScopedPointer();
150/// // Destroy this 'ScopedPointer' object and the target object
151/// // that it owns, using the stored deleter function.
152///
153/// // Further methods appropriate to a smart pointer, such as
154/// // 'operator*' and 'operator->' elided from this example.
155/// };
156/// @endcode
157/// Then we provide a definition for each of the methods.
158/// @code
159/// template<class TARGET_TYPE>
160/// template<class SOURCE_TYPE>
161/// void ScopedPointer<TARGET_TYPE>::defaultDeleteFn(TARGET_TYPE *ptr)
162/// {
163/// delete static_cast<SOURCE_TYPE *>(ptr);
164/// }
165///
166/// template<class TARGET_TYPE>
167/// template<class SOURCE_TYPE>
168/// inline
169/// ScopedPointer<TARGET_TYPE>::ScopedPointer(SOURCE_TYPE *pointer,
170/// DeleterFn *fn)
171/// : d_target_p(pointer)
172/// , d_deleter_fn(fn)
173/// {
174/// }
175///
176/// template<class TARGET_TYPE>
177/// inline
178/// ScopedPointer<TARGET_TYPE>::ScopedPointer(bsl::nullptr_t)
179/// : d_target_p(0)
180/// , d_deleter_fn(0)
181/// {
182/// }
183///
184/// template<class TARGET_TYPE>
185/// inline
186/// ScopedPointer<TARGET_TYPE>::~ScopedPointer()
187/// {
188/// if (d_deleter_fn) {
189/// d_deleter_fn(d_target_p);
190/// }
191/// }
192/// @endcode
193/// Finally, we can construct a `ScopedPointer` with a null pointer literal,
194/// that would otherwise be non-deducible, using our `bsl::nullptr_t` overload.
195/// @code
196/// void testScopedPointer()
197/// {
198/// ScopedPointer<int> x(0);
199/// }
200/// @endcode
201/// @}
202/** @} */
203/** @} */
204
205/** @addtogroup bsl
206 * @{
207 */
208/** @addtogroup bsls
209 * @{
210 */
211/** @addtogroup bsls_nullptr
212 * @{
213 */
214
215#include <bsls_compilerfeatures.h>
216#include <bsls_platform.h>
217
218#if defined(BSLS_COMPILERFEATURES_SUPPORT_NULLPTR)
219# if defined nullptr
220# error Some earlier header has defined the keyword 'nullptr' as a macro.
221 // Occasionally we encounter code-bases predating C++11 that define a macro
222 // named 'nullptr', possible trying to mimic the expected interface when
223 // ported to a C++11 world. However, it is undefined behavior to redefine
224 // a keyword of the language, and typically breaks the implementation of
225 // the type alias 'nullptr_t' in unusual ways, that (wrongly) report this
226 // header file as the source of the problem, rather than the point at which
227 // it is first observed.
228# endif
229
230# if !defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE)
231 // We currently know of no platform that supports 'nullptr' and does not
232 // also support 'decltype'. We conservatively error should such a
233 // surprising platform emerge.
234# error No support for 'std::nullptr_t' unless 'decltype' is also available.
235# else
236# define BSLS_NULLPTR_USING_NATIVE_NULLPTR_T // feature detection macro
237namespace bsl {
238 // We must define this 'typedef' appropriately for platforms that support
239 // 'nullptr'.
240
241#if defined(BSLS_PLATFORM_CMP_MSVC) && defined(__cplusplus_cli)
242 // MSVC in /clr mode defines 'nullptr' as the .NET null pointer type, which
243 // is different from C++11 'nullptr'. To resolve this conflict MSVC
244 // provides '__nullptr' for C++11 'nullptr'.
245
246 typedef decltype(__nullptr) nullptr_t;
247#else
248 typedef decltype(nullptr) nullptr_t;
249#endif
250}
251# endif
252#else
253
254
255namespace bsls {
256 // ===================
257 // class bsls::Nullptr
258 // ===================
259
260/// This implementation-private `struct` provides an alias for a type that
261/// can match a null pointer literal, but is not a pointer itself. It
262/// offers a limited emulation of the C++11 `std::nullptr_t` type.
264
265 private:
266 struct Nullptr_ProxyType { int dummy; }; // private class to supply a
267 // unique pointer-to-member type.
268
269 public:
270 typedef int Nullptr_ProxyType::* Type; // alias to an "unspecified" null
271 // pointer type.
272};
273
274} // close package namespace
275
276
277namespace bsl {
278
279 /// Alias for a type that can match a null pointer literal, but is not a
280 /// pointer type itself.
281 typedef BloombergLP::bsls::Nullptr_Impl::Type nullptr_t;
282}
283#endif
284
285#endif
286
287// ----------------------------------------------------------------------------
288// Copyright 2013 Bloomberg Finance L.P.
289//
290// Licensed under the Apache License, Version 2.0 (the "License");
291// you may not use this file except in compliance with the License.
292// You may obtain a copy of the License at
293//
294// http://www.apache.org/licenses/LICENSE-2.0
295//
296// Unless required by applicable law or agreed to in writing, software
297// distributed under the License is distributed on an "AS IS" BASIS,
298// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
299// See the License for the specific language governing permissions and
300// limitations under the License.
301// ----------------------------- END-OF-FILE ----------------------------------
302
303/** @} */
304/** @} */
305/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlb_printmethods.h:283
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:281
Definition bdlt_iso8601util.h:691
Definition bsls_nullptr.h:263
int Nullptr_ProxyType::* Type
Definition bsls_nullptr.h:270