BDE 4.14.0 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 `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/// `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// Include version that can be compiled with C++03
147// Generated on Thu Oct 21 10:11:37 2021
148// Command line: sim_cpp11_features.pl bsltf_stdallocatoradaptor.h
149# define COMPILING_BSLTF_STDALLOCATORADAPTOR_H
151# undef COMPILING_BSLTF_STDALLOCATORADAPTOR_H
152#else
153
154
155namespace bsltf {
156
157 // =========================
158 // class StdAllocatorAdaptor
159 // =========================
160
161/// This class template provides the facade of an allocator but mostly
162/// delegates operations to the allocator object (of template parameter
163/// type) it adapts, except that it enables the propagation of the
164/// (stateful) allocator object to constructed elements, if appropriate.
165///
166/// See @ref bsltf_stdallocatoradaptor
167template <class ALLOCATOR>
168class StdAllocatorAdaptor : public ALLOCATOR {
169
170 // PRIVATE TYPES
172
173 // PRIVATE MANIPULATORS
174#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
175
176 /// Create an object of the (template parameter) `ELEMENT_TYPE` at the
177 /// specified `elemAddr`, forwarding the allocator managed by this
178 /// adaptor and the specified (variable number of) `arguments` to the
179 /// corresponding constructor of `ELEMENT_TYPE`.
180 template <class ELEMENT_TYPE, class... Args>
181 void privateConstruct(bsl::true_type,
182 ELEMENT_TYPE *elemAddr,
183 Args&&... arguments);
184
185 /// Create an object of the (template parameter) `ELEMENT_TYPE` at the
186 /// specified `elemAddr`, forwarding the specified (variable number of)
187 /// `arguments` to the corresponding constructor of `ELEMENT_TYPE`.
188 template <class ELEMENT_TYPE, class... Args>
189 void privateConstruct(bsl::false_type,
190 ELEMENT_TYPE *elemAddr,
191 Args&&... arguments);
192
193#endif
194
195 public:
196 // TRAITS
198
199 // PUBLIC TYPES
200 typedef typename ALLOCATOR::size_type size_type;
201 typedef typename ALLOCATOR::difference_type difference_type;
202 typedef typename ALLOCATOR::pointer pointer;
203 typedef typename ALLOCATOR::const_pointer const_pointer;
204 typedef typename ALLOCATOR::reference reference;
205 typedef typename ALLOCATOR::const_reference const_reference;
206 typedef typename ALLOCATOR::value_type value_type;
207
208 /// This nested `struct` template, parameterized by some
209 /// `BDE_OTHER_TYPE`, provides a namespace for an `other` type alias,
210 /// which is an allocator type following the same template as this one
211 /// but that allocates elements of `BDE_OTHER_TYPE`. Note that this
212 /// allocator type is convertible to and from `other` for any
213 /// `BDE_OTHER_TYPE` including `void`.
214 template <class BDE_OTHER_TYPE>
215 struct rebind
216 {
217
218 typedef StdAllocatorAdaptor<
219 typename ALLOCATOR::template rebind<BDE_OTHER_TYPE>::other> other;
220 };
221
222 // CREATORS
223
224 /// Create a standard allocator adaptor object for a default-constructed
225 /// allocator object of the (template parameter) type `ALLOCATOR`.
227
228 /// Create a standard allocator adaptor object for the specified
229 /// `allocator` of the (template parameter) type `ALLOCATOR`.
230 explicit StdAllocatorAdaptor(const ALLOCATOR& allocator);
231
232 /// Create a standard allocator adaptor object from the null pointer
233 /// constant.
235
236 /// Create a copy of the specified `other` allocator adaptor.
237 template <class ANY_TYPE>
239
240#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
241 /// Create a copy of the specified `original` allocator adaptor.
242 StdAllocatorAdaptor(const StdAllocatorAdaptor& original) = default;
243#else
244 StdAllocatorAdaptor(const StdAllocatorAdaptor& original) = default;
245#endif
246
248 // Destroy this object.
249
250 // MANIPULATORS
251#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
252 /// Assign to this object the value of the specified `rhs` object, and
253 /// return a reference providing modifiable access to this object.
255 default;
256#else
258 default;
259#endif
260
261#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
262
263 /// Construct an object of the (template parameter) `ELEMENT_TYPE`, by
264 /// forwarding the allocator instance associated with this allocator
265 /// adaptor, if appropriate, and the specified (variable number of)
266 /// `arguments` to the corresponding constructor of `ELEMENT_TYPE`, at
267 /// the specified uninitialized memory `address`. The behavior is
268 /// undefined unless `address` is properly aligned for objects of
269 /// `ELEMENT_TYPE`.
270 template <class ELEMENT_TYPE, class... Args>
271 void construct(ELEMENT_TYPE *address, Args&&... arguments);
272#endif
273
274 // ACCESSORS
275
276 /// Return a reference to the non-modifiable allocator instance
277 /// associated with this standard allocator adaptor.
278 const ALLOCATOR& allocator() const;
279
280 /// Return an allocator adaptor for the allocator object returned by the
281 /// `select_on_container_copy_construction` class method in the
282 /// `allocator_traits` class template for the allocator object, of the
283 /// (template parameter) type `ALLOCATOR`, associated with this adaptor.
284 /// The `allocator_traits` class template presumably delegates this call
285 /// to the allocator object if such an operation is supported by the
286 /// `ALLOCATOR` type, or provides a suitable default behavior if such an
287 /// operation is not supported.
290};
291
292// FREE OPERATORS
293
294/// Return `true` if the specified `lhs` and `rhs` adaptors are equal and
295/// `false` otherwise. Two allocator adaptor instances are equal if their
296/// associated allocator instances are equal.
297template <class TYPE1, class TYPE2>
298bool operator==(const StdAllocatorAdaptor<TYPE1>& lhs,
299 const StdAllocatorAdaptor<TYPE2>& rhs);
300
301/// Return `true` if the specified `lhs` and `rhs` adaptors are not equal
302/// and `false` otherwise. Two allocator adaptor instances are not equal if
303/// their associated allocator instances are not equal.
304template <class TYPE1, class TYPE2>
305bool operator!=(const StdAllocatorAdaptor<TYPE1>& lhs,
306 const StdAllocatorAdaptor<TYPE2>& rhs);
307
308// ============================================================================
309// INLINE DEFINITIONS
310// ============================================================================
311
312 // -------------------------
313 // class StdAllocatorAdaptor
314 // -------------------------
315
316// PRIVATE MANIPULATORS
317#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
318template <class ALLOCATOR>
319template <class ELEMENT_TYPE, class... Args>
320inline
323 ELEMENT_TYPE *address,
324 Args&&... arguments)
325{
326 AllocatorTraits::construct(
327 *this,
328 address,
329 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...,
330 *this);
331}
332
333template <class ALLOCATOR>
334template <class ELEMENT_TYPE, class... Args>
335inline
336void StdAllocatorAdaptor<ALLOCATOR>::privateConstruct(
338 ELEMENT_TYPE *address,
339 Args&&... arguments)
340{
341 AllocatorTraits::construct(
342 *this, address, BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
343}
344
345#endif
346
347// CREATORS
348template <class ALLOCATOR>
349inline
354
355template <class ALLOCATOR>
356inline
358: ALLOCATOR(allocator)
359{
360}
361
362template <class ALLOCATOR>
363inline
368
369template <class ALLOCATOR>
370template <class ANY_TYPE>
371inline
377
378// MANIPULATORS
379#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
380template <class ALLOCATOR>
381template <class ELEMENT_TYPE, class... Args>
382inline void
384 Args&&... arguments)
385{
386 // If 'ELEMENT_TYPE' can use this allocator, then pass this allocator as at
387 // the end of the constructor argument list. However, if this
388 // instantiation of 'StdAllocatorAdaptor' is derived from 'bsl::allocator',
389 // then this extra argument will passed automatically by
390 // 'bsl::allocator::construct' and should not be added by
391 // 'privateConstruct'. Thus 'k_PassSelfAtEnd' is 'true' if 'ELEMENT_TYPE'
392 // uses this allocator but does NOT use 'bsl::allocator'.
393 enum { k_PassSelfAtEnd =
397 };
398
399 privateConstruct(
400 bsl::integral_constant<bool, (bool) k_PassSelfAtEnd>(),
401 address,
402 BSLS_COMPILERFEATURES_FORWARD(Args, arguments)...);
403}
404#endif
405
406// ACCESSORS
407template <class ALLOCATOR>
408inline
410{
411 return *this;
412}
413
414template <class ALLOCATOR>
415inline
418{
420 AllocatorTraits::select_on_container_copy_construction(
421 *reinterpret_cast<const ALLOCATOR *>(this)));
422}
423
424// FREE OPERATORS
425template <class TYPE1, class TYPE2>
426inline
427bool operator==(const bsltf::StdAllocatorAdaptor<TYPE1>& lhs,
429{
430 return lhs.allocator() == rhs.allocator();
431}
432
433template <class TYPE1, class TYPE2>
434inline
435bool operator!=(const bsltf::StdAllocatorAdaptor<TYPE1>& lhs,
437{
438 return lhs.allocator() != rhs.allocator();
439}
440
441} // close package namespace
442
443
444#endif // End C++11 code
445
446#endif
447
448// ----------------------------------------------------------------------------
449// Copyright 2016 Bloomberg Finance L.P.
450//
451// Licensed under the Apache License, Version 2.0 (the "License");
452// you may not use this file except in compliance with the License.
453// You may obtain a copy of the License at
454//
455// http://www.apache.org/licenses/LICENSE-2.0
456//
457// Unless required by applicable law or agreed to in writing, software
458// distributed under the License is distributed on an "AS IS" BASIS,
459// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
460// See the License for the specific language governing permissions and
461// limitations under the License.
462// ----------------------------- END-OF-FILE ----------------------------------
463
464/** @} */
465/** @} */
466/** @} */
Definition bslma_bslallocator.h:580
Definition bsltf_stdallocatoradaptor.h:168
ALLOCATOR::size_type size_type
Definition bsltf_stdallocatoradaptor.h:200
const ALLOCATOR & allocator() const
Definition bsltf_stdallocatoradaptor.h:409
BSLMF_NESTED_TRAIT_DECLARATION(StdAllocatorAdaptor, bslma::IsStdAllocator)
StdAllocatorAdaptor< ALLOCATOR > select_on_container_copy_construction() const
Definition bsltf_stdallocatoradaptor.h:417
void construct(ELEMENT_TYPE *address, Args &&... arguments)
Definition bsltf_stdallocatoradaptor.h:383
ALLOCATOR::difference_type difference_type
Definition bsltf_stdallocatoradaptor.h:201
ALLOCATOR::reference reference
Definition bsltf_stdallocatoradaptor.h:204
StdAllocatorAdaptor & operator=(const StdAllocatorAdaptor &rhs)=default
ALLOCATOR::pointer pointer
Definition bsltf_stdallocatoradaptor.h:202
ALLOCATOR::const_reference const_reference
Definition bsltf_stdallocatoradaptor.h:205
StdAllocatorAdaptor()
Definition bsltf_stdallocatoradaptor.h:350
ALLOCATOR::value_type value_type
Definition bsltf_stdallocatoradaptor.h:206
ALLOCATOR::const_pointer const_pointer
Definition bsltf_stdallocatoradaptor.h:203
StdAllocatorAdaptor(const StdAllocatorAdaptor &original)=default
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:281
Definition bsltf_allocargumenttype.h:92
Definition bslma_allocatortraits.h:1061
Definition bslmf_isconvertible.h:867
Definition bslmf_usesallocator.h:165
Definition bslma_isstdallocator.h:201
Definition bsltf_stdallocatoradaptor.h:216
StdAllocatorAdaptor< typename ALLOCATOR::template rebind< BDE_OTHER_TYPE >::other > other
Definition bsltf_stdallocatoradaptor.h:219