BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsltf_stdstatefulallocator.h
Go to the documentation of this file.
1/// @file bsltf_stdstatefulallocator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsltf_stdstatefulallocator.h -*-C++-*-
8#ifndef INCLUDED_BSLTF_STDSTATEFULALLOCATOR
9#define INCLUDED_BSLTF_STDSTATEFULALLOCATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsltf_stdstatefulallocator bsltf_stdstatefulallocator
15/// @brief Provide a minimal standard compliant allocator.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsltf
19/// @{
20/// @addtogroup bsltf_stdstatefulallocator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsltf_stdstatefulallocator-purpose"> Purpose</a>
25/// * <a href="#bsltf_stdstatefulallocator-classes"> Classes </a>
26/// * <a href="#bsltf_stdstatefulallocator-description"> Description </a>
27/// * <a href="#bsltf_stdstatefulallocator-usage"> Usage </a>
28/// * <a href="#bsltf_stdstatefulallocator-example-1-testing-the-support-for-stl-compliant-allocator"> Example 1: Testing The Support for STL-Compliant Allocator </a>
29///
30/// # Purpose {#bsltf_stdstatefulallocator-purpose}
31/// Provide a minimal standard compliant allocator.
32///
33/// # Classes {#bsltf_stdstatefulallocator-classes}
34///
35/// - bsltf::StdStatefulAllocator: standard compliant allocator managing state
36///
37/// @see bsltf_stdtestallocator
38///
39/// # Description {#bsltf_stdstatefulallocator-description}
40/// This component provides an allocator,
41/// `bsltf::StdStatefulAllocator`, that defines the minimal interface to comply
42/// with section 17.6.3.5 ([allocator.requirements]) of the C++11 standard,
43/// while still providing an externally visible and potentially distinct state
44/// for each allocator object. This type can be used to verify that constructs
45/// designed to support a standard-compliant allocator access the allocator only
46/// through the standard-defined interface.
47///
48/// `StdStatefulAllocator` delegates its operations to the allocator passed at
49/// construction (or the default allocator if no allocator is passed) that is
50/// also the sole attribute of this class. In most tests, a
51/// `bslma::TestAllocator` will be passed.
52///
53/// The key differences between this test allocator and a regular BDE allocator
54/// are:
55///
56/// * This allocator does not support the `scoped` allocation model, so that
57/// elements in a container will often have a different allocator to the
58/// container object itself.
59/// * This allocator may propagate through copy operations, move operations
60/// and `swap` operations, depending on how the template is configured as
61/// it is instantiated.
62///
63/// ## Usage {#bsltf_stdstatefulallocator-usage}
64///
65///
66/// This section illustrates intended use of this component.
67///
68/// ### Example 1: Testing The Support for STL-Compliant Allocator {#bsltf_stdstatefulallocator-example-1-testing-the-support-for-stl-compliant-allocator}
69///
70///
71/// In this example we will verify that a type supports the use of a
72/// STL-compliant allocator.
73///
74/// First, we define a simple container type intended to be used with a C++11
75/// standard compliant allocator:
76/// @code
77/// template <class TYPE, class ALLOCATOR>
78/// class MyContainer {
79/// // This container type is parameterized on a standard allocator type
80/// // and contains a single object, always initialized, which can be
81/// // replaced and accessed.
82///
83/// // DATA MEMBERS
84/// ALLOCATOR d_allocator; // allocator used to supply memory (held, not
85/// // owned)
86///
87/// TYPE *d_object_p; // pointer to the contained object
88///
89/// public:
90/// // CREATORS
91/// MyContainer(const TYPE& object, const ALLOCATOR& allocator);
92/// // Create an container containing the specified 'object', using the
93/// // specified 'allocator' to supply memory.
94///
95/// ~MyContainer();
96/// // Destroy this container.
97///
98/// // MANIPULATORS
99/// TYPE& object();
100/// // Return a reference providing modifiable access to the object
101/// // contained in this container.
102///
103/// // ACCESSORS
104/// const TYPE& object() const;
105/// // Return a reference providing non-modifiable access to the object
106/// // contained in this container.
107/// };
108/// @endcode
109/// Then, we define the member functions of `MyContainer`:
110/// @code
111/// // CREATORS
112/// template <class TYPE, class ALLOCATOR>
113/// MyContainer<TYPE, ALLOCATOR>::MyContainer(const TYPE& object,
114/// const ALLOCATOR& allocator)
115/// : d_allocator(allocator)
116/// {
117/// d_object_p = d_allocator.allocate(1);
118/// new (static_cast<void *>(d_object_p)) TYPE(object);
119/// }
120///
121/// template <class TYPE, class ALLOCATOR>
122/// MyContainer<TYPE, ALLOCATOR>::~MyContainer()
123/// {
124/// d_object_p->~TYPE();
125/// d_allocator.deallocate(d_object_p, 1);
126/// }
127///
128/// // MANIPULATORS
129/// template <class TYPE, class ALLOCATOR>
130/// TYPE& MyContainer<TYPE, ALLOCATOR>::object()
131/// {
132/// return *d_object_p;
133/// }
134///
135/// // ACCESSORS
136/// template <class TYPE, class ALLOCATOR>
137/// const TYPE& MyContainer<TYPE, ALLOCATOR>::object() const
138/// {
139/// return *d_object_p;
140/// }
141/// @endcode
142/// Now, we use `bsltf::StdStatefulAllocator` to implement a simple test for
143/// `MyContainer` to verify it correctly uses a parameterized allocator using
144/// only the C++11 standard methods:
145/// @code
146/// bslma::TestAllocator oa("object", veryVeryVeryVerbose);
147/// {
148/// typedef MyContainer<int, bsltf::StdStatefulAllocator<int> > Obj;
149///
150/// Obj mX(2, bsltf::StdStatefulAllocator<int>(&oa));
151/// const Obj& X = mX;
152/// assert(sizeof(int) == oa.numBytesInUse());
153///
154/// assert(X.object() == 2);
155///
156/// mX.object() = -10;
157/// assert(X.object() == -10);
158/// }
159///
160/// assert(0 == oa.numBytesInUse());
161/// @endcode
162/// @}
163/** @} */
164/** @} */
165
166/** @addtogroup bsl
167 * @{
168 */
169/** @addtogroup bsltf
170 * @{
171 */
172/** @addtogroup bsltf_stdstatefulallocator
173 * @{
174 */
175
176#include <bslscm_version.h>
177
178#include <bslma_allocator.h>
179#include <bslma_default.h>
180#include <bslma_isstdallocator.h>
181
182#include <bslmf_assert.h>
184#include <bslmf_issame.h>
185#include <bslmf_util.h> // 'forward(V)'
186
189#include <bsls_util.h> // 'forward<T>(V)'
190
191#include <new>
192
193#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
194// clang-format off
195// Include version that can be compiled with C++03
196// Generated on Mon Jan 13 08:31:33 2025
197// Command line: sim_cpp11_features.pl bsltf_stdstatefulallocator.h
198
199# define COMPILING_BSLTF_STDSTATEFULALLOCATOR_H
201# undef COMPILING_BSLTF_STDSTATEFULALLOCATOR_H
202
203// clang-format on
204#else
205
206
207namespace bsltf {
208
209 // ==========================
210 // class StdStatefulAllocator
211 // ==========================
212
213/// This allocator implements the minimal interface to comply with section
214/// 17.6.3.5 ([allocator.requirements]) of the C++11 standard, while
215/// maintaining a distinct object state - in this case a wrapped pointer to
216/// a `bslma::Allocator`. The template is configurable to control its
217/// allocator propagation properties, but does not support the BDE "scoped"
218/// allocator model, as scoped allocators should never propagate. Instances
219/// of this allocator delegate their operations to the wrapped allocator that constitutes its state.
220///
221/// \note Note that while we define the various
222/// traits used by the C++11 allocator traits facility, they actually mean
223/// very little for this component, as it is the consumer of the allocator's
224/// responsibility to check and apply the traits correctly, typically by
225/// using `bsl::allocator_traits` to perform all memory allocation tasks
226/// rather than using the allocator directly. The
227/// `PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION` flag is consumed directly
228/// though, in the static member function
229/// @ref select_on_container_copy_construction .
230///
231/// See @ref bsltf_stdstatefulallocator
232template <class TYPE,
233 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION = true,
234 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT = true,
235 bool PROPAGATE_ON_CONTAINER_SWAP = true,
236 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT = true,
237 bool IS_ALWAYS_EQUAL = false>
239
240 private:
241 // DATA
242 bslma::Allocator *d_allocator_p; // the wrapped allocator (held, not
243 // owned)
244
245 public:
246 // TRAITS
249
250 // PUBLIC TYPES
251 typedef TYPE value_type;
252
253 // For a minimal allocator, these should all be deducible for a C++11
254 // container implementation. Unfortunately, the C++03 implementation of
255 // 'allocator_traits' supported by BDE does not try the leaps of template
256 // metaprogramming necessary to deduce these types. That is left for a
257 // future C++11 implementation, where language makes such metaprograms
258 // much simpler to write.
259
260#if !defined(BSLSTL_ALLOCATOR_TRAITS_SUPPORTS_ALL_CPP11_DEDUCTIONS)
261 typedef std::size_t size_type;
262 typedef std::ptrdiff_t difference_type;
263 typedef TYPE *pointer;
264 typedef const TYPE *const_pointer;
265#endif
266
267 typedef bsl::integral_constant<bool,
268 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT>
270
273
274 typedef bsl::integral_constant<bool,
275 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT>
277
278 typedef bsl::integral_constant<bool,
279 IS_ALWAYS_EQUAL>
281
282 /// This nested `struct` template, parameterized by some
283 /// `BDE_OTHER_TYPE`, provides a namespace for an `other` type alias,
284 /// which is an allocator type following the same template as this one but that allocates elements of `BDE_OTHER_TYPE`.
285 ///
286 /// \note Note that this
287 /// allocator type is convertible to and from `other` for any
288 /// `BDE_OTHER_TYPE` including `void`.
289 template <class BDE_OTHER_TYPE>
290 struct rebind
291 {
292
293 typedef StdStatefulAllocator<
294 BDE_OTHER_TYPE,
295 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
296 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
297 PROPAGATE_ON_CONTAINER_SWAP,
298 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
299 IS_ALWAYS_EQUAL> other;
300 };
301
302 // CREATORS
303
304 /// Create a `StdStatefulAllocator` object wrapping the specified
305 /// `allocator`.
307
308 StdStatefulAllocator(const StdStatefulAllocator& original) = default;
309 // Create an allocator having the same value as the specified
310 // 'original' object.
311
312 /// Create a `StdStatefulAllocator` object wrapping the same test
313 /// allocator as the specified `original`.
314 template <class BDE_OTHER_TYPE>
316 BDE_OTHER_TYPE,
317 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
318 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
319 PROPAGATE_ON_CONTAINER_SWAP,
320 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
321 IS_ALWAYS_EQUAL>& original);
322
324 // Destroy this object.
325
326 // MANIPULATORS
328 operator=(const StdStatefulAllocator& rhs) = default;
329 // Assign to this object the value of the specified 'rhs' object, and
330 // return a reference providing modifiable access to this object.
331
332 /// Allocate enough (properly aligned) space for the specified
333 /// `numElements` of the (template parameter) type `TYPE`. If the
334 /// underlying `bslma::Allocator` is unable to fulfill the allocation
335 /// request, an exception (typically `bsl::bad_alloc`) will be thrown.
336 TYPE *allocate(bslma::Allocator::size_type numElements);
337
338#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
339
340 /// Construct an object of the (template parameter) `ELEMENT_TYPE`, by
341 /// forwarding the specified (variable number of) `arguments` to the
342 /// corresponding constructor of `ELEMENT_TYPE`, at the specified uninitialized memory `address`.
343 ///
344 /// \pre The behavior is undefined unless
345 /// `address` is properly aligned for objects of `ELEMENT_TYPE`.
346 template <class ELEMENT_TYPE, class... Args>
347 void construct(ELEMENT_TYPE *address, Args&&... arguments);
348#endif
349
350 /// Return memory previously allocated at the specified `address` for
351 /// `numElements` back to this allocator. The `numElements` argument is ignored by this allocator type.
352 ///
353 /// \pre The behavior is undefined unless
354 /// `address` was allocated using this allocator object and has not
355 /// already been deallocated.
356 void deallocate(TYPE *address, bslma::Allocator::size_type numElements);
357
358 /// Invoke the `ELEMENT_TYPE` destructor for the object at the specified
359 /// `address`.
360 template <class ELEMENT_TYPE>
361 void destroy(ELEMENT_TYPE *address);
362
363 // ACCESSORS
364#if !defined(BSLSTL_ALLOCATOR_TRAITS_SUPPORTS_ALL_CPP11_DEDUCTIONS)
365 /// Return the maximum number of elements of type `TYPE` that can be
366 /// allocated using this allocator in a single call to the `allocate` method.
367 ///
368 /// \note Note that there is no guarantee that attempts at allocating
369 /// less elements than the value returned by @ref max_size will not throw.
370 /// *** DO NOT RELY ON THE CONTINUING PRESENT OF THIS METHOD *** THIS
371 /// METHOD WILL BE REMOVED ONCE `bslstl::allocator_traits` PROPERLY
372 /// DEDUCES AN IMPLEMENTATION FOR THIS FUNCTION WHEN NOT SUPPLIED BY THE
373 /// ALLOCATOR DIRECTLY.
374 size_type max_size() const;
375#endif
376
377 /// Return a copy of this object if the `bool` template parameter
378 /// `PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION` is true, and a copy of a
379 /// `StdStatefulAllocator` object wrapping the default allocator
380 /// otherwise.
382
383 /// Return the address of the allocator wrapped by this object.
385};
386
387// FREE OPERATORS
388
389/// Return `true` if the specified `lhs` and `rhs` have the same underlying
390/// test allocator, and `false` otherwise.
391template <class TYPE1,
392 class TYPE2,
393 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
394 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
395 bool PROPAGATE_ON_CONTAINER_SWAP,
396 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
397 bool IS_ALWAYS_EQUAL>
398bool operator==(const StdStatefulAllocator<
399 TYPE1,
400 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
401 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
402 PROPAGATE_ON_CONTAINER_SWAP,
403 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
404 IS_ALWAYS_EQUAL>& lhs,
406 TYPE2,
407 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
408 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
409 PROPAGATE_ON_CONTAINER_SWAP,
410 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
411 IS_ALWAYS_EQUAL>& rhs);
412
413/// Return `true` if the specified `lhs` and `rhs` have different underlying
414/// test allocators, and `false` otherwise.
415template <class TYPE1,
416 class TYPE2,
417 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
418 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
419 bool PROPAGATE_ON_CONTAINER_SWAP,
420 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
421 bool IS_ALWAYS_EQUAL>
422bool operator!=(const StdStatefulAllocator<
423 TYPE1,
424 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
425 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
426 PROPAGATE_ON_CONTAINER_SWAP,
427 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
428 IS_ALWAYS_EQUAL>& lhs,
430 TYPE2,
431 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
432 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
433 PROPAGATE_ON_CONTAINER_SWAP,
434 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
435 IS_ALWAYS_EQUAL>& rhs);
436
437
438// ============================================================================
439// INLINE DEFINITIONS
440// ============================================================================
441
442 // --------------------------
443 // class StdStatefulAllocator
444 // --------------------------
445
446// CREATORS
447template <class TYPE,
448 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
449 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
450 bool PROPAGATE_ON_CONTAINER_SWAP,
451 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
452 bool IS_ALWAYS_EQUAL>
453inline
455 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
456 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
457 PROPAGATE_ON_CONTAINER_SWAP,
458 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
459 IS_ALWAYS_EQUAL>::
460StdStatefulAllocator(bslma::Allocator *allocator)
461: d_allocator_p(bslma::Default::allocator(allocator))
462{
463}
464
465template <class TYPE,
466 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
467 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
468 bool PROPAGATE_ON_CONTAINER_SWAP,
469 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
470 bool IS_ALWAYS_EQUAL>
471template <class BDE_OTHER_TYPE>
472inline
474 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
475 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
476 PROPAGATE_ON_CONTAINER_SWAP,
477 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
478 IS_ALWAYS_EQUAL>::
479StdStatefulAllocator(const StdStatefulAllocator<
480 BDE_OTHER_TYPE,
481 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
482 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
483 PROPAGATE_ON_CONTAINER_SWAP,
484 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
485 IS_ALWAYS_EQUAL>& original)
486: d_allocator_p(original.allocator())
487{
488}
489
490// MANIPULATORS
491template <class TYPE,
492 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
493 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
494 bool PROPAGATE_ON_CONTAINER_SWAP,
495 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
496 bool IS_ALWAYS_EQUAL>
497inline
498TYPE *
500 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
501 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
502 PROPAGATE_ON_CONTAINER_SWAP,
503 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
504 IS_ALWAYS_EQUAL>::allocate(
505 bslma::Allocator::size_type numElements)
506{
507 if (numElements > this->max_size()) {
508 BloombergLP::bsls::BslExceptionUtil::throwBadAlloc();
509 }
510
511 return static_cast<TYPE *>(d_allocator_p->allocate(
512 bslma::Allocator::size_type(numElements * sizeof(TYPE))));
513}
514
515#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
516template <class TYPE,
517 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
518 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
519 bool PROPAGATE_ON_CONTAINER_SWAP,
520 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
521 bool IS_ALWAYS_EQUAL>
522template <class ELEMENT_TYPE, class... Args>
523inline
524void
526 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
527 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
528 PROPAGATE_ON_CONTAINER_SWAP,
529 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
530 IS_ALWAYS_EQUAL>::construct(
531 ELEMENT_TYPE *address, Args&&... arguments)
532{
533 ::new (static_cast<void*>(address)) ELEMENT_TYPE(
534 BSLS_COMPILERFEATURES_FORWARD(Args,arguments)...);
535}
536#endif
537
538template <class TYPE,
539 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
540 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
541 bool PROPAGATE_ON_CONTAINER_SWAP,
542 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
543 bool IS_ALWAYS_EQUAL>
544inline
545void StdStatefulAllocator<TYPE,
546 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
547 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
548 PROPAGATE_ON_CONTAINER_SWAP,
549 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
550 IS_ALWAYS_EQUAL>::
551deallocate(TYPE *address, bslma::Allocator::size_type)
552{
553 d_allocator_p->deallocate(address);
554}
555
556template <class TYPE,
557 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
558 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
559 bool PROPAGATE_ON_CONTAINER_SWAP,
560 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
561 bool IS_ALWAYS_EQUAL>
562template <class ELEMENT_TYPE>
563inline
564void StdStatefulAllocator<TYPE,
565 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
566 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
567 PROPAGATE_ON_CONTAINER_SWAP,
568 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
569 IS_ALWAYS_EQUAL>::destroy(
570 ELEMENT_TYPE * address)
571{
572 address->~ELEMENT_TYPE();
573}
574
575template <class TYPE,
576 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
577 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
578 bool PROPAGATE_ON_CONTAINER_SWAP,
579 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
580 bool IS_ALWAYS_EQUAL>
581inline
582typename StdStatefulAllocator<
583 TYPE,
584 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
585 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
586 PROPAGATE_ON_CONTAINER_SWAP,
587 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
588 IS_ALWAYS_EQUAL>::size_type
590 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
591 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
592 PROPAGATE_ON_CONTAINER_SWAP,
593 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
594 IS_ALWAYS_EQUAL>::
595max_size() const
596{
597 // Return the largest value, 'v', such that 'v * sizeof(T)' fits in a
598 // 'size_type' (copied from bslstl_allocator).
599
600 // We will calculate MAX_NUM_BYTES based on our knowledge that
601 // 'bslma::Allocator::size_type' is just an alias for 'std::size_t'. First
602 // demonstrate that is true:
603
604 BSLMF_ASSERT((bsl::is_same<BloombergLP::bslma::Allocator::size_type,
605 std::size_t>::value));
606
607 static const std::size_t MAX_NUM_BYTES = ~std::size_t(0);
608 static const std::size_t MAX_NUM_ELEMENTS =
609 std::size_t(MAX_NUM_BYTES) / sizeof(TYPE);
610 return MAX_NUM_ELEMENTS;
611}
612
613template <class TYPE,
614 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
615 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
616 bool PROPAGATE_ON_CONTAINER_SWAP,
617 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
618 bool IS_ALWAYS_EQUAL>
619inline
621 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
622 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
623 PROPAGATE_ON_CONTAINER_SWAP,
624 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
625 IS_ALWAYS_EQUAL>
627 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
628 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
629 PROPAGATE_ON_CONTAINER_SWAP,
630 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
631 IS_ALWAYS_EQUAL>::
632select_on_container_copy_construction() const
633{
634 if (PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION) {
635 return *this; // RETURN
636 }
637
638 // else
639
641}
642
643template <class TYPE,
644 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
645 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
646 bool PROPAGATE_ON_CONTAINER_SWAP,
647 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
648 bool IS_ALWAYS_EQUAL>
649inline
652 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
653 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
654 PROPAGATE_ON_CONTAINER_SWAP,
655 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
656 IS_ALWAYS_EQUAL>::
657allocator() const
658{
659 return d_allocator_p;
660}
661
662} // close package namespace
663
664// FREE OPERATORS
665template <class TYPE1,
666 class TYPE2,
667 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
668 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
669 bool PROPAGATE_ON_CONTAINER_SWAP,
670 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
671 bool IS_ALWAYS_EQUAL>
672inline
673bool bsltf::operator==(const StdStatefulAllocator<
674 TYPE1,
675 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
676 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
677 PROPAGATE_ON_CONTAINER_SWAP,
678 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
679 IS_ALWAYS_EQUAL>& lhs,
680 const StdStatefulAllocator<
681 TYPE2,
682 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
683 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
684 PROPAGATE_ON_CONTAINER_SWAP,
685 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
686 IS_ALWAYS_EQUAL>& rhs)
687{
688 return IS_ALWAYS_EQUAL || (lhs.allocator() == rhs.allocator());
689}
690
691template <class TYPE1,
692 class TYPE2,
693 bool PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
694 bool PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
695 bool PROPAGATE_ON_CONTAINER_SWAP,
696 bool PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
697 bool IS_ALWAYS_EQUAL>
698inline
699bool bsltf::operator!=(const StdStatefulAllocator<
700 TYPE1,
701 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
702 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
703 PROPAGATE_ON_CONTAINER_SWAP,
704 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
705 IS_ALWAYS_EQUAL>& lhs,
706 const StdStatefulAllocator<
707 TYPE2,
708 PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION,
709 PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT,
710 PROPAGATE_ON_CONTAINER_SWAP,
711 PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT,
712 IS_ALWAYS_EQUAL>& rhs)
713{
714 return !IS_ALWAYS_EQUAL && (lhs.allocator() != rhs.allocator());
715}
716
717
718
719#endif // End C++11 code
720
721#endif
722
723// ----------------------------------------------------------------------------
724// Copyright 2013 Bloomberg Finance L.P.
725//
726// Licensed under the Apache License, Version 2.0 (the "License");
727// you may not use this file except in compliance with the License.
728// You may obtain a copy of the License at
729//
730// http://www.apache.org/licenses/LICENSE-2.0
731//
732// Unless required by applicable law or agreed to in writing, software
733// distributed under the License is distributed on an "AS IS" BASIS,
734// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
735// See the License for the specific language governing permissions and
736// limitations under the License.
737// ----------------------------- END-OF-FILE ----------------------------------
738
739/** @} */
740/** @} */
741/** @} */
Definition bslma_allocator.h:545
std::size_t size_type
Definition bslma_allocator.h:593
Definition bsltf_stdstatefulallocator.h:238
std::ptrdiff_t difference_type
Definition bsltf_stdstatefulallocator.h:262
bslma::Allocator * allocator() const
Return the address of the allocator wrapped by this object.
Definition bsltf_stdstatefulallocator.h:657
bsl::integral_constant< bool, PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT > propagate_on_container_move_assignment
Definition bsltf_stdstatefulallocator.h:276
StdStatefulAllocator select_on_container_copy_construction() const
Definition bsltf_stdstatefulallocator.h:632
TYPE * allocate(bslma::Allocator::size_type numElements)
Definition bsltf_stdstatefulallocator.h:504
bsl::integral_constant< bool, PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT > propagate_on_container_copy_assignment
Definition bsltf_stdstatefulallocator.h:269
const TYPE * const_pointer
Definition bsltf_stdstatefulallocator.h:264
StdStatefulAllocator(const StdStatefulAllocator &original)=default
std::size_t size_type
Definition bsltf_stdstatefulallocator.h:261
TYPE value_type
Definition bsltf_stdstatefulallocator.h:251
bsl::integral_constant< bool, PROPAGATE_ON_CONTAINER_SWAP > propagate_on_container_swap
Definition bsltf_stdstatefulallocator.h:272
void destroy(ELEMENT_TYPE *address)
Definition bsltf_stdstatefulallocator.h:569
void construct(ELEMENT_TYPE *address, Args &&... arguments)
Definition bsltf_stdstatefulallocator.h:530
BSLMF_NESTED_TRAIT_DECLARATION(StdStatefulAllocator, bslma::IsStdAllocator)
StdStatefulAllocator & operator=(const StdStatefulAllocator &rhs)=default
bsl::integral_constant< bool, IS_ALWAYS_EQUAL > is_always_equal
Definition bsltf_stdstatefulallocator.h:280
void deallocate(TYPE *address, bslma::Allocator::size_type numElements)
Definition bsltf_stdstatefulallocator.h:551
size_type max_size() const
Definition bsltf_stdstatefulallocator.h:595
TYPE * pointer
Definition bsltf_stdstatefulallocator.h:263
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#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
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition baljsn_encoder_testtypes.h:76
Definition bsltf_allocargumenttype.h:92
bool operator!=(const AllocBitwiseMoveableTestType &lhs, const AllocBitwiseMoveableTestType &rhs)
bool operator==(const AllocBitwiseMoveableTestType &lhs, const AllocBitwiseMoveableTestType &rhs)
Definition bdldfp_decimal.h:5549
Definition bslmf_integralconstant.h:261
Definition bslmf_issame.h:146
static Allocator * defaultAllocator()
Definition bslma_default.h:905
Definition bslma_isstdallocator.h:202
Definition bsltf_stdstatefulallocator.h:291
StdStatefulAllocator< BDE_OTHER_TYPE, PROPAGATE_ON_CONTAINER_COPY_CONSTRUCTION, PROPAGATE_ON_CONTAINER_COPY_ASSIGNMENT, PROPAGATE_ON_CONTAINER_SWAP, PROPAGATE_ON_CONTAINER_MOVE_ASSIGNMENT, IS_ALWAYS_EQUAL > other
Definition bsltf_stdstatefulallocator.h:299