BDE 4.14.0 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. The behavior is undefined
207 /// unless the iterator is at a valid position in the list.
209
210 /// Advance this iterator to the next attribute container in the list
211 /// and return the value of the iterator prior to this method call.
212 /// The behavior is undefined unless the iterator is at a valid
213 /// position in the list.
215
216 // ACCESSORS
217
218 /// Return the address of the non-modifiable attribute container at
219 /// which this iterator is positioned. The behavior is undefined unless
220 /// this iterator is at a valid position in the list.
221 const AttributeContainer *operator*() const;
222
223 /// Return `true` if this iterator is at a valid position in the
224 /// sequence of `AttributeContainer` addresses and `false` otherwise.
225 bool valid() const;
226};
227
228// FREE OPERATORS
229
230/// Return `true` if the specified `lhs` and the specified `rhs` iterators
231/// have the same value and `false` otherwise. Two iterators have the same
232/// value if they refer to the same position in the same list, or if both
233/// iterators are at an invalid position in the list (i.e., the "end" of the
234/// list, or the default constructed value).
235bool operator==(const AttributeContainerListIterator& lhs,
237
238/// Return `true` if the specified `lhs` and the specified `rhs` iterators
239/// do not have the same value and `false` otherwise. Two iterators do not
240/// have the same value if they differ in either the list to which they
241/// refer or the position in the list object.
242bool operator!=(const AttributeContainerListIterator& lhs,
244
245 // ============================
246 // class AttributeContainerList
247 // ============================
248
249/// This class provides an in-core value-semantic list of
250/// `AttributeContainer` object addresses. Attribute container addresses
251/// are added to this list using `pushFront()`, which returns an iterator
252/// located at the new element. A `AttributeContainerList::iterator` object
253/// remains valid until the element referred to by the iterator is removed.
254/// Attribute container addresses can be removed using either `remove()`,
255/// `removeAll()`, or `removeAllAndRelease()`. This list object attempts to
256/// minimize the number of memory allocations it requires by placing the
257/// memory for elements that have been released in a free memory store, and
258/// re-using the memory when new elements are added. The `removeAll()`
259/// removes all the elements from the list, but does not release any
260/// allocated memory (placing it in the free store). The
261/// `removeAllAndRelease()` operation removes all elements and releases all
262/// allocated memory. Note that maintaining a free store is important for
263/// this component because the expectation is that elements will be both
264/// added and removed frequently.
265///
266/// See @ref ball_attributecontainerlist
268 public:
269 // TYPES
271
272 private:
273 // PRIVATE TYPES
275
276 // DATA
277 Node *d_head_p; // head of the linked list of elements
278 Node *d_free_p; // head of the free store
279 int d_length; // length of the list
280 allocator_type d_allocator; // allocator
281
282 public:
283 // TRAITS
286
287 // PUBLIC TYPES
288
289 /// An iterator over this list.
291
292 // CREATORS
293
295 /// Create an empty container list. Optionally specify an `allocator`
296 /// (e.g., the address of a `bslma::Allocator` object) to supply memory;
297 /// otherwise, the default allocator is used.
298 explicit AttributeContainerList(const allocator_type& allocator);
299
300 /// Create a container list having the same value as the specified
301 /// `original`. Optionally specify an `allocator` (e.g., the address of
302 /// a `bslma::Allocator` object) to supply memory; otherwise, the
303 /// default allocator is used.
305 const AttributeContainerList& original,
306 const allocator_type& allocator = allocator_type());
307
308 /// Destroy this object.
310
311 // MANIPULATORS
312
313 /// Assign this container list the value of the specified `rhs` one, and
314 /// return a reference to this list.
316
317 /// Prepend the address of the specified `container` to this list of
318 /// attribute container addresses, and return an iterator located at
319 /// the newly added list element.
321
322 /// Remove the specified `element` from this list. The behavior is
323 /// undefined unless `element` is a valid iterator on this list and the
324 /// referenced address has not previously been removed (by either
325 /// `remove()`, `removeAll()`, or `removeAllAndRelease()`.
326 void remove(const iterator& element);
327
328 /// Remove all the elements from this list. After this operation
329 /// returns, `numContainers()` will be 0. This operation adds all the
330 /// allocated memory to an internal free store, and does not deallocate
331 /// any memory.
332 void removeAll();
333
334 /// Remove all the elements from this list and deallocate any allocated
335 /// memory.
337
338 // ACCESSORS
339
340 /// Return an iterator positioned at the beginning of the list of
341 /// `AttributeContainer` object addresses represented by this object.
342 iterator begin() const;
343
344 /// Return an iterator positioned one past the final
345 /// `AttributeContainer` object address in the list of addresses
346 /// represented by this object.
347 iterator end() const;
348
349 /// Return the number of attribute container addresses currently in
350 /// this list.
351 int numContainers() const;
352
353 /// Return `true` if the attribute having specified `value` exists in
354 /// any of the attribute containers referred to by this object, and
355 /// `false` otherwise.
356 bool hasValue(const Attribute& value) const;
357
358 /// Format this object to the specified output `stream` at the
359 /// (absolute value of) the optionally specified indentation `level`
360 /// and return a reference to `stream`. If `level` is specified,
361 /// optionally specify `spacesPerLevel`, the number of spaces per
362 /// indentation level for this and all of its nested objects. If
363 /// `level` is negative, suppress indentation of the first line. If
364 /// `spacesPerLevel` is negative, format the entire output on one line,
365 /// suppressing all but the initial indentation (as governed by
366 /// `level`). If `stream` is not valid on entry, this operation has no
367 /// effect.
368 bsl::ostream& print(bsl::ostream& stream,
369 int level = 0,
370 int spacesPerLevel = 4) const;
371
372 // Aspects
373
374 /// Return the allocator used by this object to supply memory. Note
375 /// that if no allocator was supplied at construction the default
376 /// allocator in effect at construction is used.
378};
379
380// FREE OPERATORS
381
382/// Return `true` if the specified `lhs` and `rhs` lists have the same
383/// value, and `false` otherwise. Two lists have the same value if they
384/// have the same number of attribute container addresses, and the address
385/// at each index position have the same value.
386bool operator==(const AttributeContainerList& lhs,
387 const AttributeContainerList& rhs);
388
389/// Return `true` if the specified `lhs` and `rhs` lists do not have the
390/// same value, and `false` otherwise. Two lists do not have the same
391/// value if have differing numbers of attribute container addresses or any
392/// of the addresses at corresponding indices have different values.
393inline
394bool operator!=(const AttributeContainerList& lhs,
395 const AttributeContainerList& rhs);
396
397/// Write a formatted description of the specified `rhs` to the specified
398/// `stream` and return a reference to the modifiable `stream`.
399inline
400bsl::ostream& operator<<(bsl::ostream& output,
401 const AttributeContainerList& rhs);
402
403 // =================================
404 // class AttributeContainerList_Node
405 // =================================
406
407/// This is an implementation type of `AttributeContainerList` and should
408/// not be used by clients of this package. A `AttributeContainerList_Node`
409/// represents a node in a `AttributeContainerList` object.
411
412 const AttributeContainer *d_value_p; // address value of this
413 // element
414
416
418 // address of previous
419 // element's next pointer
420};
421
422// ============================================================================
423// INLINE DEFINITIONS
424// ============================================================================
425
426 // ------------------------------------
427 // class AttributeContainerListIterator
428 // ------------------------------------
429
430// CREATORS
431inline
436
437inline
443
444inline
446 const AttributeContainerListIterator& original)
447: d_node_p(original.d_node_p)
448{
449}
450
451// MANIPULATORS
452inline
456{
457 d_node_p = rhs.d_node_p;
458 return *this;
459}
460
461inline
464{
465 Node *current = d_node_p;
466 d_node_p = d_node_p->d_next_p;
467 return AttributeContainerListIterator(current);
468}
469
470inline
473{
474 d_node_p = d_node_p->d_next_p;
475 return AttributeContainerListIterator(d_node_p);
476}
477
478// ACCESSORS
479inline
480const AttributeContainer *
482{
483 return d_node_p->d_value_p;
484}
485
486inline
488{
489 return 0 != d_node_p;
490}
491
492 // ============================
493 // class AttributeContainerList
494 // ============================
495
496// CREATORS
497inline
499: d_head_p(0)
500, d_free_p(0)
501, d_length(0)
502, d_allocator()
503{
504}
505
506inline
508: d_head_p(0)
509, d_free_p(0)
510, d_length(0)
511, d_allocator(allocator)
512{
513}
514
515inline
520
521// ACCESSORS
522inline
525{
526 return iterator(d_head_p);
527}
528
529inline
534
535inline
537{
538 return d_length;
539}
540
541inline
544{
545 return d_allocator;
546}
547
548} // close package namespace
549
550// FREE OPERATORS
551inline
552bool ball::operator==(const AttributeContainerListIterator& lhs,
553 const AttributeContainerListIterator& rhs)
554{
555 return lhs.d_node_p == rhs.d_node_p;
556}
557
558inline
559bool ball::operator!=(const AttributeContainerListIterator& lhs,
560 const AttributeContainerListIterator& rhs)
561{
562 return !(lhs == rhs);
563}
564
565inline
566bool ball::operator!=(const AttributeContainerList& lhs,
567 const AttributeContainerList& rhs)
568{
569 return !(lhs == rhs);
570}
571
572inline
573bsl::ostream& ball::operator<<(bsl::ostream& output,
574 const AttributeContainerList& rhs)
575{
576 return rhs.print(output, 0, -1);
577}
578
579
580
581#endif
582
583// ----------------------------------------------------------------------------
584// Copyright 2015 Bloomberg Finance L.P.
585//
586// Licensed under the Apache License, Version 2.0 (the "License");
587// you may not use this file except in compliance with the License.
588// You may obtain a copy of the License at
589//
590// http://www.apache.org/licenses/LICENSE-2.0
591//
592// Unless required by applicable law or agreed to in writing, software
593// distributed under the License is distributed on an "AS IS" BASIS,
594// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
595// See the License for the specific language governing permissions and
596// limitations under the License.
597// ----------------------------- END-OF-FILE ----------------------------------
598
599/** @} */
600/** @} */
601/** @} */
Definition ball_attributecontainerlist.h:168
AttributeContainerListIterator()
Create an uninitialized iterator.
Definition ball_attributecontainerlist.h:432
const AttributeContainer * operator*() const
Definition ball_attributecontainerlist.h:481
friend bool operator==(const AttributeContainerListIterator &, const AttributeContainerListIterator &)
~AttributeContainerListIterator()=default
Destroy this object.
bool valid() const
Definition ball_attributecontainerlist.h:487
AttributeContainerListIterator & operator=(const AttributeContainerListIterator &rhs)
Definition ball_attributecontainerlist.h:454
AttributeContainerListIterator operator++()
Definition ball_attributecontainerlist.h:472
Definition ball_attributecontainerlist.h:267
bsl::allocator< char > allocator_type
Definition ball_attributecontainerlist.h:270
BSLMF_NESTED_TRAIT_DECLARATION(AttributeContainerList, bslma::UsesBslmaAllocator)
iterator end() const
Definition ball_attributecontainerlist.h:530
iterator pushFront(const AttributeContainer *container)
AttributeContainerList()
Definition ball_attributecontainerlist.h:498
int numContainers() const
Definition ball_attributecontainerlist.h:536
iterator begin() const
Definition ball_attributecontainerlist.h:524
AttributeContainerListIterator iterator
An iterator over this list.
Definition ball_attributecontainerlist.h:290
allocator_type get_allocator() const
Definition ball_attributecontainerlist.h:543
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:516
Definition ball_attributecontainer.h:426
Definition ball_attribute.h:198
Definition bslma_bslallocator.h:580
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
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)
Definition ball_attributecontainerlist.h:410
AttributeContainerList_Node ** d_prevNextAddr_p
Definition ball_attributecontainerlist.h:417
const AttributeContainer * d_value_p
Definition ball_attributecontainerlist.h:412
AttributeContainerList_Node * d_next_p
Definition ball_attributecontainerlist.h:415
Definition bslma_usesbslmaallocator.h:343