BDE 4.14.0 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// Include version that can be compiled with C++03
250// Generated on Thu Oct 21 10:11:37 2021
251// Command line: sim_cpp11_features.pl bslstl_bidirectionalnodepool.h
252# define COMPILING_BSLSTL_BIDIRECTIONALNODEPOOL_H
254# undef COMPILING_BSLSTL_BIDIRECTIONALNODEPOOL_H
255#else
256
257
258namespace bslstl {
259
260 // ===========================
261 // class BidirectionalNodePool
262 // ===========================
263
264/// This class provides methods for creating and destroying nodes using the
265/// appropriate allocator-traits of the (template parameter) type
266/// `ALLOCATOR`.
267///
268/// See @ref bslstl_bidirectionalnodepool
269template <class VALUE, class ALLOCATOR>
271
272 // PRIVATE TYPES
273
274 /// This `typedef` is an alias for the memory pool allocator.
276
277 /// This `typedef` is an alias for the allocator traits defined by
278 /// `SimplePool`.
279 typedef typename Pool::AllocatorTraits AllocatorTraits;
280
281 /// This typedef is a convenient alias for the utility associated with
282 /// movable references.
284
285 // DATA
286 Pool d_pool; // pool for allocating memory
287
288 private:
289 // NOT IMPLEMENTED
292
293 public:
294 // PUBLIC TYPE
295
296 /// Alias for the allocator type defined by `SimplePool`.
298
299 /// Alias for the `size_type` of the allocator defined by `SimplePool`.
300 typedef typename AllocatorTraits::size_type size_type;
301
302 public:
303 // CREATORS
304
305 /// Create a `BidirectionalNodePool` object that will use the specified
306 /// `allocator` to supply memory for allocated node objects. If the
307 /// (template parameter) `ALLOCATOR` is `bsl::allocator`, then
308 /// `allocator` shall be convertible to `bslma::Allocator *`.
309 explicit BidirectionalNodePool(const ALLOCATOR& allocator);
310
311 /// Create a bidirectional node-pool, adopting all outstanding memory
312 /// allocations associated with the specified `original` node-pool, that
313 /// will use the allocator associated with `original` to supply memory
314 /// for allocated node objects. `original` is left in a valid but
315 /// unspecified state.
317
318 /// Destroy the memory pool maintained by this object, releasing all
319 /// memory used by the nodes of the type `BidirectionalNode<VALUE>` in
320 /// the pool. Any memory allocated for the nodes` `value` attribute of
321 /// the (template parameter) type `VALUE` will be leaked unless the
322 /// nodes are explicitly destroyed via the `destroyNode` method.
324
325 // MANIPULATORS
326
327 /// Adopt all outstanding memory allocations associated with the
328 /// specified node `pool`. The behavior is undefined unless this pool
329 /// uses the same allocator as that associated with `pool`. The
330 /// behavior is also undefined unless this pool is in the
331 /// default-constructed state.
333
334 /// Return a reference providing modifiable access to the allocator
335 /// supplying memory for the memory pool maintained by this object. The
336 /// behavior is undefined if the allocator used by this object is
337 /// changed with this method. Note that this method provides modifiable
338 /// access to enable a client to call non-`const` methods on the
339 /// allocator.
341
342 /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
343 /// copy-construct an object of the (template parameter) type `VALUE`
344 /// having the same value as the specified `original` at the `value`
345 /// attribute of the node. Return the address of the node. Note that
346 /// the `next` and `prev` attributes of the returned node will be
347 /// uninitialized.
349 const bslalg::BidirectionalLink& original);
350
351 /// Destroy the `VALUE` attribute of the specified `linkNode` and return
352 /// the memory footprint of `linkNode` to this pool for potential reuse.
353 /// The behavior is undefined unless `node` refers to a
354 /// `bslalg::BidirectionalNode<VALUE>` that was allocated by this pool.
356
357#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
358 /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
359 /// construct in-place an object of the (template parameter) type
360 /// `VALUE` with the specified constructor `arguments`. Return the
361 /// address of the node. Note that the `next` and `prev` attributes of
362 /// the returned node will be uninitialized.
363 template <class... Args>
365#endif
366
367 /// Allocate a node of the type `BidirectionalNode<VALUE>`, and
368 /// move-construct an object of the (template parameter) type `VALUE`
369 /// with the (explicitly moved) value indicated by the `value` attribute
370 /// of the specified `original` link. Return the address of the node.
371 /// Note that the `next` and `prev` attributes of the returned node will
372 /// be uninitialized. Also note that the `value` attribute of
373 /// `original` is left in a valid but unspecified state.
375 bslalg::BidirectionalLink *original);
376
377 /// Relinquish all memory currently allocated with the memory pool
378 /// maintained by this object.
379 void release();
380
381 /// Add to this pool sufficient memory to satisfy memory requests for at
382 /// least the specified `numNodes` before the pool replenishes. The
383 /// additional memory is added irrespective of the amount of free memory
384 /// when called. The behavior is undefined unless `0 < numNodes`.
385 void reserveNodes(size_type numNodes);
386
387 /// Efficiently exchange the nodes of this object with those of the
388 /// specified `other` object. This method provides the no-throw
389 /// exception-safety guarantee. The behavior is undefined unless
390 /// `allocator() == other.allocator()`.
392
393 /// Efficiently exchange the nodes and the allocator of this object with
394 /// those of the specified `other` object. This method provides the
395 /// no-throw exception-safety guarantee.
397
398 // ACCESSORS
399
400 /// Return a reference providing non-modifiable access to the allocator
401 /// supplying memory for the memory pool maintained by this object.
402 const AllocatorType& allocator() const;
403};
404
405// FREE FUNCTIONS
406
407/// Efficiently exchange the nodes of the specified `a` object with those of
408/// the specified `b` object. This method provides the no-throw
409/// exception-safety guarantee. The behavior is undefined unless
410/// `a.allocator() == b.allocator()`.
411template <class VALUE, class ALLOCATOR>
414
415} // close package namespace
416
417
418// ============================================================================
419// TYPE TRAITS
420// ============================================================================
421
422// Type traits for HashTable:
423//: o A HashTable is bitwise moveable if the allocator is bitwise moveable.
424
425namespace bslmf {
426
427template <class VALUE, class ALLOCATOR>
428struct IsBitwiseMoveable<bslstl::BidirectionalNodePool<VALUE, ALLOCATOR> >
429: bsl::integral_constant<bool, bslmf::IsBitwiseMoveable<ALLOCATOR>::value>
430{};
431
432} // close namespace bslmf
433
434// ============================================================================
435// TEMPLATE AND INLINE FUNCTION DEFINITIONS
436// ============================================================================
437
438namespace bslstl {
439
440// CREATORS
441template <class VALUE, class ALLOCATOR>
442inline
444 const ALLOCATOR& allocator)
445: d_pool(allocator)
446{
447}
448
449template <class VALUE, class ALLOCATOR>
450inline
456
457// MANIPULATORS
458template <class VALUE, class ALLOCATOR>
459inline
462{
463 BidirectionalNodePool& lvalue = pool;
464 d_pool.adopt(MoveUtil::move(lvalue.d_pool));
465}
466
467template <class VALUE, class ALLOCATOR>
468inline
469typename
470SimplePool<bslalg::BidirectionalNode<VALUE>, ALLOCATOR>::AllocatorType&
475
476template <class VALUE, class ALLOCATOR>
477inline
480 const bslalg::BidirectionalLink& original)
481{
482 return emplaceIntoNewNode(
483 static_cast<const bslalg::BidirectionalNode<VALUE>&>(original).value());
484}
485
486#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
487template <class VALUE, class ALLOCATOR>
488template <class... Args>
489inline
492 Args&&... arguments)
493{
494 bslalg::BidirectionalNode<VALUE> *node = d_pool.allocate();
495 bslma::DeallocatorProctor<Pool> proctor(node, &d_pool);
496
497 AllocatorTraits::construct(
498 allocator(),
500 BSLS_COMPILERFEATURES_FORWARD(Args,arguments)...);
501 proctor.release();
502 return node;
503}
504#endif
505
506template <class VALUE, class ALLOCATOR>
507inline
511{
512 return emplaceIntoNewNode(MoveUtil::move(
513 static_cast<bslalg::BidirectionalNode<VALUE> *>(original)->value()));
514}
515
516template <class VALUE, class ALLOCATOR>
519{
520 BSLS_ASSERT(linkNode);
521
523 static_cast<bslalg::BidirectionalNode<VALUE> *>(linkNode);
524 AllocatorTraits::destroy(allocator(),
526 d_pool.deallocate(node);
527}
528
529template <class VALUE, class ALLOCATOR>
530inline
532{
533 d_pool.release();
534}
535
536template <class VALUE, class ALLOCATOR>
537inline
539{
540 BSLS_ASSERT_SAFE(0 < numNodes);
541
542 d_pool.reserve(numNodes);
543}
544
545template <class VALUE, class ALLOCATOR>
546inline
549{
550 BSLS_ASSERT_SAFE(allocator() == other.allocator());
551
552 d_pool.quickSwapRetainAllocators(other.d_pool);
553}
554
555template <class VALUE, class ALLOCATOR>
556inline
559{
560 d_pool.quickSwapExchangeAllocators(other.d_pool);
561}
562
563// ACCESSORS
564template <class VALUE, class ALLOCATOR>
565inline
566const typename
568 AllocatorType&
573
574} // close package namespace
575
576template <class VALUE, class ALLOCATOR>
577inline
580{
582}
583
584
585
586#endif // End C++11 code
587
588#endif
589
590// ----------------------------------------------------------------------------
591// Copyright 2019 Bloomberg Finance L.P.
592//
593// Licensed under the Apache License, Version 2.0 (the "License");
594// you may not use this file except in compliance with the License.
595// You may obtain a copy of the License at
596//
597// http://www.apache.org/licenses/LICENSE-2.0
598//
599// Unless required by applicable law or agreed to in writing, software
600// distributed under the License is distributed on an "AS IS" BASIS,
601// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
602// See the License for the specific language governing permissions and
603// limitations under the License.
604// ----------------------------- END-OF-FILE ----------------------------------
605
606/** @} */
607/** @} */
608/** @} */
Definition bslalg_bidirectionalnode.h:357
ValueType & value()
Definition bslalg_bidirectionalnode.h:404
Definition bslma_deallocatorproctor.h:312
void release()
Definition bslma_deallocatorproctor.h:384
Definition bslmf_movableref.h:751
Definition bslstl_bidirectionalnodepool.h:270
void release()
Definition bslstl_bidirectionalnodepool.h:531
bslalg::BidirectionalLink * cloneNode(const bslalg::BidirectionalLink &original)
Definition bslstl_bidirectionalnodepool.h:479
AllocatorType & allocator()
Definition bslstl_bidirectionalnodepool.h:471
void adopt(bslmf::MovableRef< BidirectionalNodePool > pool)
Definition bslstl_bidirectionalnodepool.h:460
void swapRetainAllocators(BidirectionalNodePool &other)
Definition bslstl_bidirectionalnodepool.h:547
bslalg::BidirectionalLink * emplaceIntoNewNode(Args &&... arguments)
Definition bslstl_bidirectionalnodepool.h:491
AllocatorTraits::size_type size_type
Alias for the size_type of the allocator defined by SimplePool.
Definition bslstl_bidirectionalnodepool.h:300
BidirectionalNodePool(const ALLOCATOR &allocator)
Definition bslstl_bidirectionalnodepool.h:443
void swapExchangeAllocators(BidirectionalNodePool &other)
Definition bslstl_bidirectionalnodepool.h:557
BidirectionalNodePool(bslmf::MovableRef< BidirectionalNodePool > original)
Definition bslstl_bidirectionalnodepool.h:451
Pool::AllocatorType AllocatorType
Alias for the allocator type defined by SimplePool.
Definition bslstl_bidirectionalnodepool.h:297
void deleteNode(bslalg::BidirectionalLink *linkNode)
Definition bslstl_bidirectionalnodepool.h:517
bslalg::BidirectionalLink * moveIntoNewNode(bslalg::BidirectionalLink *original)
Definition bslstl_bidirectionalnodepool.h:509
const AllocatorType & allocator() const
Definition bslstl_bidirectionalnodepool.h:569
void reserveNodes(size_type numNodes)
Definition bslstl_bidirectionalnodepool.h:538
Definition bslstl_simplepool.h:292
Types::AllocatorType AllocatorType
Definition bslstl_simplepool.h:341
AllocatorType & allocator()
Definition bslstl_simplepool.h:573
Types::AllocatorTraits AllocatorTraits
Definition bslstl_simplepool.h:345
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlbb_blob.h:576
Definition bslstl_algorithm.h:82
void swap(BidirectionalNodePool< VALUE, ALLOCATOR > &a, BidirectionalNodePool< VALUE, ALLOCATOR > &b)
Definition bslmf_integralconstant.h:244
Definition bslmf_isbitwisemoveable.h:718
Definition bslmf_movableref.h:791
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305