BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_forwarditerator.h
Go to the documentation of this file.
1/// @file bslstl_forwarditerator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_forwarditerator.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_FORWARDITERATOR
9#define INCLUDED_BSLSTL_FORWARDITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_forwarditerator bslstl_forwarditerator
15/// @brief Provide a template to create STL-compliant forward iterators.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_forwarditerator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_forwarditerator-purpose"> Purpose</a>
25/// * <a href="#bslstl_forwarditerator-classes"> Classes </a>
26/// * <a href="#bslstl_forwarditerator-description"> Description </a>
27/// * <a href="#bslstl_forwarditerator-usage"> Usage </a>
28///
29/// # Purpose {#bslstl_forwarditerator-purpose}
30/// Provide a template to create STL-compliant forward iterators.
31///
32/// # Classes {#bslstl_forwarditerator-classes}
33///
34/// - bslstl::ForwardIterator: forward iterator template
35///
36/// **Canonical header:** bsl_iterator.h
37///
38/// @see bslstl_iterator, bslstl_bidirectionaliterator,
39/// bslstl_randomaccessiterator
40///
41/// # Description {#bslstl_forwarditerator-description}
42/// This component provides an iterator adaptor that, given an
43/// implementation class defining a core set of iterator functionality, adapts
44/// it to provide an STL-compliant forward iterator interface. The set of
45/// requirements for a forward iterator is found in "Table 106: Forward iterator
46/// requirements", under the tag "[forward.iterators]". (Note that this
47/// reference is sourced in N3092, a C++0x working paper; the actual table
48/// number may vary in the actual standard.) Include bsl_iterator.h to use this
49/// component.
50///
51/// ## Usage {#bslstl_forwarditerator-usage}
52///
53///
54/// Given the following "iterator-like" implementation class:
55/// @code
56/// template <class T>
57/// class my_IteratorImp {
58/// public:
59/// // CREATORS
60/// my_IteratorImp();
61/// my_IteratorImp(const my_IteratorImp&);
62/// ~my_IteratorImp();
63///
64/// // An additional value-constructor should be supplied that can be
65/// // called by the unspecified container type, providing access to the
66/// // container's internal data structure that is to be iterated over.
67/// // This would typically be called by 'begin' and 'end'.
68///
69/// // MANIPULATORS
70/// my_IteratorImp& operator=(const my_IteratorImp&);
71///
72/// void operator++();
73///
74/// // ACCESSORS
75/// T& operator*() const;
76/// };
77///
78/// template <class T>
79/// bool operator==(const my_IteratorImp<T>& lhs,
80/// const my_IteratorImp<T>& rhs);
81/// @endcode
82/// simply add the following two `typedef`s to any container class that provides
83/// `my_IteratorImp<T>` access, and the container will have STL-compliant
84/// forward iterators:
85/// @code
86/// typedef bslstl::ForwardIterator<T, my_IteratorImp<T> > iterator;
87/// typedef bslstl::ForwardIterator<const T, my_IteratorImp<T> >
88/// const_iterator;
89/// @endcode
90/// Note that the implementation for `const_iterator` is `my_IteratorImp<T>` and
91/// *not* `my_IteratorImp<const T>`, rather the `const` is added to the return
92/// value of `operator*` by way of conversion to the first template argument.
93/// @}
94/** @} */
95/** @} */
96
97/** @addtogroup bsl
98 * @{
99 */
100/** @addtogroup bslstl
101 * @{
102 */
103/** @addtogroup bslstl_forwarditerator
104 * @{
105 */
106
107// DOCUMENTATION IS INCOMPLETE: Note that we need to say something about 'T'
108// and iterator stability. Incrementing two copies of 'T' must produce two
109// iterators that compare equal, and refer to exactly the same object. Without
110// this guarantee, we cannot build the multi-pass property of Forward Iterator,
111// and merely have an Input Iterator. This is not something we can detect at
112// compile time, and is prohibitively expensive to validate at runtime. It is
113// the sort of thing that should be validated by a Forward Iterator test suite,
114// it could be what we really need, in addition to the adapters, is a
115// generalized test case to validate that a type conforms to the iterator
116// requirements.
117
118#include <bslscm_version.h>
119
120#include <bslstl_iterator.h>
121
123#include <bslmf_removecv.h>
124#include <bslmf_util.h>
125
127#include <bsls_libraryfeatures.h>
128#include <bsls_util.h>
129
130#include <cstddef>
131#include <iterator>
132
133
134
135namespace bslstl {
136
137 //======================
138 // class ForwardIterator
139 //======================
140
141/// Given an `ITER_IMP` type that implements a minimal subset of an iterator
142/// interface, this template generates a complete iterator that meets all of
143/// the requirements of a "forward iterator" in the C++ standard. If `T` is
144/// const-qualified, then the resulting type is a const iterator. `T` shall
145/// not be a function, reference type or void. `ITER_IMP` must provide
146/// public operations so that, for objects `i` and `j` of type `ITER_IMP`,
147/// the following operations are supported:
148/// @code
149/// ITER_IMP i; Default construction
150/// ITER_IMP j(i); Copy construction
151/// i = j Assignment
152/// ++i Increment to next element
153/// i == j // convertible to bool Equality comparison
154/// *i // reference convertible to T& Element access (dereference)
155/// @endcode
156template <class T, class ITER_IMP, class TAG_TYPE = std::forward_iterator_tag>
158#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
159// Sun CC workaround: iterators must be derived from 'std::iterator' to work
160// with the native std library algorithms. However, 'std::iterator' is
161// deprecated in C++17, so do not rely on derivation unless required, to avoid
162// deprecation warnings on modern compilers.
163 : public std::iterator<TAG_TYPE,
164 typename bsl::remove_cv<T>::type,
165 std::ptrdiff_t,
166 T *,
167 T&>
168#endif
169{
170
171#if defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE) && \
172 defined(BSLS_COMPILERFEATURES_SUPPORT_STATIC_ASSERT)
173 static_assert(
175 decltype(*bslmf::Util::declval<const ITER_IMP&>())>::value,
176 "Forward iterators must return a true reference to their element when "
177 "dereferenced.");
178#endif
179
180 // PRIVATE TYPES
181 typedef typename bsl::remove_cv<T>::type UnCvqT; // value type without
182 // 'const' and 'volatile'
183 // qualifications
184
187
188 private:
189 // DATA
190 ITER_IMP d_imp; // externally-supplied implementation of iterator
191 // functionality
192
193 public:
194 // TYPES
195 typedef UnCvqT value_type;
196 typedef std::ptrdiff_t difference_type;
197 typedef T *pointer;
198 typedef T& reference;
199 typedef std::forward_iterator_tag iterator_category;
200
201 // CREATORS
202
203 /// Construct the default value for this iterator type. All default-
204 /// constructed `ForwardIterator` objects represent non-dereferenceable
205 /// iterators into the same empty range. They do not have a singular
206 /// value unless an object of the type specified by the template
207 /// parameter `ITER_IMP` has a singular value after
208 /// value-initialization.
210
211 /// Construct a forward iterator having the specified `implementation`
212 /// of the parameterized `ITER_IMP` type.
213 ForwardIterator(const ITER_IMP& implementation);
214
215 /// Create a `ForwardIterator` having the same value as the specified
216 /// `original` iterator. Note that this method's definition is compiler
217 /// generated.
219
220 /// Construct a forward iterator from the specified `other` iterator of
221 /// another (compatible) `ForwardIterator` type, e.g., a mutable
222 /// iterator of the same type. Note that this constructor may be the
223 /// copy constructor (inhibiting the implicit declaration of a copy
224 /// constructor above), or may be an additional overload.
226
227 /// Destroy this iterator. Note that this method's definition is
228 /// compiler generated.
230
231 // MANIPULATORS
232
233 /// Copy the value of the specified `rhs` to this iterator. Return a
234 /// reference to this modifiable object. Note that this method's
235 /// definition is compiler generated.
237
238 /// Copy the value of the specified `rhs` of another (compatible)
239 /// `ForwardIterator` type, (e.g., a mutable iterator of the same type)
240 /// to this iterator. Return a reference to this modifiable object.
241 /// Note that this method may be the copy-assignment operator
242 /// (inhibiting the implicit declaration of a copy-assignment operator
243 /// above), or may be an additional overload.
245
246 /// Increment to the next element. Return a reference to this
247 /// modifiable iterator. The behavior is undefined if, on entry, this
248 /// iterator has the past-the-end value for an iterator over the
249 /// underlying sequence.
251
252 /// Return a modifiable reference to the implementation object.
253 ITER_IMP& imp();
254
255 // ACCESSORS
256
257 /// Return a reference to the current, modifiable element. The behavior
258 /// is undefined if this iterator has the past-the-end value for an
259 /// iterator over the underlying sequence.
260 T& operator*() const;
261
262 /// Return a pointer to the current, modifiable element. The behavior
263 /// is undefined if this iterator has the past-the-end value for an
264 /// iterator over the underlying sequence.
265 T *operator->() const;
266
267 /// Return a non-modifiable reference to the implementation object.
268 const ITER_IMP& imp() const;
269};
270
271// FREE OPERATORS
272
273/// Return `true` if the specified `lhs` iterator has the same value as the
274/// specified `rhs` iterator, and `false` otherwise. Two iterators have the
275/// same value if they refer to the same element, or both have the past-the-
276/// end value for the underlying sequence. The behavior is undefined unless
277/// both iterators refer to the same underlying sequence.
278template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
279bool operator==(const ForwardIterator<T1,ITER_IMP,TAG_TYPE>& lhs,
281
282/// Return `true` if the specified `lhs` iterator does not have the same
283/// value as the specified `rhs` iterator, and `false` otherwise. Two
284/// iterators do not have the same value if (1) they do not refer to the
285/// same element and (2) both do not have the past-the-end iterator value
286/// for the underlying sequence. The behavior is undefined unless both
287/// iterators refer to the same underlying sequence.
288template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
289bool operator!=(const ForwardIterator<T1,ITER_IMP,TAG_TYPE>& lhs,
291
292/// Increment the specified `iter` to the next element. Return the previous
293/// value of `iter`. The behavior is undefined if, on entry, `iter` has the
294/// past-the-end value for an iterator of the underlying sequence.
295template <class T, class ITER_IMP, class TAG_TYPE>
298
299// ============================================================================
300// INLINE FUNCTION DEFINITIONS
301// ============================================================================
302
303 //----------------------
304 // class ForwardIterator
305 //----------------------
306
307// CREATORS
308template <class T, class ITER_IMP, class TAG_TYPE>
309inline
314
315template <class T, class ITER_IMP, class TAG_TYPE>
316inline
318ForwardIterator(const ITER_IMP& implementation)
319: d_imp(implementation)
320{
321}
322
323template <class T, class ITER_IMP, class TAG_TYPE>
324inline
327: d_imp(other.imp())
328{
329}
330
331// MANIPULATORS
332template <class T, class ITER_IMP, class TAG_TYPE>
333inline
336 const ForwardNonConstIterator& rhs)
337{
338 d_imp = rhs.imp();
339 return *this;
340}
341
342template <class T, class ITER_IMP, class TAG_TYPE>
343inline
346{
347 ++this->d_imp;
348 return *this;
349}
350
351template <class T, class ITER_IMP, class TAG_TYPE>
352inline
354{
355 return d_imp;
356}
357
358// ACCESSORS
359template <class T, class ITER_IMP, class TAG_TYPE>
360inline
362{
363 return *d_imp;
364}
365
366template <class T, class ITER_IMP, class TAG_TYPE>
367inline
372
373template <class T, class ITER_IMP, class TAG_TYPE>
374inline
375const ITER_IMP&
377{
378 return d_imp;
379}
380
381} // close package namespace
382
383// FREE OPERATORS
384template <class T, class ITER_IMP, class TAG_TYPE>
385inline
387bslstl::operator++(ForwardIterator<T,ITER_IMP,TAG_TYPE>& iter, int)
388{
389 ForwardIterator<T,ITER_IMP,TAG_TYPE> tmp(iter);
390 ++iter;
391 return tmp;
392}
393
394template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
395inline
396bool bslstl::operator==(const ForwardIterator<T1,ITER_IMP,TAG_TYPE>& lhs,
397 const ForwardIterator<T2,ITER_IMP,TAG_TYPE>& rhs)
398{
399 return lhs.imp() == rhs.imp();
400}
401
402template <class T1, class T2, class ITER_IMP, class TAG_TYPE>
403inline
404bool bslstl::operator!=(const ForwardIterator<T1,ITER_IMP,TAG_TYPE>& lhs,
405 const ForwardIterator<T2,ITER_IMP,TAG_TYPE>& rhs)
406{
407 return !(lhs == rhs);
408}
409
410#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
411// ============================================================================
412// BACKWARD COMPATIBILITY
413// ============================================================================
414
415#ifdef bslstl_ForwardIterator
416#undef bslstl_ForwardIterator
417#endif
418/// This alias is defined for backward compatibility.
419#define bslstl_ForwardIterator bslstl::ForwardIterator
420#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
421
422
423
424#endif
425
426// ----------------------------------------------------------------------------
427// Copyright 2013 Bloomberg Finance L.P.
428//
429// Licensed under the Apache License, Version 2.0 (the "License");
430// you may not use this file except in compliance with the License.
431// You may obtain a copy of the License at
432//
433// http://www.apache.org/licenses/LICENSE-2.0
434//
435// Unless required by applicable law or agreed to in writing, software
436// distributed under the License is distributed on an "AS IS" BASIS,
437// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
438// See the License for the specific language governing permissions and
439// limitations under the License.
440// ----------------------------- END-OF-FILE ----------------------------------
441
442/** @} */
443/** @} */
444/** @} */
Definition bslstl_forwarditerator.h:169
std::ptrdiff_t difference_type
Definition bslstl_forwarditerator.h:196
T & operator*() const
Definition bslstl_forwarditerator.h:361
const ITER_IMP & imp() const
Return a non-modifiable reference to the implementation object.
Definition bslstl_forwarditerator.h:376
ForwardIterator & operator=(const ForwardIterator &rhs)
UnCvqT value_type
Definition bslstl_forwarditerator.h:195
ForwardIterator & operator=(const ForwardNonConstIterator &rhs)
Definition bslstl_forwarditerator.h:335
ForwardIterator(const ForwardNonConstIterator &other)
Definition bslstl_forwarditerator.h:326
T * pointer
Definition bslstl_forwarditerator.h:197
ITER_IMP & imp()
Return a modifiable reference to the implementation object.
Definition bslstl_forwarditerator.h:353
T & reference
Definition bslstl_forwarditerator.h:198
T * operator->() const
Definition bslstl_forwarditerator.h:368
ForwardIterator & operator++()
Definition bslstl_forwarditerator.h:345
ForwardIterator(const ITER_IMP &implementation)
Definition bslstl_forwarditerator.h:318
std::forward_iterator_tag iterator_category
Definition bslstl_forwarditerator.h:199
ForwardIterator()
Definition bslstl_forwarditerator.h:310
ForwardIterator(const ForwardIterator &original)
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
Definition bslstl_algorithm.h:82
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)
Definition bslmf_islvaluereference.h:125
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:126