BDE 4.39.x Production Release
Loading...
Searching...
No Matches
ball_attributecontainerlist.h
Go to the documentation of this file.
1/// @file ball_attributecontainerlist.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_attributecontainerlist.h -*-C++-*-
8#ifndef INCLUDED_BALL_ATTRIBUTECONTAINERLIST
9#define INCLUDED_BALL_ATTRIBUTECONTAINERLIST
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_attributecontainerlist ball_attributecontainerlist
15/// @brief Provide a list of attribute container addresses.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_attributecontainerlist
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_attributecontainerlist-purpose"> Purpose</a>
25/// * <a href="#ball_attributecontainerlist-classes"> Classes </a>
26/// * <a href="#ball_attributecontainerlist-description"> Description </a>
27/// * <a href="#ball_attributecontainerlist-thread-safety"> Thread Safety </a>
28/// * <a href="#ball_attributecontainerlist-usage"> Usage </a>
29/// * <a href="#ball_attributecontainerlist-example-1-basic-usage-of-ball-attributecontainerlist"> Example 1: Basic Usage of ball::AttributeContainerList </a>
30///
31/// # Purpose {#ball_attributecontainerlist-purpose}
32/// Provide a list of attribute container addresses.
33///
34/// # Classes {#ball_attributecontainerlist-classes}
35///
36/// - ball::AttributeContainerList: a list of container addresses
37/// - ball::AttributeContainerListIterator: an iterator over a container list
38///
39/// @see ball_attribute, ball_attributecontainer
40///
41/// # Description {#ball_attributecontainerlist-description}
42/// This component defines a class `ball::AttributeContainerList`
43/// that provides a linked list of `ball::AttributeContainer` object
44/// *addresses*. Addresses can be prepended (to the front of the list) using
45/// the `pushFront()` method. The `pushFront()` method returns an iterator that
46/// can be used later to efficiently remove the added element. The
47/// `ball::AttributeContainerList` also provides a `hasValue()` operation, that
48/// returns `true` if any of the attribute containers in the list contain the
49/// supplied attribute, and `false` otherwise. The
50/// `ball::AttributeContainerList` maintains a store of free list-nodes to
51/// minimize the amount of memory allocation required if addresses are
52/// frequently added and removed from the container. This component also
53/// defines a class `ball::AttributeContainerListIterator` (as well as the alias
54/// `ball::AttributeContainerList::iterator)` that provides an STL-style
55/// iterator over the addresses in a `ball::AttributeContainer`.
56///
57/// This component participates in the implementation of "Rule-Based Logging".
58/// For more information on how to use that feature, please see the package
59/// level documentation and usage examples for "Rule-Based Logging".
60///
61/// ## Thread Safety {#ball_attributecontainerlist-thread-safety}
62///
63///
64/// `ball::AttributeContainerList` is *const* *thread-safe*, meaning that
65/// accessors may be invoked concurrently from different threads, but it is not
66/// safe to access or modify a `ball::AttributeContainerList` in one thread
67/// while another thread modifies the same object.
68///
69/// ## Usage {#ball_attributecontainerlist-usage}
70///
71///
72/// This section illustrates intended use of this component.
73///
74/// ### Example 1: Basic Usage of ball::AttributeContainerList {#ball_attributecontainerlist-example-1-basic-usage-of-ball-attributecontainerlist}
75///
76///
77/// In the following example we demonstrate how to create a
78/// `ball::AttributeContainerList` object, how to add and remove elements from
79/// the list, and how to walk the list of attribute container addresses.
80///
81/// We start by creating three attribute sets that we will use to populate our
82/// attribute container list. Note that this example uses the `AttributeSet`
83/// implementation of the `ball::AttributeContainer` protocol defined in the
84/// @ref ball_attributecontainer component documentation.
85/// @code
86/// AttributeSet s1, s2, s3;
87/// s1.insert(ball::AttributeValue("Set1", 1));
88/// s2.insert(ball::AttributeValue("Set2", 2));
89/// s3.insert(ball::AttributeValue("Set3", 3));
90/// @endcode
91/// We now create a `ball::AttributeContainerList` and add the three attribute
92/// container addresses to the list:
93/// @code
94/// ball::AttributeContainerList exampleList;
95/// ball::AttributeContainerList::iterator s1Iter = exampleList.pushFront(&s1);
96/// ball::AttributeContainerList::iterator s2Iter = exampleList.pushFront(&s2);
97/// ball::AttributeContainerList::iterator s3Iter = exampleList.pushFront(&s3);
98/// @endcode
99/// We can use the `hasValue()` operation to test which attribute value are
100/// contained within the list of containers:
101/// @code
102/// assert(true == exampleList.hasValue("Set1", 1));
103/// assert(true == exampleList.hasValue("Set2", 2));
104/// assert(true == exampleList.hasValue("Set3", 3));
105///
106/// assert(false == exampleList.hasValue("Set1", 2));
107/// assert(false == exampleList.hasValue("Set2", 1));
108/// assert(false == exampleList.hasValue("Set4", 1));
109/// @endcode
110/// We can use the iterators to efficiently remove elements from the list:
111/// @code
112/// exampleList.remove(s3Iter);
113/// @endcode
114/// Finally, we can use either the stream operator or the `print()` method to
115/// print the attributes within an attribute container list:
116/// @code
117/// bsl::cout << exampleList << bsl::endl;
118/// @endcode
119/// The resulting output will be the following:
120/// @code
121/// [ [ [ Set2 = 2 ] ] [ [ Set1 = 1 ] ] ]
122/// @endcode
123/// Note that the output shows the values in `s2` (i.e., `("Set2", 2)`) and
124/// then the values in `s1` (i.e., `("Set1", 1)`).
125/// @}
126/** @} */
127/** @} */
128
129/** @addtogroup bal
130 * @{
131 */
132/** @addtogroup ball
133 * @{
134 */
135/** @addtogroup ball_attributecontainerlist
136 * @{
137 */
138
139#include <balscm_version.h>
140
141#include <bslma_allocator.h>
142#include <bslma_bslallocator.h>
144
146
147#include <bsl_iosfwd.h>
148
149
150namespace ball {
151
152class Attribute;
153class AttributeContainer;
154struct AttributeContainerList_Node;
155
156 // ====================================
157 // class AttributeContainerListIterator
158 // ====================================
159
160/// This class provides an STL-style iterator over a sequence of
161/// `AttributeContainer` object addresses. The behavior of the `operator*`
162/// method is undefined unless the iterator is at a valid position in the
163/// sequence of `AttributeContainer` object addresses (i.e., not the "end")
164/// and the referenced element has not been removed since the iterator was
165/// constructed.
166///
167/// See @ref ball_attributecontainerlist
169
170 // PRIVATE TYPES
172
173 // DATA
174 Node *d_node_p; // current iterator location
175
176 // FRIENDS
180
181 public:
182 // CREATORS
183
184 /// Create an uninitialized iterator.
186
187 /// Create an iterator having the same value as the specified
188 /// `original` one.
190 const AttributeContainerListIterator& original);
191
192 /// Create an iterator at the specified `position`.
194
195 /// Destroy this object.
197
198 // MANIPULATORS
199
200 /// Assign this iterator the value of the specified `rhs` and return a
201 /// modifiable reference to this iterator.
204
205 /// Advance this iterator to the next attribute container in the list
206 /// and return the value of this iterator.
207 ///
208 /// \pre The behavior is undefined unless the iterator is at a valid position in the list.
210
211 /// Advance this iterator to the next attribute container in the list
212 /// and return the value of the iterator prior to this method call.
213 ///
214 /// \pre The behavior is undefined unless the iterator is at a valid
215 /// position in the list.
217
218 // ACCESSORS
219
220 /// Return the address of the non-modifiable attribute container at which this iterator is positioned.
221 ///
222 /// \pre The behavior is undefined unless
223 /// this iterator is at a valid position in the list.
224 const AttributeContainer *operator*() const;
225
226 /// Return `true` if this iterator is at a valid position in the
227 /// sequence of `AttributeContainer` addresses and `false` otherwise.
228 bool valid() const;
229};
230
231// FREE OPERATORS
232
233/// Return `true` if the specified `lhs` and the specified `rhs` iterators
234/// have the same value and `false` otherwise. Two iterators have the same
235/// value if they refer to the same position in the same list, or if both
236/// iterators are at an invalid position in the list (i.e., the "end" of the
237/// list, or the default constructed value).
238bool operator==(const AttributeContainerListIterator& lhs,
240
241/// Return `true` if the specified `lhs` and the specified `rhs` iterators
242/// do not have the same value and `false` otherwise. Two iterators do not
243/// have the same value if they differ in either the list to which they
244/// refer or the position in the list object.
245bool operator!=(const AttributeContainerListIterator& lhs,
247
248 // ============================
249 // class AttributeContainerList
250 // ============================
251
252/// This class provides an in-core value-semantic list of
253/// `AttributeContainer` object addresses. Attribute container addresses
254/// are added to this list using `pushFront()`, which returns an iterator
255/// located at the new element. A `AttributeContainerList::iterator` object
256/// remains valid until the element referred to by the iterator is removed.
257/// Attribute container addresses can be removed using either `remove()`,
258/// `removeAll()`, or `removeAllAndRelease()`. This list object attempts to
259/// minimize the number of memory allocations it requires by placing the
260/// memory for elements that have been released in a free memory store, and
261/// re-using the memory when new elements are added. The `removeAll()`
262/// removes all the elements from the list, but does not release any
263/// allocated memory (placing it in the free store). The
264/// `removeAllAndRelease()` operation removes all elements and releases all allocated memory.
265///
266/// \note Note that maintaining a free store is important for
267/// this component because the expectation is that elements will be both
268/// added and removed frequently.
269///
270/// See @ref ball_attributecontainerlist
272 public:
273 // TYPES
275
276 private:
277 // PRIVATE TYPES
279
280 // DATA
281 Node *d_head_p; // head of the linked list of elements
282 Node *d_free_p; // head of the free store
283 int d_length; // length of the list
284 allocator_type d_allocator; // allocator
285
286 public:
287 // TRAITS
290
291 // PUBLIC TYPES
292
293 /// An iterator over this list.
295
296 // CREATORS
297
298 /// Create an empty container list. Optionally specify an `allocator`
299 /// (e.g., the address of a `bslma::Allocator` object) to supply memory;
300 /// otherwise, the default allocator is used.
302 explicit AttributeContainerList(const allocator_type& allocator);
303
304 /// Create a container list having the same value as the specified
305 /// `original`. Optionally specify an `allocator` (e.g., the address of
306 /// a `bslma::Allocator` object) to supply memory; otherwise, the
307 /// default allocator is used.
309 const AttributeContainerList& original,
310 const allocator_type& allocator = allocator_type());
311
312 /// Destroy this object.
314
315 // MANIPULATORS
316
317 /// Assign this container list the value of the specified `rhs` one, and
318 /// return a reference to this list.
320
321 /// Prepend the address of the specified `container` to this list of
322 /// attribute container addresses, and return an iterator located at
323 /// the newly added list element.
325
326 /// Remove the specified `element` from this list.
327 ///
328 /// \pre The behavior is undefined unless `element` is a valid iterator on this list and the
329 /// referenced address has not previously been removed (by either
330 /// `remove()`, `removeAll()`, or `removeAllAndRelease()`.
331 void remove(const iterator& element);
332
333 /// Remove all the elements from this list. After this operation
334 /// returns, `numContainers()` will be 0. This operation adds all the
335 /// allocated memory to an internal free store, and does not deallocate
336 /// any memory.
337 void removeAll();
338
339 /// Remove all the elements from this list and deallocate any allocated
340 /// memory.
342
343 // ACCESSORS
344
345 /// Return an iterator positioned at the beginning of the list of
346 /// `AttributeContainer` object addresses represented by this object.
347 iterator begin() const;
348
349 /// Return an iterator positioned one past the final
350 /// `AttributeContainer` object address in the list of addresses
351 /// represented by this object.
352 iterator end() const;
353
354 /// Return the number of attribute container addresses currently in
355 /// this list.
356 int numContainers() const;
357
358 /// Return `true` if the attribute having specified `value` exists in
359 /// any of the attribute containers referred to by this object, and
360 /// `false` otherwise.
361 bool hasValue(const Attribute& value) const;
362
363 /// Format this object to the specified output `stream` at the
364 /// (absolute value of) the optionally specified indentation `level`
365 /// and return a reference to `stream`. If `level` is specified,
366 /// optionally specify `spacesPerLevel`, the number of spaces per
367 /// indentation level for this and all of its nested objects. If
368 /// `level` is negative, suppress indentation of the first line. If
369 /// `spacesPerLevel` is negative, format the entire output on one line,
370 /// suppressing all but the initial indentation (as governed by
371 /// `level`). If `stream` is not valid on entry, this operation has no
372 /// effect.
373 bsl::ostream& print(bsl::ostream& stream,
374 int level = 0,
375 int spacesPerLevel = 4) const;
376
377 // Aspects
378
379 /// Return the allocator used by this object to supply memory.
380 ///
381 /// \note Note that if no allocator was supplied at construction the default
382 /// allocator in effect at construction is used.
384};
385
386// FREE OPERATORS
387
388/// Return `true` if the specified `lhs` and `rhs` lists have the same
389/// value, and `false` otherwise. Two lists have the same value if they
390/// have the same number of attribute container addresses, and the address
391/// at each index position have the same value.
392bool operator==(const AttributeContainerList& lhs,
393 const AttributeContainerList& rhs);
394
395/// Return `true` if the specified `lhs` and `rhs` lists do not have the
396/// same value, and `false` otherwise. Two lists do not have the same
397/// value if have differing numbers of attribute container addresses or any
398/// of the addresses at corresponding indices have different values.
399inline
400bool operator!=(const AttributeContainerList& lhs,
401 const AttributeContainerList& rhs);
402
403/// Write a formatted description of the specified `rhs` to the specified
404/// `stream` and return a reference to the modifiable `stream`.
405inline
406bsl::ostream& operator<<(bsl::ostream& output,
407 const AttributeContainerList& rhs);
408
409 // =================================
410 // class AttributeContainerList_Node
411 // =================================
412
413/// This is an implementation type of `AttributeContainerList` and should
414/// not be used by clients of this package. A `AttributeContainerList_Node`
415/// represents a node in a `AttributeContainerList` object.
416///
417/// See @ref ball_attributecontainerlist
419
420 const AttributeContainer *d_value_p; // address value of this
421 // element
422
424
426 // address of previous
427 // element's next pointer
428};
429
430// ============================================================================
431// INLINE DEFINITIONS
432// ============================================================================
433
434 // ------------------------------------
435 // class AttributeContainerListIterator
436 // ------------------------------------
437
438// CREATORS
439inline
444
445inline
451
452inline
454 const AttributeContainerListIterator& original)
455: d_node_p(original.d_node_p)
456{
457}
458
459// MANIPULATORS
460inline
464{
465 d_node_p = rhs.d_node_p;
466 return *this;
467}
468
469inline
472{
473 Node *current = d_node_p;
474 d_node_p = d_node_p->d_next_p;
475 return AttributeContainerListIterator(current);
476}
477
478inline
481{
482 d_node_p = d_node_p->d_next_p;
483 return AttributeContainerListIterator(d_node_p);
484}
485
486// ACCESSORS
487inline
488const AttributeContainer *
490{
491 return d_node_p->d_value_p;
492}
493
494inline
496{
497 return 0 != d_node_p;
498}
499
500 // ============================
501 // class AttributeContainerList
502 // ============================
503
504// CREATORS
505inline
507: d_head_p(0)
508, d_free_p(0)
509, d_length(0)
510, d_allocator()
511{
512}
513
514inline
516: d_head_p(0)
517, d_free_p(0)
518, d_length(0)
519, d_allocator(allocator)
520{
521}
522
523inline
528
529// ACCESSORS
530inline
533{
534 return iterator(d_head_p);
535}
536
537inline
542
543inline
545{
546 return d_length;
547}
548
549inline
552{
553 return d_allocator;
554}
555
556} // close package namespace
557
558// FREE OPERATORS
559inline
560bool ball::operator==(const AttributeContainerListIterator& lhs,
561 const AttributeContainerListIterator& rhs)
562{
563 return lhs.d_node_p == rhs.d_node_p;
564}
565
566inline
567bool ball::operator!=(const AttributeContainerListIterator& lhs,
568 const AttributeContainerListIterator& rhs)
569{
570 return !(lhs == rhs);
571}
572
573inline
574bool ball::operator!=(const AttributeContainerList& lhs,
575 const AttributeContainerList& rhs)
576{
577 return !(lhs == rhs);
578}
579
580inline
581bsl::ostream& ball::operator<<(bsl::ostream& output,
582 const AttributeContainerList& rhs)
583{
584 return rhs.print(output, 0, -1);
585}
586
587
588
589#endif
590
591// ----------------------------------------------------------------------------
592// Copyright 2015 Bloomberg Finance L.P.
593//
594// Licensed under the Apache License, Version 2.0 (the "License");
595// you may not use this file except in compliance with the License.
596// You may obtain a copy of the License at
597//
598// http://www.apache.org/licenses/LICENSE-2.0
599//
600// Unless required by applicable law or agreed to in writing, software
601// distributed under the License is distributed on an "AS IS" BASIS,
602// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
603// See the License for the specific language governing permissions and
604// limitations under the License.
605// ----------------------------- END-OF-FILE ----------------------------------
606
607/** @} */
608/** @} */
609/** @} */
Definition ball_attributecontainerlist.h:168
AttributeContainerListIterator()
Create an uninitialized iterator.
Definition ball_attributecontainerlist.h:440
const AttributeContainer * operator*() const
Definition ball_attributecontainerlist.h:489
friend bool operator==(const AttributeContainerListIterator &, const AttributeContainerListIterator &)
~AttributeContainerListIterator()=default
Destroy this object.
bool valid() const
Definition ball_attributecontainerlist.h:495
AttributeContainerListIterator & operator=(const AttributeContainerListIterator &rhs)
Definition ball_attributecontainerlist.h:462
AttributeContainerListIterator operator++()
Definition ball_attributecontainerlist.h:480
Definition ball_attributecontainerlist.h:271
bsl::allocator< char > allocator_type
Definition ball_attributecontainerlist.h:274
BSLMF_NESTED_TRAIT_DECLARATION(AttributeContainerList, bslma::UsesBslmaAllocator)
iterator end() const
Definition ball_attributecontainerlist.h:538
iterator pushFront(const AttributeContainer *container)
AttributeContainerList()
Definition ball_attributecontainerlist.h:506
int numContainers() const
Definition ball_attributecontainerlist.h:544
iterator begin() const
Definition ball_attributecontainerlist.h:532
AttributeContainerListIterator iterator
An iterator over this list.
Definition ball_attributecontainerlist.h:294
allocator_type get_allocator() const
Definition ball_attributecontainerlist.h:551
bool hasValue(const Attribute &value) const
AttributeContainerList & operator=(const AttributeContainerList &rhs)
AttributeContainerList(const AttributeContainerList &original, const allocator_type &allocator=allocator_type())
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
void remove(const iterator &element)
~AttributeContainerList()
Destroy this object.
Definition ball_attributecontainerlist.h:524
Definition ball_attributecontainer.h:426
Definition ball_attribute.h:199
Definition bslma_bslallocator.h:588
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition ball_administration.h:214
bsl::ostream & operator<<(bsl::ostream &output, const Attribute &attribute)
bool operator!=(const Attribute &lhs, const Attribute &rhs)
bool operator==(const Attribute &lhs, const Attribute &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition ball_attributecontainerlist.h:418
AttributeContainerList_Node ** d_prevNextAddr_p
Definition ball_attributecontainerlist.h:425
const AttributeContainer * d_value_p
Definition ball_attributecontainerlist.h:420
AttributeContainerList_Node * d_next_p
Definition ball_attributecontainerlist.h:423
Definition bslma_usesbslmaallocator.h:344