BDE 4.14.0 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. The behavior
210 /// is undefined if this iterator is empty.
212
213 /// Copy this iterator, increment, and return by value the copy that was
214 /// made prior to the increment. The behavior is undefined if this
215 /// iterator is empty.
217
218 // ACCESSORS
219
220 /// Return a pointer to the `TYPE` object referred to by this iterator.
221 /// The behavior is undefined if this iterator is empty.
222 pointer operator->() const;
223
224 /// Return a const reference to the `TYPE` object referred to by this
225 /// iterator. The behavior is undefined if this iterator is empty.
226 reference operator*() const;
227};
228
229// FREE OPERATORS
230
231/// Return `true` if the specified `lhs` and `rhs` refer to the same `TYPE`
232/// object and `false` othersise.
233template <class TYPE>
234inline
236 const InputIterator<TYPE>& rhs);
237
238/// Return `true` if the specified `lhs` and `rhs` do not refer to the same
239/// `TYPE` object and `false` othersise.
240template <class TYPE>
241inline
243 const InputIterator<TYPE>& rhs);
244
245 // =======================
246 // class InputIteratorUtil
247 // =======================
248
249/// This namespace `struct` allows the easy creation of `begin` and `end`
250/// iterators from a variety of contiguous range types. Either the argument
251/// must be an array, or a container that supports the following operations:
252/// * `size()`
253/// * `operator@ref size_t ` (if 0 != size())
254///
255/// and the type `CONTIGUOUS_CONTAINER::value_type`.
257
258 // CLASS METHODS
259
260 /// Return an `InputIterator` referring to the first element of the
261 /// specified `container` or a null iterator if `container` is empty.
262 template <class CONTIGUOUS_CONTAINER>
264 CONTIGUOUS_CONTAINER& container);
265 template <class CONTIGUOUS_CONTAINER>
267 begin(const CONTIGUOUS_CONTAINER& container);
268
269 /// Return an `InputIterator` referring to the first element of the
270 /// specified `array`.
271 template <class TYPE, std::size_t LEN>
272 static InputIterator<TYPE> begin(TYPE (&array)[LEN]);
273 template <class TYPE, std::size_t LEN>
274 static InputIterator<const TYPE> begin(const TYPE (&array)[LEN]);
275
276 /// Return an `InputIterator` referring to after the last element of the
277 /// specified `container` or a null iterator if `container` is empty.
278 template <class CONTIGUOUS_CONTAINER>
280 CONTIGUOUS_CONTAINER& container);
281 template <class CONTIGUOUS_CONTAINER>
283 const CONTIGUOUS_CONTAINER& container);
284
285 /// Return an `InputIterator` referring to after the last element of the
286 /// specified `array`.
287 template <class TYPE, std::size_t LEN>
288 static InputIterator<TYPE> end(TYPE (&array)[LEN]);
289 template <class TYPE, std::size_t LEN>
290 static InputIterator<const TYPE> end(const TYPE (&array)[LEN]);
291};
292
293// ============================================================================
294// INLINE DEFINITIONS
295// ============================================================================
296
297 // -------------------
298 // class InputIterator
299 // -------------------
300
301// CREATORS
302template<class TYPE>
303inline
305: d_value_p(0)
306{
307}
308
309template<class TYPE>
310inline
312: d_value_p(ptr)
313{
314}
315
316// MANIPULATORS
317template<class TYPE>
318inline
320{
321 BSLS_ASSERT_SAFE(d_value_p);
322
323 ++d_value_p;
324
325 return *this;
326}
327
328template<class TYPE>
329inline
331{
332 BSLS_ASSERT_SAFE(d_value_p);
333
334 TYPE *prev = d_value_p++;
335 return InputIterator(prev);
336}
337
338// ACCESSORS
339template<class TYPE>
340inline
342{
343 BSLS_ASSERT_SAFE(d_value_p);
344
345 return d_value_p;
346}
347
348template<class TYPE>
349inline
351{
352 BSLS_ASSERT_SAFE(d_value_p);
353
354 return *d_value_p;
355}
356
357} // close package namespace
358
359// FREE OPERATORS
360template <class TYPE>
361inline
364{
365 return lhs.d_value_p == rhs.d_value_p;
366}
367
368template <class TYPE>
369inline
372{
373 return lhs.d_value_p != rhs.d_value_p;
374}
375
376namespace bsltf {
377
378 // -----------------------
379 // class InputIteratorUtil
380 // -----------------------
381
382// CLASS METHODS
383template <class CONTIGUOUS_CONTAINER>
384inline
385InputIterator<typename CONTIGUOUS_CONTAINER::value_type>
386 InputIteratorUtil::begin(CONTIGUOUS_CONTAINER& container)
387{
389 0 == container.size() ? 0 : &container[0]);
390}
391
392template <class CONTIGUOUS_CONTAINER>
394 InputIteratorUtil::begin(const CONTIGUOUS_CONTAINER& container)
395{
397 0 == container.size() ? 0 : &container[0]);
398}
399
400template <class TYPE, std::size_t LEN>
402{
403 return InputIterator<TYPE>(array + 0);
404}
405
406template <class TYPE, std::size_t LEN>
408{
409 return InputIterator<const TYPE>(array + 0);
410}
411
412template <class CONTIGUOUS_CONTAINER>
414 InputIteratorUtil::end(CONTIGUOUS_CONTAINER& container)
415{
417 0 == container.size() ? 0 : &container[0] + container.size());
418}
419
420template <class CONTIGUOUS_CONTAINER>
422 InputIteratorUtil::end(const CONTIGUOUS_CONTAINER& container)
423{
425 0 == container.size() ? 0 : &container[0] + container.size());
426}
427
428template <class TYPE, std::size_t LEN>
430{
431 return InputIterator<TYPE>(array + LEN);
432}
433
434template <class TYPE, std::size_t LEN>
436{
437 return InputIterator<const TYPE>(array + LEN);
438}
439
440} // close package namespace
441
442
443#endif
444
445// ----------------------------------------------------------------------------
446// Copyright 2021 Bloomberg Finance L.P.
447//
448// Licensed under the Apache License, Version 2.0 (the "License");
449// you may not use this file except in compliance with the License.
450// You may obtain a copy of the License at
451//
452// http://www.apache.org/licenses/LICENSE-2.0
453//
454// Unless required by applicable law or agreed to in writing, software
455// distributed under the License is distributed on an "AS IS" BASIS,
456// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
457// See the License for the specific language governing permissions and
458// limitations under the License.
459// ----------------------------- END-OF-FILE ----------------------------------
460
461/** @} */
462/** @} */
463/** @} */
Definition bsltf_inputiterator.h:162
TYPE & reference
Definition bsltf_inputiterator.h:174
InputIterator()
Construct an empty input iterator.
Definition bsltf_inputiterator.h:304
reference operator*() const
Definition bsltf_inputiterator.h:350
TYPE * pointer
Definition bsltf_inputiterator.h:173
InputIterator & operator++()
Definition bsltf_inputiterator.h:319
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:341
TYPE value_type
Definition bsltf_inputiterator.h:171
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
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:256
static InputIterator< typename CONTIGUOUS_CONTAINER::value_type > end(CONTIGUOUS_CONTAINER &container)
Definition bsltf_inputiterator.h:414
static InputIterator< typename CONTIGUOUS_CONTAINER::value_type > begin(CONTIGUOUS_CONTAINER &container)
Definition bsltf_inputiterator.h:386