BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_bidirectionalnodepool.h
Go to the documentation of this file.
1/// @file bslstl_bidirectionalnodepool.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_bidirectionalnodepool.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_BIDIRECTIONALNODEPOOL
9#define INCLUDED_BSLSTL_BIDIRECTIONALNODEPOOL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_bidirectionalnodepool bslstl_bidirectionalnodepool
15/// @brief Provide efficient creation of nodes used in a node-based container.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_bidirectionalnodepool
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_bidirectionalnodepool-purpose"> Purpose</a>
25/// * <a href="#bslstl_bidirectionalnodepool-classes"> Classes </a>
26/// * <a href="#bslstl_bidirectionalnodepool-description"> Description </a>
27/// * <a href="#bslstl_bidirectionalnodepool-memory-allocation"> Memory Allocation </a>
28/// * <a href="#bslstl_bidirectionalnodepool-usage"> Usage </a>
29/// * <a href="#bslstl_bidirectionalnodepool-example-1-creating-a-linked-list-container"> Example 1: Creating a Linked List Container </a>
30///
31/// # Purpose {#bslstl_bidirectionalnodepool-purpose}
32/// Provide efficient creation of nodes used in a node-based container.
33///
34/// # Classes {#bslstl_bidirectionalnodepool-classes}
35///
36/// - bslstl::BidirectionalNodePool: memory manager to allocate hash table nodes
37///
38/// @see bslstl_simplepool
39///
40/// # Description {#bslstl_bidirectionalnodepool-description}
41/// This component implements a mechanism, `BidirectionalNodePool`,
42/// that creates and destroys `bslalg::BidirectionalListNode` objects holding
43/// objects of a (template parameter) type `VALUE` for use in hash-table-based
44/// containers.
45///
46/// A `BidirectionalNodePool` uses a memory pool provided by the
47/// @ref bslstl_simplepool component in its implementation to provide memory for
48/// the nodes (see @ref bslstl_simplepool ).
49///
50/// ## Memory Allocation {#bslstl_bidirectionalnodepool-memory-allocation}
51///
52///
53/// `BidirectionalNodePool` uses an allocator of the (template parameter) type
54/// `ALLOCATOR` specified at construction to allocate memory.
55/// `BidirectionalNodePool` supports allocators meeting the requirements of the
56/// C++ standard allocator requirements ([allocator.requirements], C++11
57/// 17.6.3.5).
58///
59/// If `ALLOCATOR` is `bsl::allocator` and the (template parameter) type `VALUE`
60/// defines the `bslma::UsesBslmaAllocator` trait, then the `bslma::Allocator`
61/// object specified at construction will be supplied to constructors of the
62/// (template parameter) type `VALUE` in the `cloneNode` method and
63/// `emplaceIntoNewNode` method overloads.
64///
65/// ## Usage {#bslstl_bidirectionalnodepool-usage}
66///
67///
68/// This section illustrates intended use of this component.
69///
70/// ### Example 1: Creating a Linked List Container {#bslstl_bidirectionalnodepool-example-1-creating-a-linked-list-container}
71///
72///
73/// Suppose that we want to define a bidirectional linked list that can hold
74/// elements of a template parameter type. `bslstl::BidirectionalNodePool` can
75/// be used to create and destroy nodes that make up a linked list.
76///
77/// First, we create an elided definition of the class template `MyList`:
78/// @code
79/// #include <bslalg_bidirectionallinklistutil.h>
80///
81/// /// This class template implements a bidirectional linked list of
82/// /// element of the (template parameter) type `VALUE`. The memory used
83/// /// will be allocated from an allocator of the (template parameter) type
84/// /// `ALLOCATOR` specified at construction.
85/// template <class VALUE, class ALLOCATOR>
86/// class MyList {
87///
88/// public:
89/// // TYPES
90///
91/// /// This `typedef` is an alias to the type of the linked list node.
92/// typedef bslalg::BidirectionalNode<VALUE> Node;
93///
94/// private:
95/// // TYPES
96///
97/// /// This `typedef` is an alias to the type of the memory pool.
98/// typedef bslstl::BidirectionalNodePool<VALUE, ALLOCATOR> Pool;
99///
100/// /// This `typedef` is an alias to the utility `struct` providing
101/// /// functions for constructing and manipulating linked lists.
102/// typedef bslalg::BidirectionalLinkListUtil Util;
103///
104/// /// This `typedef` is an alias to the type of the linked list link.
105/// typedef bslalg::BidirectionalLink Link;
106///
107/// // DATA
108/// Node *d_head_p; // pointer to the head of the linked list
109/// Node *d_tail_p; // pointer to the tail of the linked list
110/// Pool d_pool; // memory pool used to allocate memory
111///
112///
113/// public:
114/// // CREATORS
115///
116/// /// Create an empty linked list that allocate memory using the
117/// /// specified `allocator`.
118/// MyList(const ALLOCATOR& allocator = ALLOCATOR());
119///
120/// /// Destroy this linked list by calling destructor for each element
121/// /// and deallocate all allocated storage.
122/// ~MyList();
123///
124/// // MANIPULATORS
125///
126/// /// Insert the specified 'value' at the front of this linked list.
127/// void pushFront(const VALUE& value);
128///
129/// /// Insert the specified 'value' at the end of this linked list.
130/// void pushBack(const VALUE& value);
131///
132/// //...
133/// };
134/// @endcode
135/// Now, we define the methods of `MyMatrix`:
136/// @code
137/// CREATORS
138/// template <class VALUE, class ALLOCATOR>
139/// MyList<VALUE, ALLOCATOR>::MyList(const ALLOCATOR& allocator)
140/// : d_head_p(0)
141/// , d_tail_p(0)
142/// , d_pool(allocator)
143/// {
144/// }
145///
146/// template <class VALUE, class ALLOCATOR>
147/// MyList<VALUE, ALLOCATOR>::~MyList()
148/// {
149/// Link *link = d_head_p;
150/// while (link) {
151/// Link *next = link->nextLink();
152/// @endcode
153/// Here, we call the memory pool's `deleteNode` method to destroy the `value`
154/// attribute of the node and return its memory footprint back to the pool:
155/// @code
156/// d_pool.deleteNode(static_cast<Node*>(link));
157/// link = next;
158/// }
159/// }
160///
161/// MANIPULATORS
162/// template <class VALUE, class ALLOCATOR>
163/// void
164/// MyList<VALUE, ALLOCATOR>::pushFront(const VALUE& value)
165/// {
166/// @endcode
167/// Here, we call the memory pool's `emplaceIntoNewNode` method to allocate a
168/// node and copy-construct the specified `value` at the `value` attribute of
169/// the node:
170/// @code
171/// Node *node = static_cast<Node *>(d_pool.emplaceIntoNewNode(value));
172/// @endcode
173/// Note that the memory pool will allocate the footprint of the node using the
174/// allocator specified at construction. If the (template parameter) type
175/// `ALLOCATOR` is an instance of `bsl::allocator` and the (template parameter)
176/// type `VALUE` has the `bslma::UsesBslmaAllocator` trait, then the allocator
177/// specified at construction will also be supplied to the copy-constructor of
178/// `VALUE`.
179/// @code
180/// if (!d_head_p) {
181/// d_tail_p = node;
182/// node->setNextLink(0);
183/// node->setPreviousLink(0);
184/// }
185/// else {
186/// Util::insertLinkBeforeTarget(node, d_head_p);
187/// }
188/// d_head_p = node;
189/// }
190///
191/// template <class VALUE, class ALLOCATOR>
192/// void
193/// MyList<VALUE, ALLOCATOR>::pushBack(const VALUE& value)
194/// {
195/// @endcode
196/// Here, just like how we implemented the `pushFront` method, we call the
197/// pool's `emplaceIntoNewNode` method to allocate a node and copy-construct the
198/// specified `value` at the `value` attribute of the node:
199/// @code
200/// Node *node = static_cast<Node *>(d_pool.emplaceIntoNewNode(value));
201/// if (!d_head_p) {
202/// d_head_p = node;
203/// node->setNextLink(0);
204/// node->setPreviousLink(0);
205/// }
206/// else {
207/// Util::insertLinkAfterTarget(node, d_tail_p);
208/// }
209/// d_tail_p = node;
210/// }
211/// @endcode
212/// @}
213/** @} */
214/** @} */
215
216/** @addtogroup bsl
217 * @{
218 */
219/** @addtogroup bslstl
220 * @{
221 */
222/** @addtogroup bslstl_bidirectionalnodepool
223 * @{
224 */
225
226#include <bslscm_version.h>
227
228#include <bslstl_simplepool.h>
229
232
235
237#include <bslmf_movableref.h>
238#include <bslmf_util.h> // 'forward(V)'
239
240#include <bsls_assert.h>
242#include <bsls_util.h>
243
244#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
245#include <bsls_nativestd.h>
246#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
247
248#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
249// clang-format off
250// Include version that can be compiled with C++03
251// Generated on Mon Jan 13 08:31:39 2025
252// Command line: sim_cpp11_features.pl bslstl_bidirectionalnodepool.h
253
254# define COMPILING_BSLSTL_BIDIRECTIONALNODEPOOL_H
256# undef COMPILING_BSLSTL_BIDIRECTIONALNODEPOOL_H
257
258// clang-format on
259#else
260
261
262namespace bslstl {
263
264 // ===========================
265 // class BidirectionalNodePool
266 // ===========================
267
268/// This class provides methods for creating and destroying nodes using the
269/// appropriate allocator-traits of the (template parameter) type
270/// `ALLOCATOR`.
271///
272/// See @ref bslstl_bidirectionalnodepool
273template <class VALUE, class ALLOCATOR>
275
276 // PRIVATE TYPES
277
278 /// This `typedef` is an alias for the memory pool allocator.
280
281 /// This `typedef` is an alias for the allocator traits defined by
282 /// `SimplePool`.
283 typedef typename Pool::AllocatorTraits AllocatorTraits;
284
285 /// This typedef is a convenient alias for the utility associated with
286 /// movable references.
288
289 // DATA
290 Pool d_pool; // pool for allocating memory
291
292 private:
293 // NOT IMPLEMENTED
296
297 public:
298 // PUBLIC TYPE
299
300 /// Alias for the allocator type defined by `SimplePool`.
302
303 /// Alias for the `size_type` of the allocator defined by `SimplePool`.
304 typedef typename AllocatorTraits::size_type size_type;
305
306 public:
307 // CREATORS
308
309 /// Create a `BidirectionalNodePool` object that will use the specified
310 /// `allocator` to supply memory for allocated node objects. If the
311 /// (template parameter) `ALLOCATOR` is `bsl::allocator`, then
312 /// `allocator` shall be convertible to `bslma::Allocator *`.
313 explicit BidirectionalNodePool(const ALLOCATOR& allocator);
314
315 /// Create a bidirectional node-pool, adopting all outstanding memory
316 /// allocations associated with the specified `original` node-pool, that
317 /// will use the allocator associated with `original` to supply memory
318 /// for allocated node objects. `original` is left in a valid but
319 /// unspecified state.
321
322 /// Destroy the memory pool maintained by this object, releasing all
323 /// memory used by the nodes of the type `BidirectionalNode<VALUE>` in
324 /// the pool. Any memory allocated for the nodes` `value` attribute of
325 /// the (template parameter) type `VALUE` will be leaked unless the
326 /// nodes are explicitly destroyed via the `destroyNode` method.
328
329 // MANIPULATORS
330
331 /// Adopt all outstanding memory allocations associated with the specified node `pool`.
332 ///
333 /// \pre The behavior is undefined unless this pool
334 /// uses the same allocator as that associated with `pool`. The
335 /// behavior is also undefined unless this pool is in the
336 /// default-constructed state.
338
339 /// Return a reference providing modifiable access to the allocator
340 /// supplying memory for the memory pool maintained by this object.
341 ///
342 /// \pre The behavior is undefined if the allocator used by this object is changed with this method.
343 ///
344 /// \note Note that this method provides modifiable
345 /// access to enable a client to call non-`const` methods on the
346 /// allocator.
348
349 /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
350 /// copy-construct an object of the (template parameter) type `VALUE`
351 /// having the same value as the specified `original` at the `value`
352 /// attribute of the node. Return the address of the node.
353 ///
354 /// \note Note that the `next` and `prev` attributes of the returned node will be
355 /// uninitialized.
357 const bslalg::BidirectionalLink& original);
358
359 /// Destroy the `VALUE` attribute of the specified `linkNode` and return
360 /// the memory footprint of `linkNode` to this pool for potential reuse.
361 ///
362 /// \pre The behavior is undefined unless `node` refers to a
363 /// `bslalg::BidirectionalNode<VALUE>` that was allocated by this pool.
365
366#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
367 /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
368 /// construct in-place an object of the (template parameter) type
369 /// `VALUE` with the specified constructor `arguments`. Return the address of the node.
370 ///
371 /// \note Note that the `next` and `prev` attributes of
372 /// the returned node will be uninitialized.
373 template <class... Args>
375#endif
376
377 /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
378 /// move-construct an object of the (template parameter) type `VALUE`
379 /// with the (explicitly moved) value indicated by the `value` attribute
380 /// of the specified `original` link. Return the address of the node.
381 ///
382 /// \note Note that the `next` and `prev` attributes of the returned node will
383 /// be uninitialized. Also note that the `value` attribute of
384 /// `original` is left in a valid but unspecified state.
386 bslalg::BidirectionalLink *original);
387
388 /// Relinquish all memory currently allocated with the memory pool
389 /// maintained by this object.
390 void release();
391
392 /// Add to this pool sufficient memory to satisfy memory requests for at
393 /// least the specified `numNodes` before the pool replenishes. The
394 /// additional memory is added irrespective of the amount of free memory when called.
395 ///
396 /// \pre The behavior is undefined unless `0 < numNodes`.
397 void reserveNodes(size_type numNodes);
398
399 /// Efficiently exchange the nodes of this object with those of the
400 /// specified `other` object. This method provides the no-throw exception-safety guarantee.
401 ///
402 /// \pre The behavior is undefined unless
403 /// `allocator() == other.allocator()`.
405
406 /// Efficiently exchange the nodes and the allocator of this object with
407 /// those of the specified `other` object. This method provides the
408 /// no-throw exception-safety guarantee.
410
411 // ACCESSORS
412
413 /// Return a reference providing non-modifiable access to the allocator
414 /// supplying memory for the memory pool maintained by this object.
415 const AllocatorType& allocator() const;
416};
417
418// FREE FUNCTIONS
419
420/// Efficiently exchange the nodes of the specified `a` object with those of
421/// the specified `b` object. This method provides the no-throw exception-safety guarantee.
422///
423/// \pre The behavior is undefined unless
424/// `a.allocator() == b.allocator()`.
425template <class VALUE, class ALLOCATOR>
428
429} // close package namespace
430
431
432// ============================================================================
433// TYPE TRAITS
434// ============================================================================
435
436// Type traits for HashTable:
437//: o A HashTable is bitwise moveable if the allocator is bitwise moveable.
438
439namespace bslmf {
440
441template <class VALUE, class ALLOCATOR>
442struct IsBitwiseMoveable<bslstl::BidirectionalNodePool<VALUE, ALLOCATOR> >
443: bsl::integral_constant<bool, bslmf::IsBitwiseMoveable<ALLOCATOR>::value>
444{};
445
446} // close namespace bslmf
447
448// ============================================================================
449// TEMPLATE AND INLINE FUNCTION DEFINITIONS
450// ============================================================================
451
452namespace bslstl {
453
454// CREATORS
455template <class VALUE, class ALLOCATOR>
456inline
458 const ALLOCATOR& allocator)
459: d_pool(allocator)
460{
461}
462
463template <class VALUE, class ALLOCATOR>
464inline
470
471// MANIPULATORS
472template <class VALUE, class ALLOCATOR>
473inline
476{
477 BidirectionalNodePool& lvalue = pool;
478 d_pool.adopt(MoveUtil::move(lvalue.d_pool));
479}
480
481template <class VALUE, class ALLOCATOR>
482inline
483typename
484SimplePool<bslalg::BidirectionalNode<VALUE>, ALLOCATOR>::AllocatorType&
489
490template <class VALUE, class ALLOCATOR>
491inline
494 const bslalg::BidirectionalLink& original)
495{
496 return emplaceIntoNewNode(
497 static_cast<const bslalg::BidirectionalNode<VALUE>&>(original).value());
498}
499
500#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
501template <class VALUE, class ALLOCATOR>
502template <class... Args>
503inline
506 Args&&... arguments)
507{
508 bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
509 bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);
510
511 AllocatorTraits::construct(
512 allocator(),
514 BSLS_COMPILERFEATURES_FORWARD(Args,arguments)...);
515 proctor.release();
516 return node;
517}
518#endif
519
520template <class VALUE, class ALLOCATOR>
521inline
525{
526 return emplaceIntoNewNode(MoveUtil::move(
527 static_cast<bslalg::BidirectionalNode<VALUE> *>(original)->value()));
528}
529
530template <class VALUE, class ALLOCATOR>
533{
534 BSLS_ASSERT(linkNode);
535
537 static_cast<bslalg::BidirectionalNode<VALUE> *>(linkNode);
538 AllocatorTraits::destroy(allocator(),
540 d_pool.deallocate(node);
541}
542
543template <class VALUE, class ALLOCATOR>
544inline
546{
547 d_pool.release();
548}
549
550template <class VALUE, class ALLOCATOR>
551inline
553{
554 BSLS_ASSERT_SAFE(0 < numNodes);
555
556 d_pool.reserve(numNodes);
557}
558
559template <class VALUE, class ALLOCATOR>
560inline
563{
564 BSLS_ASSERT_SAFE(allocator() == other.allocator());
565
566 d_pool.quickSwapRetainAllocators(other.d_pool);
567}
568
569template <class VALUE, class ALLOCATOR>
570inline
573{
574 d_pool.quickSwapExchangeAllocators(other.d_pool);
575}
576
577// ACCESSORS
578template <class VALUE, class ALLOCATOR>
579inline
580const typename
582 AllocatorType&
587
588} // close package namespace
589
590template <class VALUE, class ALLOCATOR>
591inline
594{
596}
597
598
599
600#endif // End C++11 code
601
602#endif
603
604// ----------------------------------------------------------------------------
605// Copyright 2019 Bloomberg Finance L.P.
606//
607// Licensed under the Apache License, Version 2.0 (the "License");
608// you may not use this file except in compliance with the License.
609// You may obtain a copy of the License at
610//
611// http://www.apache.org/licenses/LICENSE-2.0
612//
613// Unless required by applicable law or agreed to in writing, software
614// distributed under the License is distributed on an "AS IS" BASIS,
615// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
616// See the License for the specific language governing permissions and
617// limitations under the License.
618// ----------------------------- END-OF-FILE ----------------------------------
619
620/** @} */
621/** @} */
622/** @} */
Definition bslalg_bidirectionalnode.h:357
ValueType & value()
Definition bslalg_bidirectionalnode.h:404
Definition bslma_deallocatorproctor.h:312
void release()
Definition bslma_deallocatorproctor.h:389
Definition bslmf_movableref.h:752
Definition bslstl_bidirectionalnodepool.h:274
void release()
Definition bslstl_bidirectionalnodepool.h:545
bslalg::BidirectionalLink * cloneNode(const bslalg::BidirectionalLink &original)
Definition bslstl_bidirectionalnodepool.h:493
AllocatorType & allocator()
Definition bslstl_bidirectionalnodepool.h:485
void adopt(bslmf::MovableRef< BidirectionalNodePool > pool)
Definition bslstl_bidirectionalnodepool.h:474
void swapRetainAllocators(BidirectionalNodePool &other)
Definition bslstl_bidirectionalnodepool.h:561
bslalg::BidirectionalLink * emplaceIntoNewNode(Args &&... arguments)
Definition bslstl_bidirectionalnodepool.h:505
AllocatorTraits::size_type size_type
Alias for the size_type of the allocator defined by SimplePool.
Definition bslstl_bidirectionalnodepool.h:304
BidirectionalNodePool(const ALLOCATOR &allocator)
Definition bslstl_bidirectionalnodepool.h:457
void swapExchangeAllocators(BidirectionalNodePool &other)
Definition bslstl_bidirectionalnodepool.h:571
BidirectionalNodePool(bslmf::MovableRef< BidirectionalNodePool > original)
Definition bslstl_bidirectionalnodepool.h:465
Pool::AllocatorType AllocatorType
Alias for the allocator type defined by SimplePool.
Definition bslstl_bidirectionalnodepool.h:301
void deleteNode(bslalg::BidirectionalLink *linkNode)
Definition bslstl_bidirectionalnodepool.h:531
bslalg::BidirectionalLink * moveIntoNewNode(bslalg::BidirectionalLink *original)
Definition bslstl_bidirectionalnodepool.h:523
const AllocatorType & allocator() const
Definition bslstl_bidirectionalnodepool.h:583
void reserveNodes(size_type numNodes)
Definition bslstl_bidirectionalnodepool.h:552
Definition bslstl_simplepool.h:294
Types::AllocatorType AllocatorType
Definition bslstl_simplepool.h:343
AllocatorType & allocator()
Definition bslstl_simplepool.h:586
Types::AllocatorTraits AllocatorTraits
Definition bslstl_simplepool.h:347
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#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
Definition bdlbb_blob.h:579
Definition bslstl_algorithm.h:84
void swap(BidirectionalNodePool< VALUE, ALLOCATOR > &a, BidirectionalNodePool< VALUE, ALLOCATOR > &b)
Definition bslmf_integralconstant.h:261
Definition bslmf_isbitwisemoveable.h:718
Definition bslmf_movableref.h:795
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:312