BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsltf_stdallocatoradaptor.h
Go to the documentation of this file.
1/// @file bsltf_stdallocatoradaptor.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsltf_stdallocatoradaptor.h -*-C++-*-
8#ifndef INCLUDED_BSLTF_STDALLOCATORADAPTOR
9#define INCLUDED_BSLTF_STDALLOCATORADAPTOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsltf_stdallocatoradaptor bsltf_stdallocatoradaptor
15/// @brief Provide a mechanism to propagate standard allocator state.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsltf
19/// @{
20/// @addtogroup bsltf_stdallocatoradaptor
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsltf_stdallocatoradaptor-purpose"> Purpose</a>
25/// * <a href="#bsltf_stdallocatoradaptor-classes"> Classes </a>
26/// * <a href="#bsltf_stdallocatoradaptor-description"> Description </a>
27/// * <a href="#bsltf_stdallocatoradaptor-usage"> Usage </a>
28/// * <a href="#bsltf_stdallocatoradaptor-example-1-allocator-propagation"> Example 1: Allocator Propagation </a>
29///
30/// # Purpose {#bsltf_stdallocatoradaptor-purpose}
31/// Provide a mechanism to propagate standard allocator state.
32///
33/// # Classes {#bsltf_stdallocatoradaptor-classes}
34///
35/// - bsltf::StdAllocatorAdaptor: adaptor that propagates allocator state
36///
37/// # Description {#bsltf_stdallocatoradaptor-description}
38/// This component provides an allocator adaptor class template,
39/// `bsltf::StdAllocatorAdaptor`, that mostly delegates operations to an
40/// allocator object of a (template parameter) allocator type, except that it
41/// enables the propagation of the (stateful) allocator object to constructed
42/// elements, if appropriate. This class template enables reuse of test cases
43/// in higher level components (e.g., containers) written first using
44/// `bslma::Allocator` and `bslma::TestAllocator` to also test correct
45/// allocation using a C++ standard style allocator.
46///
47/// StdAllocatorAdaptor' defines the minimal interface needed in order to comply
48/// with section 17.6.3.5 ([allocator.requirements]) of the C++11 standard. This
49/// class is similar to the @ref scoped_allocator_adaptor class template that is
50/// part of the C++11 standard, except that this adaptor does not support
51/// multiple levels of allocators (i.e., it is equivalent to the
52/// @ref scoped_allocator_adaptor with a single allocator).
53///
54/// ## Usage {#bsltf_stdallocatoradaptor-usage}
55///
56///
57/// This section illustrates intended use of this component.
58///
59/// ### Example 1: Allocator Propagation {#bsltf_stdallocatoradaptor-example-1-allocator-propagation}
60///
61///
62/// `bslma::ConstructionUtil` propagates `bslma::Allocator`, wrapped by C++
63/// standard style allocator, to the constructor, if type, being constructed,
64/// supports `UsesBslmaAllocator` trait. `bsltf::StdAllocatorAdaptor` is used
65/// in test drivers to get the same behavior for the types that do not support
66/// that trait.
67///
68/// Suppose, we want to adopt a test for a component that uses `bslma`-style
69/// allocation to test that this component correctly works with standard
70/// allocators. For simplicity the test below constructs an object of the
71/// (template parameter) type `TYPE` by calling allocator's `construct` method.
72/// We want to test that allocator is correctly propagated to the object
73/// constructor. First, we define the test implementation:
74/// @code
75/// template<class TYPE, class ALLOC = bsl::allocator<TYPE> >
76/// class TestDriver
77/// {
78/// public:
79/// static void testCase()
80/// {
81/// bslma::TestAllocator oa("object");
82/// ALLOC xoa(&oa);
83///
84/// bsls::ObjectBuffer<TYPE> buffer;
85///
86/// xoa.construct(buffer.address(), 1);
87///
88/// bslma::DestructorGuard<TYPE> guard(&buffer.object());
89///
90/// const TYPE& X = buffer.object();
91///
92/// assert(1 == X.data());
93/// assert(&oa == X.allocator());
94/// }
95/// };
96/// @endcode
97/// Now, parameterize `TestDriver` class with `StdAllocatorAdaptor` explicitly
98/// to expand `testCase` behavior for types, that don't support bslma
99/// allocators:
100/// @code
101/// template<class TYPE>
102/// class StdBslmaTestDriver : public TestDriver<TYPE,
103/// bsltf::StdAllocatorAdaptor<bsl::allocator<TYPE> > >
104/// {
105/// };
106/// @endcode
107/// Finally, run the test for types that use `bslma` and standard allocators:
108/// @code
109/// TestDriver<AllocTestType>::testCase();
110/// StdBslmaTestDriver<StdAllocTestType<bsl::allocator<int> > >::testCase();
111/// @endcode
112/// @}
113/** @} */
114/** @} */
115
116/** @addtogroup bsl
117 * @{
118 */
119/** @addtogroup bsltf
120 * @{
121 */
122/** @addtogroup bsltf_stdallocatoradaptor
123 * @{
124 */
125
126#include <bslscm_version.h>
127
129#include <bslma_isstdallocator.h>
130#include <bslma_bslallocator.h>
131
133#include <bslmf_isconvertible.h>
134#include <bslmf_usesallocator.h>
135#include <bslmf_util.h> // 'forward(V)'
136
137#include <bsls_assert.h>
139#include <bsls_nullptr.h>
140#include <bsls_util.h> // 'forward<T>(V)'
141
142#include <new>
143#include <stddef.h>
144
145#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
146// clang-format off
147// Include version that can be compiled with C++03
148// Generated on Mon Jan 13 08:31:33 2025
149// Command line: sim_cpp11_features.pl bsltf_stdallocatoradaptor.h
150
151# define COMPILING_BSLTF_STDALLOCATORADAPTOR_H
153# undef COMPILING_BSLTF_STDALLOCATORADAPTOR_H
154
155// clang-format on
156#else
157
158
159namespace bsltf {
160
161 // =========================
162 // class StdAllocatorAdaptor
163 // =========================
164
165/// This class template provides the facade of an allocator but mostly
166/// delegates operations to the allocator object (of template parameter
167/// type) it adapts, except that it enables the propagation of the
168/// (stateful) allocator object to constructed elements, if appropriate.
169///
170/// See @ref bsltf_stdallocatoradaptor
171template <class ALLOCATOR>
172class StdAllocatorAdaptor : public ALLOCATOR {
173
174 // PRIVATE TYPES
176
177 // PRIVATE MANIPULATORS
178#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
179
180 /// Create an object of the (template parameter) `ELEMENT_TYPE` at the
181 /// specified `elemAddr`, forwarding the allocator managed by this
182 /// adaptor and the specified (variable number of) `arguments` to the
183 /// corresponding constructor of `ELEMENT_TYPE`.
184 template <class ELEMENT_TYPE, class... Args>
185 void privateConstruct(bsl::true_type,
186 ELEMENT_TYPE *elemAddr,
187 Args&&... arguments);
188
189 /// Create an object of the (template parameter) `ELEMENT_TYPE` at the
190 /// specified `elemAddr`, forwarding the specified (variable number of)
191 /// `arguments` to the corresponding constructor of `ELEMENT_TYPE`.
192 template <class ELEMENT_TYPE, class... Args>
193 void privateConstruct(bsl::false_type,
194 ELEMENT_TYPE *elemAddr,
195 Args&&... arguments);
196
197#endif
198
199 public:
200 // TRAITS
202
203 // PUBLIC TYPES
204 typedef typename ALLOCATOR::size_type size_type;
205 typedef typename ALLOCATOR::difference_type difference_type;
206 typedef typename ALLOCATOR::pointer pointer;
207 typedef typename ALLOCATOR::const_pointer const_pointer;
208 typedef typename ALLOCATOR::reference reference;
209 typedef typename ALLOCATOR::const_reference const_reference;
210 typedef typename ALLOCATOR::value_type value_type;
211
212 /// This nested `struct` template, parameterized by some
213 /// `BDE_OTHER_TYPE`, provides a namespace for an `other` type alias,
214 /// which is an allocator type following the same template as this one but that allocates elements of `BDE_OTHER_TYPE`.
215 ///
216 /// \note Note that this
217 /// allocator type is convertible to and from `other` for any
218 /// `BDE_OTHER_TYPE` including `void`.
219 template <class BDE_OTHER_TYPE>
220 struct rebind
221 {
222
223 typedef StdAllocatorAdaptor<
224 typename ALLOCATOR::template rebind<BDE_OTHER_TYPE>::other> other;
225 };
226
227 // CREATORS
228
229 /// Create a standard allocator adaptor object for a default-constructed
230 /// allocator object of the (template parameter) type `ALLOCATOR`.
232
233 /// Create a standard allocator adaptor object for the specified
234 /// `allocator` of the (template parameter) type `ALLOCATOR`.
235 explicit StdAllocatorAdaptor(const ALLOCATOR& allocator);
236
237 /// Create a standard allocator adaptor object from the null pointer
238 /// constant.
240
241 /// Create a copy of the specified `other` allocator adaptor.
242 template <class ANY_TYPE>
244
245#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
246 /// Create a copy of the specified `original` allocator adaptor.
247 StdAllocatorAdaptor(const StdAllocatorAdaptor& original) = default;
248#else
249 StdAllocatorAdaptor(const StdAllocatorAdaptor& original) = default;
250#endif
251
253 // Destroy this object.
254
255 // MANIPULATORS
256#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
257 /// Assign to this object the value of the specified `rhs` object, and
258 /// return a reference providing modifiable access to this object.
260 default;
261#else
263 default;
264#endif
265
266#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
267
268 /// Construct an object of the (template parameter) `ELEMENT_TYPE`, by
269 /// forwarding the allocator instance associated with this allocator
270 /// adaptor, if appropriate, and the specified (variable number of)
271 /// `arguments` to the corresponding constructor of `ELEMENT_TYPE`, at
272 /// the specified uninitialized memory `address`.
273 ///
274 /// \pre The behavior is undefined unless `address` is properly aligned for objects of
275 /// `ELEMENT_TYPE`.
276 template <class ELEMENT_TYPE, class... Args>
277 void construct(ELEMENT_TYPE *address, Args&&... arguments);
278#endif
279
280 // ACCESSORS
281
282 /// Return a reference to the non-modifiable allocator instance
283 /// associated with this standard allocator adaptor.
284 const ALLOCATOR& allocator() const;
285
286 /// Return an allocator adaptor for the allocator object returned by the
287 /// @ref select_on_container_copy_construction class method in the
288 /// `allocator_traits` class template for the allocator object, of the
289 /// (template parameter) type `ALLOCATOR`, associated with this adaptor.
290 /// The `allocator_traits` class template presumably delegates this call
291 /// to the allocator object if such an operation is supported by the
292 /// `ALLOCATOR` type, or provides a suitable default behavior if such an
293 /// operation is not supported.
296};
297
298// FREE OPERATORS
299
300/// Return `true` if the specified `lhs` and `rhs` adaptors are equal and
301/// `false` otherwise. Two allocator adaptor instances are equal if their
302/// associated allocator instances are equal.
303template <class TYPE1, class TYPE2>
304bool operator==(const StdAllocatorAdaptor<TYPE1>& lhs,
305 const StdAllocatorAdaptor<TYPE2>& rhs);
306
307/// Return `true` if the specified `lhs` and `rhs` adaptors are not equal
308/// and `false` otherwise. Two allocator adaptor instances are not equal if
309/// their associated allocator instances are not equal.
310template <class TYPE1, class TYPE2>
311bool operator!=(const StdAllocatorAdaptor<TYPE1>& lhs,
312 const StdAllocatorAdaptor<TYPE2>& rhs);
313
314// ============================================================================
315// INLINE DEFINITIONS
316// ============================================================================
317
318 // -------------------------
319 // class StdAllocatorAdaptor
320 // -------------------------
321
322// PRIVATE MANIPULATORS
323#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
324template <class ALLOCATOR>
325template <class ELEMENT_TYPE, class... Args>
326inline
329 ELEMENT_TYPE *address,
330 Args&&... arguments)
331{
332 AllocatorTraits::construct(
333 *this,
334 address,
335 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...,
336 *this);
337}
338
339template <class ALLOCATOR>
340template <class ELEMENT_TYPE, class... Args>
341inline
342void StdAllocatorAdaptor<ALLOCATOR>::privateConstruct(
344 ELEMENT_TYPE *address,
345 Args&&... arguments)
346{
347 AllocatorTraits::construct(
348 *this, address, BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
349}
350
351#endif
352
353// CREATORS
354template <class ALLOCATOR>
355inline
360
361template <class ALLOCATOR>
362inline
364: ALLOCATOR(allocator)
365{
366}
367
368template <class ALLOCATOR>
369inline
374
375template <class ALLOCATOR>
376template <class ANY_TYPE>
377inline
383
384// MANIPULATORS
385#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
386template <class ALLOCATOR>
387template <class ELEMENT_TYPE, class... Args>
388inline void
390 Args&&... arguments)
391{
392 // If 'ELEMENT_TYPE' can use this allocator, then pass this allocator as at
393 // the end of the constructor argument list. However, if this
394 // instantiation of 'StdAllocatorAdaptor' is derived from 'bsl::allocator',
395 // then this extra argument will passed automatically by
396 // 'bsl::allocator::construct' and should not be added by
397 // 'privateConstruct'. Thus 'k_PassSelfAtEnd' is 'true' if 'ELEMENT_TYPE'
398 // uses this allocator but does NOT use 'bsl::allocator'.
399 enum { k_PassSelfAtEnd =
403 };
404
405 privateConstruct(
406 bsl::integral_constant<bool, (bool) k_PassSelfAtEnd>(),
407 address,
408 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
409}
410#endif
411
412// ACCESSORS
413template <class ALLOCATOR>
414inline
416{
417 return *this;
418}
419
420template <class ALLOCATOR>
421inline
424{
426 AllocatorTraits::select_on_container_copy_construction(
427 *reinterpret_cast<const ALLOCATOR *>(this)));
428}
429
430// FREE OPERATORS
431template <class TYPE1, class TYPE2>
432inline
433bool operator==(const bsltf::StdAllocatorAdaptor<TYPE1>& lhs,
435{
436 return lhs.allocator() == rhs.allocator();
437}
438
439template <class TYPE1, class TYPE2>
440inline
441bool operator!=(const bsltf::StdAllocatorAdaptor<TYPE1>& lhs,
443{
444 return lhs.allocator() != rhs.allocator();
445}
446
447} // close package namespace
448
449
450#endif // End C++11 code
451
452#endif
453
454// ----------------------------------------------------------------------------
455// Copyright 2016 Bloomberg Finance L.P.
456//
457// Licensed under the Apache License, Version 2.0 (the "License");
458// you may not use this file except in compliance with the License.
459// You may obtain a copy of the License at
460//
461// http://www.apache.org/licenses/LICENSE-2.0
462//
463// Unless required by applicable law or agreed to in writing, software
464// distributed under the License is distributed on an "AS IS" BASIS,
465// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
466// See the License for the specific language governing permissions and
467// limitations under the License.
468// ----------------------------- END-OF-FILE ----------------------------------
469
470/** @} */
471/** @} */
472/** @} */
Definition bslma_bslallocator.h:588
Definition bsltf_stdallocatoradaptor.h:172
ALLOCATOR::size_type size_type
Definition bsltf_stdallocatoradaptor.h:204
const ALLOCATOR & allocator() const
Definition bsltf_stdallocatoradaptor.h:415
BSLMF_NESTED_TRAIT_DECLARATION(StdAllocatorAdaptor, bslma::IsStdAllocator)
StdAllocatorAdaptor< ALLOCATOR > select_on_container_copy_construction() const
Definition bsltf_stdallocatoradaptor.h:423
void construct(ELEMENT_TYPE *address, Args &&... arguments)
Definition bsltf_stdallocatoradaptor.h:389
ALLOCATOR::difference_type difference_type
Definition bsltf_stdallocatoradaptor.h:205
ALLOCATOR::reference reference
Definition bsltf_stdallocatoradaptor.h:208
StdAllocatorAdaptor & operator=(const StdAllocatorAdaptor &rhs)=default
ALLOCATOR::pointer pointer
Definition bsltf_stdallocatoradaptor.h:206
ALLOCATOR::const_reference const_reference
Definition bsltf_stdallocatoradaptor.h:209
StdAllocatorAdaptor()
Definition bsltf_stdallocatoradaptor.h:356
ALLOCATOR::value_type value_type
Definition bsltf_stdallocatoradaptor.h:210
ALLOCATOR::const_pointer const_pointer
Definition bsltf_stdallocatoradaptor.h:207
StdAllocatorAdaptor(const StdAllocatorAdaptor &original)=default
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:283
Definition bsltf_allocargumenttype.h:92
Definition bslma_allocatortraits.h:1089
Definition bslmf_isconvertible.h:875
Definition bslmf_usesallocator.h:165
Definition bslma_isstdallocator.h:202
Definition bsltf_stdallocatoradaptor.h:221
StdAllocatorAdaptor< typename ALLOCATOR::template rebind< BDE_OTHER_TYPE >::other > other
Definition bsltf_stdallocatoradaptor.h:224