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