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