BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_bidirectionaliterator.h
Go to the documentation of this file.
1/// @file bslstl_bidirectionaliterator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_bidirectionaliterator.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_BIDIRECTIONALITERATOR
9#define INCLUDED_BSLSTL_BIDIRECTIONALITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_bidirectionaliterator bslstl_bidirectionaliterator
15/// @brief Provide a template to create STL-compliant bidirectional iterators.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_bidirectionaliterator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_bidirectionaliterator-purpose"> Purpose</a>
25/// * <a href="#bslstl_bidirectionaliterator-classes"> Classes </a>
26/// * <a href="#bslstl_bidirectionaliterator-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_bidirectionaliterator-description"> Description </a>
28/// * <a href="#bslstl_bidirectionaliterator-usage"> Usage </a>
29/// * <a href="#bslstl_bidirectionaliterator-example-1-defining-a-standard-compliant-bidirectional-iterator"> Example 1: Defining a Standard Compliant Bidirectional Iterator </a>
30///
31/// # Purpose {#bslstl_bidirectionaliterator-purpose}
32/// Provide a template to create STL-compliant bidirectional iterators.
33///
34/// # Classes {#bslstl_bidirectionaliterator-classes}
35///
36/// - bslstl::BidirectionalIterator: bidirectional iterator template
37///
38/// # Canonical Header {#bslstl_bidirectionaliterator-canonical-header}
39/// bsl_iterator.h
40///
41/// @see bslstl_iterator, bslstl_forwarditerator,
42/// bslstl_randomaccessiterator
43///
44/// # Description {#bslstl_bidirectionaliterator-description}
45/// This component provides an iterator adaptor that, given an
46/// implementation class defining a core set of iterator functionality specified
47/// in the class level documentation, adapts it to provide an STL-compliant
48/// bidirectional iterator interface. `bslstl::BidirectionalIterator` meets the
49/// requirements of a bidirectional iterator described in the C++11 standard
50/// [24.2.7] under the tag "[bidirectional.iterators]". Include bsl_iterator.h
51/// to use this component.
52///
53/// ## Usage {#bslstl_bidirectionaliterator-usage}
54///
55///
56/// In this section we show intended use of this component.
57///
58/// ### Example 1: Defining a Standard Compliant Bidirectional Iterator {#bslstl_bidirectionaliterator-example-1-defining-a-standard-compliant-bidirectional-iterator}
59///
60///
61/// Suppose we want to create a standard compliant bidirectional access iterator
62/// for a container.
63///
64/// First, we define an iterator, `MyArrayIterator`, that meets the requirements
65/// of the `IMP_ITER` template parameter of `BidirectionalIterator` class (see
66/// class level documentation), but does not meet the full set of requirements
67/// for a bidirectional iterator as defined by the C++ standard. Note that the
68/// following shows only the public interface required. Private members and
69/// additional methods that may be needed to implement this class are elided in
70/// this example:
71/// @code
72/// /// This class implements the minimal requirements to implement a
73/// /// bidirectional iterator using `bslstl::BidirectionalIterator`.
74/// template <class VALUE>
75/// class MyArrayIterator {
76///
77/// public:
78/// // CREATORS
79///
80/// /// Create a `MyArrayIterator` object that does not refer to any
81/// /// value.
82/// MyArrayIterator();
83///
84/// /// Create a `MyArrayIterator` object having the same value
85/// /// as the specified `original` object.
86/// MyArrayIterator(const MyArrayIterator& original);
87///
88/// /// Destroy this object;
89/// ~MyArrayIterator();
90///
91/// // MANIPULATORS
92///
93/// /// Assign to this object the value of the specified `rhs` object,
94/// /// and return a reference providing modifiable access to this
95/// /// object.
96/// MyArrayIterator& operator=(const MyArrayIterator& rhs);
97///
98/// /// Increment this object to refer to the next element in an array.
99/// void operator++();
100///
101/// /// Decrement this object to refer to the previous element in an
102/// /// array.
103/// void operator--();
104///
105/// // ACCESSORS
106///
107/// // Return a reference providing modifiable access to the value (of
108/// // the parameterized `VALUE` type) of the element referred to by
109/// // this object.
110/// VALUE& operator*() const;
111/// };
112///
113/// template <class VALUE>
114/// bool operator==(const MyArrayIterator<VALUE>&,
115/// const MyArrayIterator<VALUE>&);
116/// @endcode
117/// Notice that `MyArrayIterator` does not implement a complete standard
118/// compliant bidirectional iterator. It is missing methods such as `operator+`
119/// and `operator[]`.
120///
121/// Then, we define the interface for our container class template,
122/// `MyFixedSizeArray`. The implementation of the interface is elided for
123/// brevity:
124/// @code
125/// /// This class implements a container that contains the parameterized
126/// /// `SIZE` number of elements of the parameterized `VALUE` type.
127/// template <class VALUE, int SIZE>
128/// class MyFixedSizeArray {
129///
130/// // DATA
131/// VALUE d_array[SIZE]; // storage of the container
132///
133/// public:
134/// // PUBLIC TYPES
135/// typedef VALUE value_type;
136/// @endcode
137/// Now, we use `BidirectionalIterator` to create a standard compliant iterator
138/// for this container:
139/// @code
140/// typedef bslstl::BidirectionalIterator<VALUE,
141/// MyArrayIterator<VALUE> > iterator;
142/// typedef bslstl::BidirectionalIterator<const VALUE,
143/// MyArrayIterator<VALUE> >
144/// const_iterator;
145/// @endcode
146/// Notice that the implementation for `const_iterator` is
147/// `MyArrayIterator<VALUE>` and *not* `MyArrayIterator<const VALUE>`.
148///
149/// Next, we continue defining the rest of the class.
150/// @code
151/// // CREATORS
152///
153/// /// Create a `MyFixedSizeArray` object having the parameterized
154/// /// `SIZE` number of elements of the parameterized type `VALUE`.
155/// //! MyFixedSizeArray() = default;
156///
157/// /// Create a `MyFixedSizeArray` object having same number of
158/// /// elements as that of the specified `original`, the same value of
159/// /// each element as that of corresponding element in `original`.
160/// //! MyFixedSizeArray(const MyFixedSizeArray& original) = default;
161///
162/// /// Destroy this object.
163/// //! ~MyFixedSizeArray() = default;
164///
165/// // MANIPULATORS
166///
167/// /// Return a bidirectional iterator providing modifiable access to
168/// /// the first valid element of this object.
169/// iterator begin();
170///
171/// /// Return a bidirectional iterator providing modifiable access to
172/// /// the last valid element of this object.
173/// iterator end();
174///
175/// /// Return a reference providing modifiable access to the element at
176/// /// the specified `position`.
177/// VALUE& operator[](int position);
178///
179/// // ACCESSORS
180///
181/// /// Return a bidirectional iterator providing non-modifiable access
182/// /// to the first valid element of this object.
183/// const_iterator begin() const;
184///
185/// /// Return a bidirectional iterator providing non-modifiable access
186/// /// to the last valid element of this object.
187/// const_iterator end() const;
188///
189/// /// Return a reference providing non-modifiable access to the
190/// /// specified `i`th element in this object.
191/// const VALUE& operator[](int position) const;
192/// };
193/// @endcode
194/// Then, we create a `MyFixedSizeArray` and initialize its elements:
195/// @code
196/// MyFixedSizeArray<int, 5> fixedArray;
197/// fixedArray[0] = 1;
198/// fixedArray[1] = 2;
199/// fixedArray[2] = 3;
200/// fixedArray[3] = 4;
201/// fixedArray[4] = 5;
202/// @endcode
203/// Finally, to show that `MyFixedSizeArray::iterator` can be used as a
204/// bidirectional iterator, we invoke a function that takes bidirectional
205/// iterators as parameters, such as `std::reverse`, on the `begin` and `end`
206/// iterators and verify the results:
207/// @code
208/// std::reverse(fixedArray.begin(), fixedArray.end());
209///
210/// assert(fixedArray[0] == 5);
211/// assert(fixedArray[1] == 4);
212/// assert(fixedArray[2] == 3);
213/// assert(fixedArray[3] == 2);
214/// assert(fixedArray[4] == 1);
215/// @endcode
216/// @}
217/** @} */
218/** @} */
219
220/** @addtogroup bsl
221 * @{
222 */
223/** @addtogroup bslstl
224 * @{
225 */
226/** @addtogroup bslstl_bidirectionaliterator
227 * @{
228 */
229
230#include <bslscm_version.h>
231
233#include <bslstl_iterator.h>
234
235#include <bslmf_removecv.h>
236
237#include <iterator>
238
239#include <cstddef> // 'ptrdiff_t'
240
241
242
243namespace bslstl {
244
245 //============================
246 // class BidirectionalIterator
247 //============================
248
249/// Given an `ITER_IMP` type that implements a minimal subset of an iterator
250/// interface, this template generates a complete iterator that meets all of
251/// the requirements of a "bidirectional iterator" in the C++ standard. If
252/// `T` is `const`-qualified, then the resulting type is a constant
253/// iterator. `T` shall not be a function, reference type or void.
254/// `ITER_IMP` must provide public operations so that, for objects `i` and
255/// `j` of type `ITER_IMP`, the following operations are supported:
256/// @code
257/// ITER_IMP i; default construction
258/// ITER_IMP j(i); copy construction
259/// i = j assignment
260/// ++i increment to next element
261/// --i decrement to previous element
262/// i == j // convertible to bool equality comparison
263/// *i // reference convertible to T& element access (dereference)
264/// @endcode
265template <class T, class ITER_IMP, class TAG_TYPE =
266 std::bidirectional_iterator_tag>
268 : public ForwardIterator<T, ITER_IMP, TAG_TYPE> {
269
270 // PRIVATE TYPES
271 typedef typename bsl::remove_cv<T>::type UnCvqT; // value type without
272 // 'const' and
273 // 'volatile'
274 // qualifications
275
278
279 public:
280 // TYPES
281 typedef UnCvqT value_type;
282 typedef std::ptrdiff_t difference_type;
283 typedef T *pointer;
284 typedef T& reference;
285 typedef std::bidirectional_iterator_tag iterator_category;
286
287 // CREATORS
288
289 /// Construct the default value for this iterator type. All default-
290 /// constructed `BidirectionalIterator` objects represent
291 /// non-dereferenceable iterators into the same empty range. They do
292 /// not have a singular value unless an object of the type specified by
293 /// the template parameter `ITER_IMP` has a singular value after
294 /// value-initialization.
296
297 /// Construct a bidirectional iterator having the specified
298 /// `implementation` of the parameterized `ITER_IMP` type.
299 BidirectionalIterator(const ITER_IMP& implementation); // IMPLICIT
300
301 // Construct a bidirectional iterator having the same value as the
302 // `original` iterator. Note that this method's definition is compiler
303 // generated.
305
306 /// Construct a bidirectional iterator from the specified `other`
307 /// iterator of another (compatible) `BidirectionalIterator` type, e.g., a mutable iterator of the same type.
308 ///
309 /// \note Note that this constructor may
310 /// be the copy constructor (inhibiting the implicit declaration of a
311 /// copy constructor above), or may be an additional overload.
312 BidirectionalIterator(const BidirectionalNonConstIterator& other);
313
314
315 /// Destroy this iterator.
316 /// \note Note that this method's definition is
317 /// compiler generated.
319
320 // MANIPULATORS
321
322 /// Copy the value of the specified `rhs` to this iterator. Return a reference to this modifiable object.
323 ///
324 /// \note Note that this method's
325 /// definition is compiler generated.
327
328 /// Copy the value of the specified `rhs` of another (compatible)
329 /// `BidirectionalIterator` type, (e.g., a mutable iterator of the same
330 /// type) to this iterator. Return a reference to this modifiable object.
331 ///
332 /// \note Note that this method may be the copy-assignment operator
333 /// (inhibiting the implicit declaration of a copy-assignment operator
334 /// above), or may be an additional overload.
335 BidirectionalIterator& operator=(const BidirectionalNonConstIterator& rhs);
336
337 /// Increment to the next element. Return a reference to this modifiable iterator.
338 ///
339 /// \pre The behavior is undefined if, on entry, this
340 /// iterator has the past-the-end value for an iterator over the
341 /// underlying sequence.
343
344 /// Decrement to the previous element. Return a reference to this modifiable iterator.
345 ///
346 /// \pre The behavior is undefined if, on entry, this
347 /// iterator has the same value as an iterator the refers to the start
348 /// of the underlying sequence.
350};
351
352// FREE OPERATORS
353
354/// Return `true` if the specified `lhs` iterator has the same value as the
355/// specified `rhs` iterator, and `false` otherwise. Two iterators have the
356/// same value if they refer to the same element, or both have the past-the- end value for the underlying sequence.
357///
358/// \pre The behavior is undefined unless
359/// both iterators refer to the same underlying sequence.
360template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
363
364/// Return `true` if the specified `lhs` iterator does not have the same
365/// value as the specified `rhs` iterator, and `false` otherwise. Two
366/// iterators do not have the same value if (1) they do not refer to the
367/// same element and (2) both do not have the past-the-end iterator value for the underlying sequence.
368///
369/// \pre The behavior is undefined unless both
370/// iterators refer to the same underlying sequence.
371template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
374
375/// Increment the specified `iter` to the next element. Return the previous value of `iter`.
376///
377/// \pre The behavior is undefined if, on entry, `iter` has the
378/// past-the-end value for an iterator of the underlying sequence.
379template <class T, class ITER_IMP, class TAG_TYPE>
382
383/// Decrement the specified `iter` to the previous element. Return the previous value of `iter`.
384///
385/// \pre The behavior is undefined if, on entry,
386/// `iter` has the same value as an iterator to the start of the underlying
387/// sequence.
388template <class T, class ITER_IMP, class TAG_TYPE>
391
392// ============================================================================
393// INLINE FUNCTION DEFINITIONS
394// ============================================================================
395
396 //----------------------------
397 // class BidirectionalIterator
398 //----------------------------
399
400// CREATORS
401template <class T, class ITER_IMP, class TAG_TYPE>
402inline
407
408template <class T, class ITER_IMP, class TAG_TYPE>
409inline
411BidirectionalIterator(const ITER_IMP& implementation)
412: ForwardIterator<T,ITER_IMP,TAG_TYPE>(implementation)
413{
414}
415
416template <class T, class ITER_IMP, class TAG_TYPE>
417inline
423
424// MANIPULATORS
425template <class T, class ITER_IMP, class TAG_TYPE>
426inline
434
435
436template <class T, class ITER_IMP, class TAG_TYPE>
437inline
440{
441 ++this->imp();
442 return *this;
443}
444
445template <class T, class ITER_IMP, class TAG_TYPE>
446inline
449{
450 --this->imp();
451 return *this;
452}
453
454} // close package namespace
455
456// FREE OPERATORS
457template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
458inline
459bool bslstl::operator==(const BidirectionalIterator<T1,ITER_IMP,TAG_TYPE>& lhs,
460 const BidirectionalIterator<T2,ITER_IMP,TAG_TYPE>& rhs)
461{
462 return lhs.imp() == rhs.imp();
463}
464
465template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
466inline
467bool bslstl::operator!=(const BidirectionalIterator<T1,ITER_IMP,TAG_TYPE>& lhs,
468 const BidirectionalIterator<T2,ITER_IMP,TAG_TYPE>& rhs)
469{
470 return !(lhs == rhs);
471}
472
473template <class T, class ITER_IMP, class TAG_TYPE>
474inline
476bslstl::operator++(BidirectionalIterator<T,ITER_IMP,TAG_TYPE>& iter, int)
477{
478 BidirectionalIterator<T,ITER_IMP,TAG_TYPE> tmp(iter);
479 ++iter;
480 return tmp;
481}
482
483template <class T, class ITER_IMP, class TAG_TYPE>
484inline
486bslstl::operator--(BidirectionalIterator<T,ITER_IMP,TAG_TYPE>& iter, int)
487{
488 BidirectionalIterator<T,ITER_IMP,TAG_TYPE> tmp(iter);
489 --iter;
490 return tmp;
491}
492
493
494
495#endif
496
497// ----------------------------------------------------------------------------
498// Copyright 2013 Bloomberg Finance L.P.
499//
500// Licensed under the Apache License, Version 2.0 (the "License");
501// you may not use this file except in compliance with the License.
502// You may obtain a copy of the License at
503//
504// http://www.apache.org/licenses/LICENSE-2.0
505//
506// Unless required by applicable law or agreed to in writing, software
507// distributed under the License is distributed on an "AS IS" BASIS,
508// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
509// See the License for the specific language governing permissions and
510// limitations under the License.
511// ----------------------------- END-OF-FILE ----------------------------------
512
513/** @} */
514/** @} */
515/** @} */
Definition bslstl_bidirectionaliterator.h:268
UnCvqT value_type
Definition bslstl_bidirectionaliterator.h:281
BidirectionalIterator()
Definition bslstl_bidirectionaliterator.h:403
BidirectionalIterator & operator--()
Definition bslstl_bidirectionaliterator.h:448
T & reference
Definition bslstl_bidirectionaliterator.h:284
BidirectionalIterator(const BidirectionalNonConstIterator &other)
Definition bslstl_bidirectionaliterator.h:418
BidirectionalIterator & operator=(const BidirectionalIterator &rhs)
BidirectionalIterator & operator=(const BidirectionalNonConstIterator &rhs)
Definition bslstl_bidirectionaliterator.h:428
std::bidirectional_iterator_tag iterator_category
Definition bslstl_bidirectionaliterator.h:285
BidirectionalIterator & operator++()
Definition bslstl_bidirectionaliterator.h:439
BidirectionalIterator(const BidirectionalIterator &original)
T * pointer
Definition bslstl_bidirectionaliterator.h:283
std::ptrdiff_t difference_type
Definition bslstl_bidirectionaliterator.h:282
BidirectionalIterator(const ITER_IMP &implementation)
Definition bslstl_bidirectionaliterator.h:411
Definition bslstl_forwarditerator.h:171
ForwardIterator & operator=(const ForwardIterator &rhs)
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition bslstl_algorithm.h:84
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)
bool operator==(const BidirectionalIterator< T1, ITER_IMP, TAG_TYPE > &lhs, const BidirectionalIterator< T2, ITER_IMP, TAG_TYPE > &rhs)
bool operator!=(const BidirectionalIterator< T1, ITER_IMP, TAG_TYPE > &lhs, const BidirectionalIterator< T2, ITER_IMP, TAG_TYPE > &rhs)
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:128