BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsltf_inputiterator.h
Go to the documentation of this file.
1/// @file bsltf_inputiterator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsltf_inputiterator.h -*-C++-*-
8#ifndef INCLUDED_BSLTF_INPUTITERATOR
9#define INCLUDED_BSLTF_INPUTITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsltf_inputiterator bsltf_inputiterator
15/// @brief Provide a pure input iterator capable of traversing a range.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsltf
19/// @{
20/// @addtogroup bsltf_inputiterator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsltf_inputiterator-purpose"> Purpose</a>
25/// * <a href="#bsltf_inputiterator-classes"> Classes </a>
26/// * <a href="#bsltf_inputiterator-description"> Description </a>
27/// * <a href="#bsltf_inputiterator-usage"> Usage </a>
28/// * <a href="#bsltf_inputiterator-example-1-basic-use-of-bsltf-inputiterator"> Example 1: Basic Use of bsltf::InputIterator: </a>
29///
30/// # Purpose {#bsltf_inputiterator-purpose}
31/// Provide a pure input iterator capable of traversing a range.
32///
33/// # Classes {#bsltf_inputiterator-classes}
34///
35/// - bsltf::InputIterator: empty input iterator template
36///
37/// # Description {#bsltf_inputiterator-description}
38/// This components provides a value-semantic `class`,
39/// `bsltf::InputIterator`, that defines an input iterator that supports the
40/// following operations:
41///
42/// * Obj& operator++()
43/// * Obj operator++(int)
44/// * pointer operator->() const
45/// * reference& operator*() const
46///
47/// The iterator is initializable with either a pointer into a range, or a
48/// non-pointer iterator over a contiguous range.
49///
50/// This iterator type is typically used to check algorithms for compatibility
51/// with input iterators. The goal is to make sure that their code is able to
52/// compile and work even with the most restrictive input iterator.
53///
54/// ## Usage {#bsltf_inputiterator-usage}
55///
56///
57/// This section illustrates intended use of this component.
58///
59/// ### Example 1: Basic Use of bsltf::InputIterator: {#bsltf_inputiterator-example-1-basic-use-of-bsltf-inputiterator}
60///
61///
62/// In the following example we use a `bsltf::InputIterator` to test that an
63/// aggregation function compiles and works when instantiated with a pure input
64/// iterator.
65///
66/// First, we define a function `sum` that accepts two input iterators and
67/// returns the sum of all elements in range specified by them:
68/// @code
69/// template <class IN_ITER>
70/// double sum(IN_ITER first, IN_ITER last)
71/// // Return the sum of the 'double's in the specified range
72/// // '[ first, last )'.
73/// {
74/// double total = 0;
75/// while (first != last) {
76/// total += *first++;
77/// }
78/// return total;
79/// }
80/// @endcode
81/// Then, in `main`, we define an array of `double`s and define `InputIterators`
82/// pointing to the beginning and ending of it, initializing the iterators with
83/// pointers:
84/// @code
85/// static double myArray[] = { 2.5, 3, 5, 7, 11.5, 5 };
86/// enum { k_MY_ARRAY_LEN = sizeof myArray / sizeof *myArray };
87///
88/// typedef bsltf::InputIterator<const double> Iter;
89///
90/// Iter begin(myArray + 0), end(myArray + k_MY_ARRAY_LEN);
91/// @endcode
92/// Next, we call `sum` with the two iterators, and observe that its yields the
93/// expected result, and because it compiles, we know that `sum` did not attempt
94/// any operations on the iterators other than those defined for the most basic
95/// input iterator:
96/// @code
97/// const double x = sum(begin, end);
98/// assert(34.0 == x);
99/// @endcode
100/// Then, we illustrate that we can just make `begin` and `end` iterators from
101/// the array directly with the `begin` and `end` class methods of the
102/// `InputIteratorUtil` class.
103/// @code
104/// typedef bsltf::InputIteratorUtil Util;
105///
106/// const double y = sum(Util::begin(myArray), Util::end(myArray));
107/// assert(34.0 == y);
108/// @endcode
109/// Now, we make an `std::vector` containing the elements of `myArray`:
110/// @code
111/// const std::vector<double> v(myArray + 0, myArray + k_MY_ARRAY_LEN);
112/// @endcode
113/// Finally, we call `sum` using, again, the `begin` and `end` class methods to
114/// create iterators for it directly from our `vector`:
115/// @code
116/// const double z = sum(Util::begin(v), Util::end(v));
117/// assert(34.0 == z);
118/// @endcode
119/// @}
120/** @} */
121/** @} */
122
123/** @addtogroup bsl
124 * @{
125 */
126/** @addtogroup bsltf
127 * @{
128 */
129/** @addtogroup bsltf_inputiterator
130 * @{
131 */
132
133#include <bslscm_version.h>
134
135#include <bsls_assert.h>
136#include <bsls_libraryfeatures.h>
137
138#include <cstddef>
139#include <iterator>
140
141
142namespace bsltf {
143
144 // ===================
145 // class InputIterator
146 // ===================
147
148#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
149// Sun CC workaround: iterators must be derived from 'std::iterator' to work
150// with the native std library algorithms. However, 'std::iterator' is
151// deprecated in C++17, so do not rely on derivation unless required, to avoid
152// deprecation warnings on modern compilers.
153
154template <class TYPE>
155class InputIterator : public std::iterator<std::input_iterator_tag,
156 TYPE,
157 std::ptrdiff_t,
158 TYPE *,
159 TYPE> {
160#else
161template <class TYPE>
163#endif
164 // Provide an input iterator that iterates that can iterate over a
165 // contiguous range of object while supporting no operations other than
166 // those defined for 'LegacyInputIterator'.
167
168 public:
169 // PUBLIC TYPES
170 typedef std::input_iterator_tag iterator_category;
171 typedef TYPE value_type;
172 typedef std::ptrdiff_t difference_type;
173 typedef TYPE *pointer;
174 typedef TYPE& reference;
175
176 private:
177 // DATA
178 TYPE *d_value_p;
179
180 // FRIENDS
181 template <class TYPE2>
183 const InputIterator<TYPE2>&);
184 template <class TYPE2>
186 const InputIterator<TYPE2>&);
187
188 public:
189 // CREATORS
190
191 /// Construct an empty input iterator.
193
194 /// Construct an input iterator based on the specified `ptr`.
195 explicit InputIterator(TYPE *ptr);
196
197 // InputIterator(const InputIterator& original) = default;
198 // Construct a copy of the specified 'original' object.
199
200 // ~InputIterator() = default;
201 // Destroy this object.
202
203 // MANIPULATORS
204 // InputIterator& operator=(const InputIterator& rhs) = default;
205 // Assign to this object the value of the specified 'rhs' and return a
206 // reference to this modifiable object.
207
208 /// Increment this iterator to refer to the next contiguous `TYPE`
209 /// object, and return a reference to after the increment.
210 ///
211 /// \pre The behavior is undefined if this iterator is empty.
213
214 /// Copy this iterator, increment, and return by value the copy that was made prior to the increment.
215 ///
216 /// \pre The behavior is undefined if this
217 /// iterator is empty.
219
220 // ACCESSORS
221
222 /// Return a pointer to the `TYPE` object referred to by this iterator.
223 ///
224 /// \pre The behavior is undefined if this iterator is empty.
225 pointer operator->() const;
226
227 /// Return a const reference to the `TYPE` object referred to by this iterator.
228 ///
229 /// \pre The behavior is undefined if this iterator is empty.
230 reference operator*() const;
231};
232
233// FREE OPERATORS
234
235/// Return `true` if the specified `lhs` and `rhs` refer to the same `TYPE`
236/// object and `false` othersise.
237template <class TYPE>
238inline
240 const InputIterator<TYPE>& rhs);
241
242/// Return `true` if the specified `lhs` and `rhs` do not refer to the same
243/// `TYPE` object and `false` othersise.
244template <class TYPE>
245inline
247 const InputIterator<TYPE>& rhs);
248
249 // =======================
250 // class InputIteratorUtil
251 // =======================
252
253/// This namespace `struct` allows the easy creation of `begin` and `end`
254/// iterators from a variety of contiguous range types. Either the argument
255/// must be an array, or a container that supports the following operations:
256/// * `size()`
257/// * `operator@ref size_t ` (if 0 != size())
258///
259/// and the type `CONTIGUOUS_CONTAINER::value_type`.
260///
261/// See @ref bsltf_inputiterator
263
264 // CLASS METHODS
265
266 /// Return an `InputIterator` referring to the first element of the
267 /// specified `container` or a null iterator if `container` is empty.
268 template <class CONTIGUOUS_CONTAINER>
270 CONTIGUOUS_CONTAINER& container);
271 template <class CONTIGUOUS_CONTAINER>
273 begin(const CONTIGUOUS_CONTAINER& container);
274
275 /// Return an `InputIterator` referring to the first element of the
276 /// specified `array`.
277 template <class TYPE, std::size_t LEN>
278 static InputIterator<TYPE> begin(TYPE (&array)[LEN]);
279 template <class TYPE, std::size_t LEN>
280 static InputIterator<const TYPE> begin(const TYPE (&array)[LEN]);
281
282 /// Return an `InputIterator` referring to after the last element of the
283 /// specified `container` or a null iterator if `container` is empty.
284 template <class CONTIGUOUS_CONTAINER>
286 CONTIGUOUS_CONTAINER& container);
287 template <class CONTIGUOUS_CONTAINER>
289 const CONTIGUOUS_CONTAINER& container);
290
291 /// Return an `InputIterator` referring to after the last element of the
292 /// specified `array`.
293 template <class TYPE, std::size_t LEN>
294 static InputIterator<TYPE> end(TYPE (&array)[LEN]);
295 template <class TYPE, std::size_t LEN>
296 static InputIterator<const TYPE> end(const TYPE (&array)[LEN]);
297};
298
299// ============================================================================
300// INLINE DEFINITIONS
301// ============================================================================
302
303 // -------------------
304 // class InputIterator
305 // -------------------
306
307// CREATORS
308template<class TYPE>
309inline
311: d_value_p(0)
312{
313}
314
315template<class TYPE>
316inline
318: d_value_p(ptr)
319{
320}
321
322// MANIPULATORS
323template<class TYPE>
324inline
326{
327 BSLS_ASSERT_SAFE(d_value_p);
328
329 ++d_value_p;
330
331 return *this;
332}
333
334template<class TYPE>
335inline
337{
338 BSLS_ASSERT_SAFE(d_value_p);
339
340 TYPE *prev = d_value_p++;
341 return InputIterator(prev);
342}
343
344// ACCESSORS
345template<class TYPE>
346inline
348{
349 BSLS_ASSERT_SAFE(d_value_p);
350
351 return d_value_p;
352}
353
354template<class TYPE>
355inline
357{
358 BSLS_ASSERT_SAFE(d_value_p);
359
360 return *d_value_p;
361}
362
363} // close package namespace
364
365// FREE OPERATORS
366template <class TYPE>
367inline
370{
371 return lhs.d_value_p == rhs.d_value_p;
372}
373
374template <class TYPE>
375inline
378{
379 return lhs.d_value_p != rhs.d_value_p;
380}
381
382namespace bsltf {
383
384 // -----------------------
385 // class InputIteratorUtil
386 // -----------------------
387
388// CLASS METHODS
389template <class CONTIGUOUS_CONTAINER>
390inline
391InputIterator<typename CONTIGUOUS_CONTAINER::value_type>
392 InputIteratorUtil::begin(CONTIGUOUS_CONTAINER& container)
393{
395 0 == container.size() ? 0 : &container[0]);
396}
397
398template <class CONTIGUOUS_CONTAINER>
400 InputIteratorUtil::begin(const CONTIGUOUS_CONTAINER& container)
401{
403 0 == container.size() ? 0 : &container[0]);
404}
405
406template <class TYPE, std::size_t LEN>
408{
409 return InputIterator<TYPE>(array + 0);
410}
411
412template <class TYPE, std::size_t LEN>
414{
415 return InputIterator<const TYPE>(array + 0);
416}
417
418template <class CONTIGUOUS_CONTAINER>
420 InputIteratorUtil::end(CONTIGUOUS_CONTAINER& container)
421{
423 0 == container.size() ? 0 : &container[0] + container.size());
424}
425
426template <class CONTIGUOUS_CONTAINER>
428 InputIteratorUtil::end(const CONTIGUOUS_CONTAINER& container)
429{
431 0 == container.size() ? 0 : &container[0] + container.size());
432}
433
434template <class TYPE, std::size_t LEN>
436{
437 return InputIterator<TYPE>(array + LEN);
438}
439
440template <class TYPE, std::size_t LEN>
442{
443 return InputIterator<const TYPE>(array + LEN);
444}
445
446} // close package namespace
447
448
449#endif
450
451// ----------------------------------------------------------------------------
452// Copyright 2021 Bloomberg Finance L.P.
453//
454// Licensed under the Apache License, Version 2.0 (the "License");
455// you may not use this file except in compliance with the License.
456// You may obtain a copy of the License at
457//
458// http://www.apache.org/licenses/LICENSE-2.0
459//
460// Unless required by applicable law or agreed to in writing, software
461// distributed under the License is distributed on an "AS IS" BASIS,
462// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
463// See the License for the specific language governing permissions and
464// limitations under the License.
465// ----------------------------- END-OF-FILE ----------------------------------
466
467/** @} */
468/** @} */
469/** @} */
Definition bsltf_inputiterator.h:162
TYPE & reference
Definition bsltf_inputiterator.h:174
InputIterator()
Construct an empty input iterator.
Definition bsltf_inputiterator.h:310
reference operator*() const
Definition bsltf_inputiterator.h:356
TYPE * pointer
Definition bsltf_inputiterator.h:173
InputIterator & operator++()
Definition bsltf_inputiterator.h:325
std::ptrdiff_t difference_type
Definition bsltf_inputiterator.h:172
std::input_iterator_tag iterator_category
Definition bsltf_inputiterator.h:170
friend bool operator==(const InputIterator< TYPE2 > &, const InputIterator< TYPE2 > &)
friend bool operator!=(const InputIterator< TYPE2 > &, const InputIterator< TYPE2 > &)
pointer operator->() const
Definition bsltf_inputiterator.h:347
TYPE value_type
Definition bsltf_inputiterator.h:171
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#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 bsltf_allocargumenttype.h:92
bool operator!=(const AllocBitwiseMoveableTestType &lhs, const AllocBitwiseMoveableTestType &rhs)
bool operator==(const AllocBitwiseMoveableTestType &lhs, const AllocBitwiseMoveableTestType &rhs)
Definition bsltf_inputiterator.h:262
static InputIterator< typename CONTIGUOUS_CONTAINER::value_type > end(CONTIGUOUS_CONTAINER &container)
Definition bsltf_inputiterator.h:420
static InputIterator< typename CONTIGUOUS_CONTAINER::value_type > begin(CONTIGUOUS_CONTAINER &container)
Definition bsltf_inputiterator.h:392