BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_treeiterator.h
Go to the documentation of this file.
1/// @file bslstl_treeiterator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_treeiterator.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_TREEITERATOR
9#define INCLUDED_BSLSTL_TREEITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_treeiterator bslstl_treeiterator
15/// @brief Provide an STL compliant iterator for a tree of `TreeNode` objects.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_treeiterator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_treeiterator-purpose"> Purpose</a>
25/// * <a href="#bslstl_treeiterator-classes"> Classes </a>
26/// * <a href="#bslstl_treeiterator-description"> Description </a>
27/// * <a href="#bslstl_treeiterator-usage"> Usage </a>
28/// * <a href="#bslstl_treeiterator-example-1-navigating-a-tree-using-treeiterator"> Example 1: Navigating a Tree Using TreeIterator </a>
29///
30/// # Purpose {#bslstl_treeiterator-purpose}
31/// Provide an STL compliant iterator for a tree of `TreeNode` objects.
32///
33/// # Classes {#bslstl_treeiterator-classes}
34///
35/// - bslstl::TreeIterator: an STL compliant bidirectional binary tree iterator
36///
37/// @see bslstl_treenode, bslalg_rbtreeutil, bslstl_map
38///
39/// # Description {#bslstl_treeiterator-description}
40/// This component provides an STL-compliant bidirectional iterator
41/// over a binary tree of `bslstl::TreeNode` objects. The requirements of a
42/// bidirectional STL iterator are outlined in the C++11 standard in section
43/// [24.2.6] under the tag [bidirectional.iterators]. A `TreeIterator` object
44/// is parameterized on `VALUE`, `NODE`, and `DIFFERENCE_TYPE`. The
45/// parameterized `VALUE` indicates the type of the value value to which this
46/// iterator provides a references, and may be const-qualified for
47/// const-iterators. The parameterized `NODE` indicates the type of the node
48/// objects in this tree. Note that `NODE` is not necessarily `TreeNode<VALUE>`
49/// as `VALUE` may be const-qualified. Finally, the parameterized
50/// `DIFFERENCE_TYPE` determines the, standard required, @ref difference_type for
51/// the iterator. `NODE` must derives from `bslalg::RbTreeNode`, and contains a
52/// `value` method that returns a reference providing modifiable access to a
53/// type that is convertible to the parameterized `VALUE` (e.g., a
54/// `bslstl::TreeNode` object).
55///
56/// ## Usage {#bslstl_treeiterator-usage}
57///
58///
59/// In this section we show intended use of this component.
60///
61/// ### Example 1: Navigating a Tree Using TreeIterator {#bslstl_treeiterator-example-1-navigating-a-tree-using-treeiterator}
62///
63///
64/// In the following example we create a simple tree and then use a
65/// `TreeIterator` to navigate its elements.
66///
67/// First, we define a type `IntNode` for the nodes of our tree. `IntNode`
68/// inherits from `bslalg::RbTreeNode` (allowing it to be operated on by
69/// `bslalg::RbTreeUtil`), and supplies an integer payload:
70/// @code
71/// class IntNode : public bslalg::RbTreeNode {
72/// // DATA
73/// int d_value; // actual value represented by the node
74///
75/// public:
76/// // MANIPULATORS
77/// int& value() { return d_value; }
78/// // Return a reference providing modifiable access to the 'value' of
79/// // this object.
80///
81/// // ACCESSORS
82/// const int& value() const { return d_value; }
83/// // Return a reference providing non-modifiable access to the
84/// // 'value' of this object.
85/// };
86/// @endcode
87/// Then, we define a comparison function for `IntNode` objects. This type is
88/// designed to be supplied to functions in `bslalg::RbTreeUtil`:
89/// @code
90/// class IntNodeComparator {
91/// public:
92/// // CREATORS
93/// IntNodeComparator() {}
94/// // Create a node-value comparator.
95///
96/// // ACCESSORS
97/// bool operator()(const bslalg::RbTreeNode& node, int value) const {
98/// return static_cast<const IntNode&>(node).value() < value;
99/// }
100///
101/// bool operator()(int value, const bslalg::RbTreeNode& node) const {
102/// return value < static_cast<const IntNode&>(node).value();
103/// }
104/// };
105/// @endcode
106/// Next, we define the signature of the example function where we will
107/// navigate a tree using a `TreeIterator`:
108/// @code
109/// void exampleTreeNavigationFunction()
110/// {
111/// @endcode
112/// Then, we define a `bslalg::RbTreeAnchor` object to hold our tree, and a
113/// series of nodes that we will use to populate the tree:
114/// @code
115/// enum { NUM_NODES = 5 };
116///
117/// bslalg::RbTreeAnchor tree;
118/// IntNode nodes[NUM_NODES];
119/// @endcode
120/// Next, we assign values to each of the `nodes` and insert them into `tree`
121/// using `bslalg::RbTreeUtil`, supplying the `insert` function an instance of
122/// the comparator we defined earlier:
123/// @code
124/// for (int i = 0; i < NUM_NODES; ++i) {
125/// nodes[i].value() = i;
126/// bslalg::RbTreeUtil::insert(&tree, IntNodeComparator(), &nodes[i]);
127/// }
128///
129/// assert(5 == tree.numNodes());
130/// @endcode
131/// Then, we create a type alias for a `TreeIterator` providing non-modifiable
132/// access to elements in the tree. Note that in this instance, the iterator
133/// must provide non-modifiable access as modifying the key value for a node
134/// would invalidate ordering of the binary search tree:
135/// @code
136/// typedef TreeIterator<const int, IntNode, std::ptrdiff_t>
137/// ConstTreeIterator;
138/// @endcode
139/// Now, we create an instance of the `TreeIterator` and use it to navigate the
140/// elements of `tree`, printing their values to the console:
141/// @code
142/// ConstTreeIterator iterator(tree.firstNode());
143/// ConstTreeIterator endIterator(tree.sentinel());
144/// for (; iterator != endIterator; ++iterator) {
145/// printf("Node value: %d\n", *iterator);
146/// }
147/// }
148/// @endcode
149/// Finally, we observe the following console output:
150/// @code
151/// Node value: 0
152/// Node value: 1
153/// Node value: 2
154/// Node value: 3
155/// Node value: 4
156/// @endcode
157/// @}
158/** @} */
159/** @} */
160
161/** @addtogroup bsl
162 * @{
163 */
164/** @addtogroup bslstl
165 * @{
166 */
167/** @addtogroup bslstl_treeiterator
168 * @{
169 */
170
171#include <bslscm_version.h>
172
173#include <bslstl_iterator.h>
174
175#include <bslalg_rbtreenode.h>
176#include <bslalg_rbtreeutil.h>
177
178#include <bslmf_enableif.h>
179#include <bslmf_isconvertible.h>
180#include <bslmf_issame.h>
182#include <bslmf_removecv.h>
183
184#include <bsls_assert.h>
185#include <bsls_libraryfeatures.h>
186#include <bsls_platform.h>
187#include <bsls_util.h>
188
189#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
190#include <bslmf_removecvq.h>
191#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDE
192
193
194namespace bslstl {
195
196 // ==================
197 // class TreeIterator
198 // ==================
199
200/// This class provides an STL-conforming bidirectional iterator over the
201/// ordered `bslalg::RbTreeNode` objects in a binary tree (see section
202/// [24.2.6 bidirectional.iterators] of the C++11 standard). A
203/// `TreeIterator` provides access to values of the parameterized `VALUE`,
204/// over a binary tree composed of nodes of the parameterized `NODE` (which
205/// must derive from `bslalg::RbTreeNode`). The parameterized
206/// `DIFFERENCE_TYPE` determines the standard required @ref difference_type of
207/// the iterator, without requiring access to the allocator-traits for the
208/// node. The behavior of the `operator*` method is undefined unless the
209/// iterator is at a valid position in the tree (i.e., not the `end`) and
210/// the referenced element has not been removed since the iterator was
211/// constructed. `NODE` must derives from `bslalg::RbTreeNode`, and
212/// contains a `value` method that returns a reference providing modifiable
213/// access to a type that is convertible to the parameterized `VALUE` (e.g.,
214/// a `bslstl::TreeNode` object).
215template <class VALUE, class NODE, class DIFFERENCE_TYPE>
217#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
218 : public std::iterator<std::bidirectional_iterator_tag, VALUE>
219// On Solaris just to keep studio12-v4 happy, since algorithms takes only
220// iterators inheriting from 'std::iterator'.
221#endif
222{
223
224 // PRIVATE TYPES
225 typedef typename bsl::remove_cv<VALUE>::type NcType;
227
228 // DATA
229 bslalg::RbTreeNode *d_node_p; // current iterator position
230
231 private:
232 // FRIENDS
233 template <class VALUE1, class VALUE2, class NODEPTR, class DIFF>
236#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
237 template <class VALUE1, class VALUE2, class NODEPTR, class DIFF>
240#endif
241
242 template <class OTHER_VALUE, class OTHER_NODE, class OTHER_DIFFERENCE_TYPE>
243 friend class TreeIterator;
244
245 public:
246 // PUBLIC TYPES
247 typedef bsl::bidirectional_iterator_tag iterator_category;
248 typedef NcType value_type;
249 typedef DIFFERENCE_TYPE difference_type;
250 typedef VALUE* pointer;
251
252 /// Standard iterator defined types [24.4.2].
253 typedef VALUE& reference;
254
255 // CREATORS
256
257 /// Create an uninitialized iterator.
258 TreeIterator();
259
260 /// Create an iterator at the specified `position`. The behavior is
261 /// undefined unless `node` is of the parameterized `NODE`, which is
262 /// derived from 'bslalg::RbTreeNode. Note that this constructor is an
263 /// implementation detail and is not part of the C++ standard.
264 explicit TreeIterator(const bslalg::RbTreeNode *node);
265
266#ifndef BSLS_PLATFORM_CMP_SUN
267 /// Create an iterator at the same position as the specified `original`
268 /// iterator. Note that this constructor enables converting from
269 /// modifiable to const iterator types.
270 template <class NON_CONST_ITERATOR>
272 const NON_CONST_ITERATOR& original,
273 typename bsl::enable_if<bsl::is_convertible<NON_CONST_ITERATOR,
274 NcIter>::value,
275 int>::type = 0)
276 : d_node_p(static_cast<const NcIter&>(original).d_node_p)
277 {
278 // This constructor template must be defined inline inside the
279 // class definition, as Microsoft Visual C++ does not recognize the
280 // definition as matching this signature when placed out-of-line.
281 }
282#else
283 TreeIterator(const NcIter& original)
284 // Create an iterator at the same position as the specified 'original'
285 // iterator. Note that this constructor enables converting from
286 // modifiable to const iterator types.
287 : d_node_p(original.d_node_p)
288 {
289 }
290
291#endif
292
293 TreeIterator(const TreeIterator& original) = default;
294 // Create an iterator having the same value as the specified
295 // 'original'. Note that this operation is either defined by the
296 // constructor taking 'NcIter' (if 'NcType' is the same as 'VALUE'), or
297 // generated automatically by the compiler. Also note that this
298 // construct cannot be defined explicitly (without using
299 // @ref bsls_enableif ) to avoid a duplicate declaration when 'NcType' is
300 // the same as 'VALUE'.
301
302 ~TreeIterator() = default;
303 // Destroy this object.
304
305 // MANIPULATORS
306 TreeIterator& operator=(const TreeIterator& rhs) = default;
307 // Assign to this object the value of the specified 'rhs' object, and
308 // a return a reference providing modifiable access to this object.
309
310 /// Move this iterator to the next element in the tree and return a
311 /// reference providing modifiable access to this iterator. The
312 /// behavior is undefined unless the iterator refers to an element in
313 /// the tree.
315
316 /// Move this iterator to the previous element in the tree and return a
317 /// reference providing modifiable access to this iterator. The
318 /// behavior is undefined unless the iterator refers to the past-the-end
319 /// address or the non-leftmost element in the tree.
321
322 // ACCESSORS
323
324 /// Return a reference providing modifiable access to the value (of the
325 /// parameterized `VALUE`) of the element at which this iterator is
326 /// positioned. The behavior is undefined unless this iterator is at a
327 /// valid position in the tree.
328 reference operator*() const;
329
330 /// Return the address of the value (of the parameterized `VALUE`) of
331 /// the element at which this iterator is positioned. The behavior is
332 /// undefined unless this iterator is at a valid position in the tree.
333 pointer operator->() const;
334
335 /// Return the address of the non-modifiable tree node at which this
336 /// iterator is positioned, or 0 if this iterator is not at a valid
337 /// position in the tree. Note that this method is an implementation
338 /// detail and is not part of the C++ standard.
339 const bslalg::RbTreeNode *node() const;
340};
341
342// FREE OPERATORS
343
344/// Return `true` if the specified `lhs` and the specified `rhs` iterators
345/// have the same value and `false` otherwise. Two iterators have the same
346/// value if they refer to the same position in the same tree, or if both
347/// iterators are at an invalid position in the tree (i.e., the `end` of the
348/// tree, or the default constructed value).
349template <class VALUE1, class VALUE2, class NODEPTR, class DIFF>
350bool operator==(const TreeIterator<VALUE1, NODEPTR, DIFF>& lhs,
352
353#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
354/// Return `true` if the specified `lhs` and the specified `rhs` iterators
355/// do not have the same value and `false` otherwise. Two iterators do not
356/// have the same value if they differ in either the tree to which they
357/// refer or the position in that tree.
358template <class VALUE1, class VALUE2, class NODEPTR, class DIFF>
359bool operator!=(const TreeIterator<VALUE1, NODEPTR, DIFF>& lhs,
361#endif
362
363/// Move the specified `iter` to the next element in the tree and return the
364/// value of `iter` prior to this call. The behavior is undefined unless
365/// the iterator refers to an element in the tree.
366template <class VALUE, class NODE, class DIFFERENCE_TYPE>
369
370/// Move the specified `iter` to the previous element in the tree and return
371/// the value of `iter` prior to this call. The behavior is undefined
372/// unless the iterator refers to the past-the-end or the non-leftmost
373/// element in the tree.
374template <class VALUE, class NODE, class DIFFERENCE_TYPE>
377
378// ============================================================================
379// TEMPLATE AND INLINE FUNCTION DEFINITIONS
380// ============================================================================
381
382 // ------------------
383 // class TreeIterator
384 // ------------------
385
386// CREATORS
387template <class VALUE, class NODE, class DIFFERENCE_TYPE>
388inline
393
394template <class VALUE, class NODE, class DIFFERENCE_TYPE>
395inline
398: d_node_p(const_cast<bslalg::RbTreeNode *>(node))
399{
400}
401
402// MANIPULATORS
403template <class VALUE, class NODE, class DIFFERENCE_TYPE>
404inline
407{
408 d_node_p = bslalg::RbTreeUtil::next(d_node_p);
409 return *this;
410}
411
412template <class VALUE, class NODE, class DIFFERENCE_TYPE>
413inline
416{
417 d_node_p = bslalg::RbTreeUtil::previous(d_node_p);
418 return *this;
419}
420
421// ACCESSORS
422template <class VALUE, class NODE, class DIFFERENCE_TYPE>
423inline
426{
427 BSLS_ASSERT_SAFE(d_node_p);
428
429 return static_cast<NODE *>(d_node_p)->value();
430}
431
432template <class VALUE, class NODE, class DIFFERENCE_TYPE>
433inline
436{
437 BSLS_ASSERT_SAFE(d_node_p);
438
439 return bsls::Util::addressOf(static_cast<NODE *>(d_node_p)->value());
440}
441
442template <class VALUE, class NODE, class DIFFERENCE_TYPE>
443inline
446{
447 return d_node_p;
448}
449
450// FREE OPERATORS
451template <class VALUE1, class VALUE2, class NODEPTR, class DIFF>
452inline
453bool operator==(const TreeIterator<VALUE1, NODEPTR, DIFF>& lhs,
455{
456 return lhs.d_node_p == rhs.d_node_p;
457}
458
459#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
460template <class VALUE1, class VALUE2, class NODEPTR, class DIFF>
461inline
462bool operator!=(const TreeIterator<VALUE1, NODEPTR, DIFF>& lhs,
464{
465 return lhs.d_node_p != rhs.d_node_p;
466}
467#endif
468
469template <class VALUE, class NODE, class DIFFERENCE_TYPE>
470inline
473{
475 ++iter;
476 return temp;
477}
478
479template <class VALUE, class NODE, class DIFFERENCE_TYPE>
480inline
481TreeIterator<VALUE, NODE, DIFFERENCE_TYPE>
483{
485 --iter;
486 return temp;
487}
488
489} // close package namespace
490
491
492#ifndef BSLS_PLATFORM_CMP_SUN
493# ifndef BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
494namespace bsl {
495
496template <class VALUE, class NODE, class DIFFERENCE_TYPE>
498 BloombergLP::bslstl::TreeIterator<VALUE, NODE, DIFFERENCE_TYPE> >
500};
501
502} // close namespace bsl
503# endif // BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
504#endif // BSLS_PLATFORM_CMP_SUN
505
506#endif
507
508// ----------------------------------------------------------------------------
509// Copyright 2019 Bloomberg Finance L.P.
510//
511// Licensed under the Apache License, Version 2.0 (the "License");
512// you may not use this file except in compliance with the License.
513// You may obtain a copy of the License at
514//
515// http://www.apache.org/licenses/LICENSE-2.0
516//
517// Unless required by applicable law or agreed to in writing, software
518// distributed under the License is distributed on an "AS IS" BASIS,
519// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
520// See the License for the specific language governing permissions and
521// limitations under the License.
522// ----------------------------- END-OF-FILE ----------------------------------
523
524/** @} */
525/** @} */
526/** @} */
Definition bslalg_rbtreenode.h:376
Definition bslstl_treeiterator.h:222
NcType value_type
Definition bslstl_treeiterator.h:248
DIFFERENCE_TYPE difference_type
Definition bslstl_treeiterator.h:249
TreeIterator(const TreeIterator &original)=default
reference operator*() const
Definition bslstl_treeiterator.h:425
bsl::bidirectional_iterator_tag iterator_category
Definition bslstl_treeiterator.h:247
TreeIterator & operator=(const TreeIterator &rhs)=default
TreeIterator(const NON_CONST_ITERATOR &original, typename bsl::enable_if< bsl::is_convertible< NON_CONST_ITERATOR, NcIter >::value, int >::type=0)
Definition bslstl_treeiterator.h:271
VALUE & reference
Standard iterator defined types [24.4.2].
Definition bslstl_treeiterator.h:253
VALUE * pointer
Definition bslstl_treeiterator.h:250
TreeIterator & operator++()
Definition bslstl_treeiterator.h:406
const bslalg::RbTreeNode * node() const
Definition bslstl_treeiterator.h:445
pointer operator->() const
Definition bslstl_treeiterator.h:435
friend class TreeIterator
Definition bslstl_treeiterator.h:243
friend bool operator==(const TreeIterator< VALUE1, NODEPTR, DIFF > &, const TreeIterator< VALUE2, NODEPTR, DIFF > &)
Definition bslstl_treeiterator.h:453
friend bool operator!=(const TreeIterator< VALUE1, NODEPTR, DIFF > &, const TreeIterator< VALUE2, NODEPTR, DIFF > &)
Definition bslstl_treeiterator.h:462
TreeIterator & operator--()
Definition bslstl_treeiterator.h:415
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlb_printmethods.h:283
Definition bdlc_flathashmap.h:1805
Definition bslstl_algorithm.h:82
BidirectionalIterator< T, ITER_IMP, TAG_TYPE > operator--(BidirectionalIterator< T, ITER_IMP, TAG_TYPE > &iter, int)
BidirectionalIterator< T, ITER_IMP, TAG_TYPE > operator++(BidirectionalIterator< T, ITER_IMP, TAG_TYPE > &iter, int)
Definition bslmf_enableif.h:525
Definition bslmf_isconvertible.h:867
Definition bslmf_istriviallycopyable.h:329
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:126
static const RbTreeNode * previous(const RbTreeNode *node)
static const RbTreeNode * next(const RbTreeNode *node)
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305