BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_iterator.h
Go to the documentation of this file.
1/// @file bslstl_iterator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_iterator.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_ITERATOR
9#define INCLUDED_BSLSTL_ITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_iterator bslstl_iterator
15/// @brief Provide basic iterator traits, adaptors, and utilities.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_iterator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_iterator-purpose"> Purpose</a>
25/// * <a href="#bslstl_iterator-classes"> Classes </a>
26/// * <a href="#bslstl_iterator-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_iterator-description"> Description </a>
28/// * <a href="#bslstl_iterator-usage"> Usage </a>
29/// * <a href="#bslstl_iterator-example-1-using-iterators-to-traverse-a-container"> Example 1: Using Iterators to Traverse a Container </a>
30///
31/// # Purpose {#bslstl_iterator-purpose}
32/// Provide basic iterator traits, adaptors, and utilities.
33///
34/// # Classes {#bslstl_iterator-classes}
35///
36/// - bsl::iterator_traits: information about iterator associated types
37/// - bsl::reverse_iterator: bring in `std::reverse_iterator`
38/// - bsl::distance: global function to calculate iterator distance
39///
40/// # Canonical Header {#bslstl_iterator-canonical-header}
41/// bsl_iterator.h
42///
43/// @see bslstl_forwarditerator, bslstl_bidirectionaliterator,
44/// bslstl_randomaccessiterator, C++ Standard
45///
46/// # Description {#bslstl_iterator-description}
47/// This component is for internal use only. Please include
48/// `<bsl_iterator.h>` directly. This component provides the facilities of the
49/// iterators library from the C++ Standard, including iterator primitives
50/// (24.4), iterator adaptors (24.5), and stream iterators (24.6).
51///
52/// ## Usage {#bslstl_iterator-usage}
53///
54///
55/// In this section we show intended use of this component.
56///
57/// ### Example 1: Using Iterators to Traverse a Container {#bslstl_iterator-example-1-using-iterators-to-traverse-a-container}
58///
59///
60/// In this example, we will use the `bsl::iterator` and `bsl::reverse_iterator`
61/// to traverse an iterable container type.
62///
63/// Suppose that we have an iterable container template type `MyFixedSizeArray`.
64/// An instantiation of `MyFixedSizeArray` represents an array having fixed
65/// number of elements, which is a parameter passed to the class constructor
66/// during construction. A traversal of `MyFixedSizeArray` can be accomplished
67/// using basic iterators (pointers) as well as reverse iterators.
68///
69/// First, we create a elided definition of the template container class,
70/// `MyFixedSizeArray`, which provides mutable and constant iterators of
71/// template type `bsl::iterator` and @ref reverse_iterator :
72/// @code
73/// /// This is a container that contains a fixed number of elements. The
74/// /// number of elements is specified upon construction and can not be
75/// /// changed afterwards.
76/// template <class VALUE, int SIZE>
77/// class MyFixedSizeArray
78/// {
79/// // DATA
80/// VALUE d_array[SIZE]; // storage of the container
81///
82/// public:
83/// // PUBLIC TYPES
84/// typedef VALUE value_type;
85/// @endcode
86/// Here, we define mutable and constant iterators and reverse iterators:
87/// @code
88/// typedef VALUE *iterator;
89/// typedef VALUE const *const_iterator;
90/// typedef bsl::reverse_iterator<iterator> reverse_iterator;
91/// typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
92///
93/// // CREATORS
94/// //! MyFixedSizeArray() = default;
95/// // Create a `MyFixedSizeArray` object having the parameterized
96/// // `SIZE` elements of the parameterized type `VALUE`.
97///
98/// //! MyFixedSizeArray(const MyFixedSizeArray& original) = default;
99/// // Create a `MyFixedSizeArray` object having same number of
100/// // elements as that of the specified `rhs`, and the same value of
101/// // each element as that of corresponding element in `rhs`.
102///
103/// //! ~MyFixedSizeArray() = default;
104/// // Destroy this object.
105/// @endcode
106/// Now, we define the `begin` and `end` methods to return basic iterators
107/// (`VALUE*` and `const VALUE*`), and the `rbegin` and `rend` methods to return
108/// reverse iterators (`bsl::reverse_iterator<VALUE*>` and
109/// `bsl::reverse_iterator<const VALUE*>)` type:
110/// @code
111/// // MANIPULATORS
112/// iterator begin();
113/// // Return the basic iterator providing modifiable access to the
114/// // first valid element of this object.
115///
116/// iterator end();
117/// // Return the basic iterator providing modifiable access to the
118/// // position one after the last valid element of this object.
119///
120/// reverse_iterator rbegin();
121/// // Return the reverse iterator providing modifiable access to the
122/// // last valid element of this object.
123///
124/// reverse_iterator rend();
125/// // Return the reverse iterator providing modifiable access to the
126/// // position one before the first valid element of this object.
127///
128/// VALUE& operator[](int i);
129/// // Return the reference providing modifiable access of the
130/// // specified `i`th element of this object.
131///
132/// // ACCESSORS
133/// const_iterator begin() const;
134/// // Return the basic iterator providing non-modifiable access to the
135/// // first valid element of this object.
136///
137/// const_iterator end() const;
138/// // Return the basic iterator providing non-modifiable access to the
139/// // position one after the last valid element of this object.
140///
141/// const_reverse_iterator rbegin() const;
142/// // Return the reverse iterator providing non-modifiable access to
143/// // the last valid element of this object.
144///
145/// const_reverse_iterator rend() const;
146/// // Return the reverse iterator providing non-modifiable access to
147/// // the position one before the first valid element of this object.
148///
149/// int size() const;
150/// // Return the number of elements contained in this object.
151///
152/// const VALUE& operator[](int i) const;
153/// // Return the reference providing non-modifiable access of the
154/// // specified `i`th element of this object.
155/// };
156///
157/// // ...
158/// @endcode
159/// Then, we create a `MyFixedSizeArray` and initialize its elements:
160/// @code
161/// // Create a fixed array having five elements.
162///
163/// MyFixedSizeArray<int, 5> fixedArray;
164///
165/// // Initialize the values of each element in the fixed array.
166///
167/// for (int i = 0; i < fixedArray.size(); ++i) {
168/// fixedArray[i] = i + 1;
169/// }
170/// @endcode
171/// Next, we generate reverse iterators using the `rbegin` and `rend` methods of
172/// the fixed array object:
173/// @code
174/// MyFixedSizeArray<int, 5>::reverse_iterator rstart = fixedArray.rbegin();
175/// MyFixedSizeArray<int, 5>::reverse_iterator rfinish = fixedArray.rend();
176/// @endcode
177/// Now, we note that we could have acquired the iterators and container size by
178/// calling the appropriate free functions:
179/// @code
180/// assert(rstart == bsl::rbegin(fixedArray));
181/// assert(rfinish == bsl::rend( fixedArray));
182///
183/// assert(fixedArray.size() == bsl::size(fixedArray));
184/// assert(rfinish - rstart == bsl::ssize(fixedArray));
185/// @endcode
186/// Finally, we traverse the fixed array again in reverse order using the two
187/// generated reverse iterators:
188/// @code
189/// printf("Traverse array using reverse iterator:\n");
190/// while (rstart != rfinish) {
191/// printf("\tElement: %d\n", *rstart);
192/// ++rstart;
193/// }
194/// @endcode
195/// The preceding loop produces the following output on `stdout`:
196/// @code
197/// Traverse array using reverse iterator:
198/// Element: 5
199/// Element: 4
200/// Element: 3
201/// Element: 2
202/// Element: 1
203/// @endcode
204/// @}
205/** @} */
206/** @} */
207
208/** @addtogroup bsl
209 * @{
210 */
211/** @addtogroup bslstl
212 * @{
213 */
214/** @addtogroup bslstl_iterator
215 * @{
216 */
217
218#include <bslscm_version.h>
219
221#include <bsls_keyword.h>
222#include <bsls_libraryfeatures.h>
223#include <bsls_platform.h>
224
225#include <cstddef>
226#include <iterator>
227
228#if BSLS_COMPILERFEATURES_FULL_CPP11
229 #include <initializer_list>
230 #include <type_traits> // `common_type`, `make_signed`
231#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
232
233#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES) && \
234 defined(BSLS_LIBRARYFEATURES_STDCPP_LLVM) && _LIBCPP_VERSION < 220000
235 // libc++ prior to version 22.0.0 does not provide `std::ranges` objects
236 // for `rbegin`, `crbegin`, `rend`, and `crend` in the <iterator> header
237 // so we must include the full `<ranges>` header to provude the complete
238 // interface.
239 #include <ranges>
240#endif
241
242#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
243 #include <bsls_nativestd.h>
244#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
245
246#ifdef BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD
247 #define BSLSTL_ITERATOR_IMPLEMENT_CPP11_REVERSE_ITERATOR 1
248 #define BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES 1
249#endif // BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD
250
251namespace bsl {
252// Import selected symbols into the `bsl` namespace
253
254// 24.3 primitives
255using std::input_iterator_tag;
256using std::output_iterator_tag;
257using std::forward_iterator_tag;
258using std::bidirectional_iterator_tag;
259using std::random_access_iterator_tag;
260using std::iterator;
261
262// 24.3.4 iterator operations
263using std::advance;
264using std::distance;
265
266// 24.3.4 predefined iterators
267using std::back_insert_iterator;
268using std::back_inserter;
269using std::front_insert_iterator;
270using std::front_inserter;
271using std::insert_iterator;
272using std::inserter;
273
274#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY
275// 23.2
276// 23.3.2.1, incrementable traits
277using std::incrementable;
278using std::incrementable_traits;
279using std::iter_difference_t;
280
281// 23.3.2.2, indirectly readable traits
282using std::indirectly_readable_traits;
283using std::iter_value_t;
284
285// 23.3.2.3, iterator traits
286using std::iter_reference_t;
287using std::iter_rvalue_reference_t;
288
289// 23.3.4.2, concept indirectly_readable
290using std::iter_common_reference_t;
291
292// 23.3.4.3, concept indirectly_writable
293using std::indirectly_readable;
294using std::indirectly_writable;
295
296// 23.3.4.4, concept weakly_incrementable
297using std::weakly_incrementable;
298
299// 23.3.4.6, concept input_or_output_iterator
300using std::input_or_output_iterator;
301
302// 23.3.4.7, concept sentinel_for
303using std::sentinel_for;
304
305// 23.3.4.8, concept sized_sentinel_for
306using std::sized_sentinel_for;
307
308// 23.3.4.9, concept input_iterator
309using std::input_iterator;
310
311// 23.3.4.10, concept output_iterator
312using std::output_iterator;
313
314// 23.3.4.11, concept forward_iterator
315using std::forward_iterator;
316
317// 23.3.4.12, concept bidirectional_iterator
318using std::bidirectional_iterator;
319
320// 23.3.4.13, concept random_access_iterator
321using std::random_access_iterator;
322
323// 23.3.4.14, concept contiguous_iterator
324using std::contiguous_iterator;
325
326// 23.3.6.2, indirect callables
327using std::indirect_binary_predicate;
328using std::indirect_equivalence_relation;
329using std::indirect_result_t;
330using std::indirect_strict_weak_order;
331using std::indirect_unary_predicate;
332using std::indirectly_regular_unary_invocable;
333using std::indirectly_unary_invocable;
334
335// 23.3.6.3, projected
336using std::projected;
337
338// 23.3.7.2, concept indirectly_movable
339using std::indirectly_movable;
340using std::indirectly_movable_storable;
341
342// 23.3.7.3, concept indirectly_copyable
343using std::indirectly_copyable;
344using std::indirectly_copyable_storable;
345
346// 23.3.7.4, concept indirectly_swappable
347using std::indirectly_swappable;
348
349// 23.3.7.5, concept indirectly_comparable
350using std::indirectly_comparable;
351
352// 23.3.7.6, concept permutable
353using std::permutable;
354
355// 23.3.7.7, concept mergeable
356using std::mergeable;
357
358// 23.3.7.8, concept sortable
359using std::sortable;
360
361// 23.4.2, iterator tags
362using std::contiguous_iterator_tag;
363
364// 23.5.3, move iterators and sentinels
365using std::move_sentinel;
366
367// 23.5.4, common iterators
368using std::common_iterator;
369
370// 23.5.5, default sentinel
371using std::default_sentinel_t;
372
373// 23.5.6, counted iterators
374using std::counted_iterator;
375
376// 23.5.7, unreachable sentinel
377using std::unreachable_sentinel_t;
378
379#endif // BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY
380
381#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
382// 24.5 predefined iterators (C++14)
383using std::make_reverse_iterator;
384#endif // BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
385
386// 24.5 stream iterators
387using std::istream_iterator;
388using std::ostream_iterator;
389using std::istreambuf_iterator;
390using std::ostreambuf_iterator;
391
392#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
393// 23.5.3, move iterators and sentinels
394using std::move_iterator;
395using std::make_move_iterator;
396// 23.4.3, iterator operations
397using std::next;
398using std::prev;
399#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
400
401#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_AS_CONST
402using std::const_iterator;
403using std::const_sentinel;
404using std::basic_const_iterator;
405using std::make_const_iterator;
406using std::make_const_sentinel;
407using std::iter_const_reference_t;
408#endif
409
410#ifdef BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
411// Sun does not provide `std::iterator_traits` at all. We will provide our own
412// in namespace `bsl`.
413
414 // =========================
415 // class bsl::IteratorTraits
416 // =========================
417
418/// This `struct` provides access to iterator traits.
419///
420/// See @ref bslstl_iterator
421template <class ITER>
422struct iterator_traits {
423 // TYPES
424 typedef typename ITER::iterator_category iterator_category;
425 typedef typename ITER::value_type value_type;
426 typedef typename ITER::difference_type difference_type;
427 typedef typename ITER::pointer pointer;
428 typedef typename ITER::reference reference;
429};
430
431// SPECIALIZATIONS
432
433/// This specialization of `iterator_traits` will match pointer types to a
434/// parameterized non-modifiable `TYPE`.
435template <class TYPE>
436struct iterator_traits<const TYPE *> {
437 // TYPES
438 typedef std::random_access_iterator_tag iterator_category;
439 typedef TYPE value_type;
440 typedef std::ptrdiff_t difference_type;
441 typedef const TYPE* pointer;
442 typedef const TYPE& reference;
443};
444
445/// This specialization of `iterator_traits` will match pointer types to a
446/// parameterized modifiable `TYPE`.
447template <class TYPE>
448struct iterator_traits<TYPE *> {
449 // TYPES
450 typedef std::random_access_iterator_tag iterator_category;
451 typedef TYPE value_type;
452 typedef std::ptrdiff_t difference_type;
453 typedef TYPE* pointer;
454 typedef TYPE& reference;
455};
456#else // BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
457// Just use the native version
458using std::iterator_traits;
459#endif // else-of BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
460
461#ifdef BSLSTL_ITERATOR_IMPLEMENT_CPP11_REVERSE_ITERATOR
462// Working around a Solaris Studio compiler bug where `std::reverse_iterator`
463// takes 6 template arguments (of which 3 have defaults) instead of 1, which is
464// not standard compliant. Inherit from `std::reverse_iterator`. For
465// reference, the signature of the Solaris Studio `std::reverse_iterator` is:
466// ```
467// template <class Iterator,
468// class Category,
469// class T,
470// class Reference = T &,
471// class Pointer = T *,
472// class Distance = ptrdiff_t>
473// class reverse_iterator;
474// ```
475
476 // ===========================
477 // class bsl::reverse_iterator
478 // ===========================
479
480/// This class provides a template iterator adaptor that iterates from the end
481/// of the sequence defined by the (template parameter) type `ITER` to the
482/// beginning of that sequence. The type `ITER` shall meet all the
483/// requirements of a bidirectional iterator [24.2.6]. The element sequence
484/// generated in this reversed iteration is referred as "reverse iteration
485/// sequence" in the following class level documentation. The fundamental
486/// relation between a reverse iterator and its corresponding iterator `i` of
487/// type `ITER` is established by the identity
488/// `&*(reverse_iterator(i)) == &*(i - 1)`. This template meets the
489/// requirement of reverse iterator adaptor defined in C++11 standard [24.5.1].
490template <class ITER>
491class reverse_iterator :
492 public std::reverse_iterator<
493 ITER,
494 typename iterator_traits<ITER>::iterator_category,
495 typename iterator_traits<ITER>::value_type,
496 typename iterator_traits<ITER>::reference,
497 typename iterator_traits<ITER>::pointer> {
498 // PRIVATE TYPES
499 typedef std::reverse_iterator<
500 ITER,
501 typename iterator_traits<ITER>::iterator_category,
502 typename iterator_traits<ITER>::value_type,
503 typename iterator_traits<ITER>::reference,
504 typename iterator_traits<ITER>::pointer> Base;
505
506 public:
507 // For convenience:
508
509 typedef typename reverse_iterator::difference_type difference_type;
510
511 // CREATORS
512
513 /// Create the default value for this reverse iterator. The
514 /// default-constructed reverse iterator does not have a singular value
515 /// unless an object of the type specified by the template parameter `ITER`
516 /// has a singular value after default construction.
517 reverse_iterator();
518
519 /// Create a reverse iterator using the specified `base` of the (template
520 /// parameter) type `ITER`.
521 explicit reverse_iterator(ITER base);
522
523 /// Create a reverse iterator having the same value as the specified
524 /// `original`.
525 template <class OTHER_ITER>
526 reverse_iterator(const reverse_iterator<OTHER_ITER>& original);
527
528 // MANIPULATORS
529
530 /// Increment to the next element in the reverse iteration sequence and
531 /// return a reference providing modifiable access to this reverse iterator.
532 ///
533 /// \pre The behavior is undefined if, on entry, this reverse
534 /// iterator has the past-the-end value for a reverse iterator over the
535 /// underlying sequence.
536 reverse_iterator& operator++();
537
538 /// Increment to the next element in the reverse iteration sequence and
539 /// return a reverse iterator having the pre-increment value of this reverse iterator.
540 ///
541 /// \pre The behavior is undefined if, on entry, this reverse
542 /// iterator has the past-the-end value for a reverse iterator over the
543 /// underlying sequence.
544 reverse_iterator operator++(int);
545
546 /// Increment by the specified `n` number of elements in the reverse
547 /// iteration sequence and return a reference providing modifiable access to this reverse iterator.
548 ///
549 /// \pre The behavior is undefined unless this
550 /// reverse iterator, after incrementing by `n`, is within the bounds of the underlying sequence.
551 ///
552 /// \note Note that the (template parameter) type
553 /// `ITER` shall meet the requirements of a random access iterator.
554 reverse_iterator& operator+=(difference_type n);
555
556 /// Decrement to the previous element in the reverse iteration sequence and
557 /// return a reference providing modifiable access to this reverse iterator.
558 ///
559 /// \pre The behavior is undefined if, on entry, this reverse
560 /// iterator has the same value as a reverse iterator to the start of the
561 /// underlying sequence.
562 reverse_iterator& operator--();
563
564 /// Decrement to the previous element in the reverse iteration sequence and
565 /// return a reverse iterator having the pre-decrement value of this reverse iterator.
566 ///
567 /// \pre The behavior is undefined if, on entry, this reverse
568 /// iterator has the same value as a reverse iterator to the start of the
569 /// underlying sequence.
570 reverse_iterator operator--(int);
571
572 /// Decrement by the specified `n` number of elements in the reverse
573 /// iteration sequence and return a reference providing modifiable access to this reverse iterator.
574 ///
575 /// \pre The behavior is undefined unless this
576 /// reverse iterator, after decrementing by `n`, is within the bounds of the underlying sequence.
577 ///
578 /// \note Note that the (template parameter) type
579 /// `ITER` shall meet the requirements of a random access iterator.
580 reverse_iterator& operator-=(difference_type n);
581
582 // ACCESSORS
583
584 /// Return a reverse iterator having the same value as that of incrementing
585 /// this reverse iterator by the specified `n` number of elements in the reverse iteration sequence.
586 ///
587 /// \pre The behavior is undefined unless this
588 /// reverse iterator, if increments by `n`, would be within the bounds of the underlying sequence.
589 ///
590 /// \note Note that the (template parameter) type
591 /// `ITER` shall meet the requirements of a random access iterator.
592 reverse_iterator operator+(difference_type n) const;
593
594 /// Return a reverse iterator having the same value as that of decrementing
595 /// this reverse iterator by the specified `n` number of elements in the reverse iteration sequence.
596 ///
597 /// \pre The behavior is undefined unless this
598 /// reverse iterator, if decrements by `n`, would be within the bounds of the underlying sequence.
599 ///
600 /// \note Note that the (template parameter) type
601 /// `ITER` shall meet the requirements of a random access iterator.
602 reverse_iterator operator-(difference_type n) const;
603};
604
605// FREE OPERATORS
606
607/// Return `true` if the specified `lhs` reverse iterator has the same value as
608/// the specified `rhs` reverse iterator, and `false` otherwise. Two reverse
609/// iterators have the same value if they refer to the same element, or both
610/// have the past-the-end value for a reverse iterator over the underlying reverse iteration sequence.
611///
612/// \pre The behavior is undefined unless both reverse
613/// iterators refer to the same underlying sequence.
614template <class ITER>
615inline
616bool operator==(const reverse_iterator<ITER>& lhs,
617 const reverse_iterator<ITER>& rhs);
618
619/// Return `true` if the specified `lhs` reverse iterator of the (template
620/// parameter) type `ITER1` has the same value as the specified `rhs` reverse
621/// iterator of the (template parameter) type `ITER2`, and `false` otherwise.
622/// Two reverse iterators have the same value if they refer to the same
623/// element, or both have the past-the-end value for a reverse iterator over
624/// the underlying reverse iteration sequence.
625///
626/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
627template <class ITER1, class ITER2>
628inline
629bool operator==(const reverse_iterator<ITER1>& lhs,
630 const reverse_iterator<ITER2>& rhs);
631
632/// Return `true` if the specified `lhs` reverse iterator does not have the
633/// same value as the specified `rhs` reverse iterator, and `false` otherwise.
634/// Two reverse iterators do not have the same value if (1) they do not refer
635/// to the same element and (2) both do not have the past-the-end value for a
636/// reverse iterator over the underlying reverse iteration sequence.
637///
638/// \pre The behavior is undefined unless both reverse iterators refer to the same
639/// underlying sequence.
640template <class ITER>
641inline
642bool operator!=(const reverse_iterator<ITER>& lhs,
643 const reverse_iterator<ITER>& rhs);
644
645/// Return `true` if the specified `lhs` reverse iterator of the (template
646/// parameter) type `ITER1` does not have the same value as the specified `rhs`
647/// reverse iterator of the (template parameter) type `ITER2`, and `false`
648/// otherwise. Two reverse iterators do not have the same value if (1) they do
649/// not refer to the same element and (2) both do not have the past-the-end
650/// value for a reverse iterator over the underlying reverse iteration sequence.
651///
652/// \pre The behavior is undefined unless both reverse iterators refer to
653/// the same underlying sequence.
654template <class ITER1, class ITER2>
655inline
656bool operator!=(const reverse_iterator<ITER1>& lhs,
657 const reverse_iterator<ITER2>& rhs);
658
659/// Return `true` if (1) the specified `lhs` reverse iterator refers to an
660/// element before the specified `rhs` reverse iterator in the reverse
661/// iteration sequence, or (2) `rhs` (and not `lhs`) has the past-the-end value
662/// for a reverse iterator over this sequence, and `false` otherwise.
663///
664/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
665///
666/// \note Note that the (template parameter) type `ITER` shall
667/// meet the requirements of random access iterator.
668template <class ITER>
669inline
670bool operator<(const reverse_iterator<ITER>& lhs,
671 const reverse_iterator<ITER>& rhs);
672
673/// Return `true` if (1) the specified `lhs` reverse iterator of the (template
674/// parameter) type `ITER1` refers to an element before the specified `rhs`
675/// reverse iterator of the (template parameter) type `ITER2` in the reverse
676/// iteration sequence, or (2) `rhs` (and not `lhs`) has the past-the-end value
677/// for a reverse iterator over this sequence, and `false` otherwise.
678///
679/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
680///
681/// \note Note that both `ITER1` and `ITER2` shall meet the
682/// requirements of random access iterator.
683template <class ITER1, class ITER2>
684inline
685bool operator<(const reverse_iterator<ITER1>& lhs,
686 const reverse_iterator<ITER2>& rhs);
687
688/// Return `true` if (1) the specified `lhs` reverse iterator refers to an
689/// element after the specified `rhs` reverse iterator in the reverse iteration
690/// sequence, or (2) `lhs` (and not `rhs`) has the past-the-front value of an
691/// reverse iterator over this sequence, and `false` otherwise.
692///
693/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
694///
695/// \note Note that the (template parameter) type `ITER` shall meet the
696/// requirements of random access iterator.
697template <class ITER>
698inline
699bool operator>(const reverse_iterator<ITER>& lhs,
700 const reverse_iterator<ITER>& rhs);
701
702/// Return `true` if (1) the specified `lhs` reverse iterator of the (template
703/// parameter) type `ITER1` refers to an element after the specified `rhs`
704/// reverse iterator of the (template parameter) type `ITER2` in the reverse
705/// iteration sequence, or (2) `lhs` (and not `rhs`) has the past-the-front
706/// value of an reverse iterator over this sequence, and `false` otherwise.
707///
708/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
709///
710/// \note Note that both `ITER1` and `ITER2` shall meet the
711/// requirements of random access iterator.
712template <class ITER1, class ITER2>
713inline
714bool operator>(const reverse_iterator<ITER1>& lhs,
715 const reverse_iterator<ITER2>& rhs);
716
717/// Return `true` if (1) the specified `lhs` reverse iterator has the same
718/// value as the specified `rhs` reverse iterator, or (2) `lhs` refers to an
719/// element before `rhs` in the reverse iteration sequence, or (3) `rhs` has
720/// the past-the-end value for a reverse iterator over this sequence, and `false` otherwise.
721///
722/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
723///
724/// \note Note that the (template
725/// parameter) type `ITER` shall meet the requirements of a random access
726/// iterator.
727template <class ITER>
728inline
729bool operator<=(const reverse_iterator<ITER>& lhs,
730 const reverse_iterator<ITER>& rhs);
731
732/// Return `true` if (1) the specified `lhs` reverse iterator of the (template
733/// parameter) type `ITER1` has the same value as the specified `rhs` reverse
734/// iterator of the (template parameter) type `ITER2`, or (2) `lhs` refers to
735/// an element before `rhs` in the reverse iteration sequence, or (3) `rhs` has
736/// the past-the-end value for a reverse iterator over this sequence, and `false` otherwise.
737///
738/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
739///
740/// \note Note that both `ITER1` and `ITER2`
741/// shall meet the requirements of a random access iterator.
742template <class ITER1, class ITER2>
743inline
744bool operator<=(const reverse_iterator<ITER1>& lhs,
745 const reverse_iterator<ITER2>& rhs);
746
747/// Return `true` if (1) the specified `lhs` reverse iterator has the same
748/// value as the specified `rhs` reverse iterator, or (2) `lhs` has the
749/// past-the-end value for a reverse iterator over the underlying reverse
750/// iteration sequence, or (3) `lhs` refers to an element after `rhs` in this sequence, and `false` otherwise.
751///
752/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
753///
754/// \note Note that the
755/// (template parameter) type `ITER` shall meet the requirements of random
756/// access iterator.
757template <class ITER>
758inline
759bool operator>=(const reverse_iterator<ITER>& lhs,
760 const reverse_iterator<ITER>& rhs);
761
762/// Return `true` if (1) the specified `lhs` reverse iterator of the (template
763/// parameter) type `ITER1` has the same value as the specified `rhs` reverse
764/// iterator of the (template parameter) type `ITER2`, or (2) `lhs` has the
765/// past-the-end value for a reverse iterator over the underlying reverse
766/// iteration sequence, or (3) `lhs` refers to an element after `rhs` in this sequence, and `false` otherwise.
767///
768/// \pre The behavior is undefined unless both reverse iterators refer to the same underlying sequence.
769///
770/// \note Note that both
771/// type `ITER1` and type `ITER2` shall meet the requirements of random access
772/// iterator.
773template <class ITER1, class ITER2>
774inline
775bool operator>=(const reverse_iterator<ITER1>& lhs,
776 const reverse_iterator<ITER2>& rhs);
777
778/// Return the distance from the specified `rhs` reverse iterator to the specified `lhs` reverse iterator.
779///
780/// \pre The behavior is undefined unless `lhs`
781/// and `rhs` are reverse iterators into the same underlying sequence.
782///
783/// \note Note that the (template parameter) type `ITER` shall meet the requirements of
784/// random access iterator. Also note that the result might be negative.
785template <class ITER>
786inline
787typename reverse_iterator<ITER>::difference_type
788operator-(const reverse_iterator<ITER>& lhs,
789 const reverse_iterator<ITER>& rhs);
790
791/// Return a reverse iterator to the element at the specified `n` positions
792/// past the specified `rhs` reverse iterator.
793///
794/// \pre The behavior is undefined unless `rhs`, after incrementing by `n`, is within the bounds of the underlying sequence.
795///
796/// \note Note that the (template parameter) type `ITER` shall
797/// meet the requirements of random access iterator.
798template <class ITER, class DIFF_TYPE>
799inline
800reverse_iterator<ITER>
801operator+(DIFF_TYPE n, const reverse_iterator<ITER>& rhs);
802#else // BSLSTL_ITERATOR_IMPLEMENT_CPP11_REVERSE_ITERATOR
803// Just use the native version
804using std::reverse_iterator;
805#endif // else-of BSLSTL_ITERATOR_IMPLEMENT_CPP11_REVERSE_ITERATOR
806
807#ifdef BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
808
809 // ==========================
810 // struct IteratorDistanceImp
811 // ==========================
812
813/// This utility class provides a namespace for functions that operate on
814/// iterators.
815///
816/// See @ref bslstl_iterator
817struct IteratorDistanceImp {
818 // CLASS METHODS
819
820 /// Return in the specified `*ret` the distance from the specified `start`
821 /// iterator to the specified `finish` iterator.
822 ///
823 /// \pre The behavior is undefined unless `start` and `finish` both have the @ref input_iterator_tag into the
824 /// same underlying sequence, and `start` is before `finish` in that sequence.
825 ///
826 /// \note Note that input iterators are valid only for single-pass
827 /// use.
828 template <class INPUT_ITER, class DIFFERENCE_TYPE>
829 static void getDistance(DIFFERENCE_TYPE *ret,
830 INPUT_ITER start,
831 INPUT_ITER finish,
832 input_iterator_tag);
833
834 /// Return in the specified `*ret` the distance from the specified `start`
835 /// iterator to the specified `finish` iterator.
836 ///
837 /// \pre The behavior is undefined unless `start` and `finish` both have the @ref forward_iterator_tag into
838 /// the same underlying sequence, and `start` is before `finish` in that
839 /// sequence.
840 template <class FWD_ITER, class DIFFERENCE_TYPE>
841 static void getDistance(DIFFERENCE_TYPE *ret,
842 FWD_ITER start,
843 FWD_ITER finish,
844 forward_iterator_tag);
845
846 /// Return in the specified `*ret` the distance from the specified `start`
847 /// iterator to the specified `finish` iterator.
848 ///
849 /// \pre The behavior is undefined unless `start` and `finish` both have the @ref random_access_iterator_tag into the same underlying sequence.
850 ///
851 /// \note Note that the result might be
852 /// negative.
853 template <class RANDOM_ITER, class DIFFERENCE_TYPE>
854 static void getDistance(DIFFERENCE_TYPE *ret,
855 RANDOM_ITER start,
856 RANDOM_ITER finish,
857 random_access_iterator_tag);
858};
859
860/// Return the distance from the specified `start` iterator to the specified `finish` iterator.
861///
862/// \pre The behavior is undefined unless `start` and `finish`
863/// are both into the same underlying sequence, and `start` is before `finish` in that sequence.
864///
865/// \note Note that the (template parameter) type `ITER` shall
866/// at least meet the requirements of input iterator.
867/// \note Note that if `ITER` is
868/// *only* an input iterator, the iterators are valid only for a single pass
869/// and cannot be reused on return from this function. Also note that many
870/// supersets of input iterators (e.g, forward iterator, random iterator) can
871/// be reused.
872template <class ITER>
873typename iterator_traits<ITER>::difference_type
874distance(ITER start, ITER finish);
875#else // BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
876// Just use the native version
877using std::distance;
878#endif // else-of BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
879
880#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_RANGE_FUNCTIONS
881using std::begin;
882using std::end;
883#else // BSLS_LIBRARYFEATURES_HAS_CPP11_RANGE_FUNCTIONS
884
885/// Return an iterator providing modifiable access to the first valid
886/// element of the specified `container`.
887template <class T>
888typename T::iterator begin(T& container);
889
890/// Return an iterator providing non-modifiable access to the first valid
891/// element of the specified `container`.
892template <class T>
893typename T::const_iterator begin(const T& container);
894
895/// Return the address of the modifiable first element in the specified
896/// `array`.
897template<class T, size_t N>
898T *begin(T (&array)[N]);
899
900/// Return the address of the non-modifiable first element in the specified
901/// `array`.
902template<class T, size_t N>
903const T *begin(const T (&array)[N]);
904
905/// Return the iterator providing modifiable access to the position one
906/// after the last valid element in the specified `container`.
907template <class T>
908typename T::iterator end(T& container);
909
910/// Return the iterator providing non-modifiable access to the position one
911/// after the last valid element in the specified `container`.
912template <class T>
913typename T::const_iterator end(const T& container);
914
915/// Return the address of the modifiable element after the last element
916/// in the specified `array`.
917template<class T, size_t N>
918T *end(T (&array)[N]);
919
920/// Return the address of the non-modifiable element after the last element
921/// in the specified `array`.
922template<class T, size_t N>
923const T *end(const T (&array)[N]);
924
925#endif // else-of BSLS_LIBRARYFEATURES_HAS_CPP11_RANGE_FUNCTIONS
926
927#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_RANGE_FUNCTIONS
928using std::cbegin;
929using std::cend;
930using std::rbegin;
931using std::rend;
932using std::crbegin;
933using std::crend;
934#else // BSLS_LIBRARYFEATURES_HAS_CPP14_RANGE_FUNCTIONS
935
936/// Return an iterator providing non-modifiable access to the first valid
937/// element of the specified `container`.
938template <class T>
939typename T::const_iterator cbegin(const T& container);
940
941/// Return the address of the non-modifiable first element in the specified
942/// `array`.
943template<class T, size_t N>
944const T *cbegin(const T (&array)[N]);
945
946/// Return the reverse iterator providing modifiable access to the last
947/// valid element of the specified `container`.
948template <class T>
949typename T::reverse_iterator rbegin(T& container);
950
951/// Return the reverse iterator providing non-modifiable access to the last
952/// valid element of the specified `container`.
953template <class T>
954typename T::const_reverse_iterator rbegin(const T& container);
955
956/// Return the reverse iterator providing modifiable access to the last
957/// element of the specified `array`.
958template <class T, size_t N>
959reverse_iterator<T *> rbegin(T (&array)[N]);
960
961#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
962/// Return the reverse iterator providing non-modifiable access to the last
963/// element of the specified `initializerList`.
964template <class T>
965reverse_iterator<const T *> rbegin(std::initializer_list<T> initializerList);
966#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
967
968/// Return the reverse iterator providing non-modifiable access to the last
969/// valid element of the specified `container`.
970template <class T>
971typename T::const_reverse_iterator crbegin(const T& container);
972
973/// Return the reverse iterator providing non-modifiable access to the last
974/// element of the specified `array`.
975template <class T, size_t N>
976reverse_iterator<const T *> crbegin(const T (&array)[N]);
977
978/// Return the iterator providing non-modifiable access to the position one
979/// after the last valid element in the specified `container`.
980template <class T>
981typename T::const_iterator cend(const T& container);
982
983/// Return the address of the non-modifiable element after the last element
984/// in the specified `array`.
985template<class T, size_t N>
986const T *cend(const T (&array)[N]);
987
988/// Return the reverse iterator providing modifiable access to the position
989/// one before the first valid element in the specified `container`.
990template <class T>
991typename T::reverse_iterator rend(T& container);
992
993/// Return the reverse iterator providing non-modifiable access to the
994/// position one before the first valid element in the specified
995/// `container`.
996template <class T>
997typename T::const_reverse_iterator rend(const T& container);
998
999/// Return the reverse iterator providing modifiable access to the position
1000/// one before the first element in the specified `array`.
1001template <class T, size_t N>
1002reverse_iterator<T *> rend(T (&array)[N]);
1003
1004#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1005/// Return the reverse iterator providing non-modifiable access to the
1006/// position one before the first element in the specified `initializerList`.
1007template <class T>
1008reverse_iterator<const T *> rend(std::initializer_list<T> initializerList);
1009#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1010
1011/// Return the reverse iterator providing non-modifiable access to the
1012/// position one before the first element in the specified `container`.
1013template <class T>
1014typename T::const_reverse_iterator crend(const T& container);
1015
1016/// Return the reverse iterator providing non-modifiable access to the
1017/// position one before the first element in the specified `array`.
1018template <class T, size_t N>
1019reverse_iterator<const T *> crend(const T (&array)[N]);
1020#endif // else-of BSLS_LIBRARYFEATURES_HAS_CPP14_RANGE_FUNCTIONS
1021
1022namespace ranges {
1023#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES
1024
1025using std::ranges::begin;
1026using std::ranges::end;
1027using std::ranges::cbegin;
1028using std::ranges::cend;
1029using std::ranges::rbegin;
1030using std::ranges::rend;
1031using std::ranges::crbegin;
1032using std::ranges::crend;
1033using std::ranges::size;
1034using std::ranges::ssize;
1035using std::ranges::empty;
1036using std::ranges::data;
1037using std::ranges::cdata;
1038
1039using std::ranges::advance;
1040using std::ranges::distance;
1041using std::ranges::iter_move;
1042using std::ranges::iter_swap;
1043using std::ranges::next;
1044using std::ranges::prev;
1045
1046#else // BSLS_LIBRARYFEATURES_HAS_CPP20_RANGE
1047
1048using bsl::begin;
1049using bsl::end;
1050using bsl::cbegin;
1051using bsl::cend;
1052using bsl::rbegin;
1053using bsl::rend;
1054using bsl::crbegin;
1055using bsl::crend;
1056
1057#endif // BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES
1058} // close namespace ranges
1059
1060// ============================================================================
1061// INLINE FUNCTION DEFINITIONS
1062// ============================================================================
1063
1064#ifdef BSLSTL_ITERATOR_IMPLEMENT_CPP11_REVERSE_ITERATOR
1065
1066 // ---------------------------
1067 // class bsl::reverse_iterator
1068 // ---------------------------
1069
1070// CREATORS
1071template <class ITER>
1072inline
1073reverse_iterator<ITER>::reverse_iterator()
1074: Base()
1075{
1076}
1077
1078template <class ITER>
1079inline
1080reverse_iterator<ITER>::reverse_iterator(ITER base)
1081: Base(base)
1082{
1083}
1084
1085template <class ITER>
1086template <class OTHER_ITER>
1087inline
1088reverse_iterator<ITER>::reverse_iterator(
1089 const reverse_iterator<OTHER_ITER>& original)
1090: Base(original.base())
1091{
1092}
1093
1094// MANIPULATORS
1095template <class ITER>
1096inline
1097reverse_iterator<ITER>&
1098reverse_iterator<ITER>::operator++()
1099{
1100 Base::operator++();
1101 return *this;
1102}
1103
1104template <class ITER>
1105inline
1106reverse_iterator<ITER>
1107reverse_iterator<ITER>::operator++(int)
1108{
1109 const reverse_iterator tmp(*this);
1110 this->operator++();
1111 return tmp;
1112}
1113
1114template <class ITER>
1115inline
1116reverse_iterator<ITER>&
1117reverse_iterator<ITER>::operator+=(difference_type n)
1118{
1119 Base::operator+=(n);
1120 return *this;
1121}
1122
1123template <class ITER>
1124inline
1125reverse_iterator<ITER>&
1126reverse_iterator<ITER>::operator--()
1127{
1128 Base::operator--();
1129 return *this;
1130}
1131
1132template <class ITER>
1133inline
1134reverse_iterator<ITER>
1135reverse_iterator<ITER>::operator--(int)
1136{
1137 reverse_iterator tmp(*this);
1138 this->operator--();
1139 return tmp;
1140}
1141
1142template <class ITER>
1143inline
1144reverse_iterator<ITER>&
1145reverse_iterator<ITER>::operator-=(difference_type n)
1146{
1147 Base::operator-=(n);
1148 return *this;
1149}
1150
1151// ACCESSORS
1152template <class ITER>
1153inline
1154reverse_iterator<ITER>
1155reverse_iterator<ITER>::operator+(difference_type n) const
1156{
1157 reverse_iterator tmp(*this);
1158 tmp += n;
1159 return tmp;
1160}
1161
1162template <class ITER>
1163inline
1164reverse_iterator<ITER>
1165reverse_iterator<ITER>::operator-(difference_type n) const
1166{
1167 reverse_iterator tmp(*this);
1168 tmp -= n;
1169 return tmp;
1170}
1171
1172// FREE OPERATORS
1173template <class ITER>
1174inline
1175bool operator==(const reverse_iterator<ITER>& lhs,
1176 const reverse_iterator<ITER>& rhs)
1177{
1178 typedef std::reverse_iterator<
1179 ITER,
1180 typename iterator_traits<ITER>::iterator_category,
1181 typename iterator_traits<ITER>::value_type,
1182 typename iterator_traits<ITER>::reference,
1183 typename iterator_traits<ITER>::pointer> Base;
1184
1185 return std::operator==(static_cast<const Base&>(lhs),
1186 static_cast<const Base&>(rhs));
1187}
1188
1189template <class ITER1, class ITER2>
1190inline
1191bool operator==(const reverse_iterator<ITER1>& lhs,
1192 const reverse_iterator<ITER2>& rhs)
1193{
1194 // this overload compares a reverse_iterator with a const_reverse_iterator
1195
1196 return lhs.base() == rhs.base();
1197}
1198
1199template <class ITER>
1200inline
1201bool operator!=(const reverse_iterator<ITER>& lhs,
1202 const reverse_iterator<ITER>& rhs)
1203{
1204 return ! (lhs == rhs);
1205}
1206
1207template <class ITER1, class ITER2>
1208inline
1209bool operator!=(const reverse_iterator<ITER1>& lhs,
1210 const reverse_iterator<ITER2>& rhs)
1211{
1212 // this overload compares a reverse_iterator with a const_reverse_iterator
1213
1214 return ! (lhs == rhs);
1215}
1216
1217template <class ITER>
1218inline
1219bool operator<(const reverse_iterator<ITER>& lhs,
1220 const reverse_iterator<ITER>& rhs)
1221{
1222 return rhs.base() < lhs.base();
1223}
1224
1225template <class ITER1, class ITER2>
1226inline
1227bool operator<(const reverse_iterator<ITER1>& lhs,
1228 const reverse_iterator<ITER2>& rhs)
1229{
1230 // this overload compares a reverse_iterator with a const_reverse_iterator
1231
1232 return rhs.base() < lhs.base();
1233}
1234
1235template <class ITER>
1236inline
1237bool operator>(const reverse_iterator<ITER>& lhs,
1238 const reverse_iterator<ITER>& rhs)
1239{
1240 return rhs < lhs;
1241}
1242
1243template <class ITER1, class ITER2>
1244inline
1245bool operator>(const reverse_iterator<ITER1>& lhs,
1246 const reverse_iterator<ITER2>& rhs)
1247{
1248 return rhs < lhs;
1249}
1250
1251template <class ITER>
1252inline
1253bool operator<=(const reverse_iterator<ITER>& lhs,
1254 const reverse_iterator<ITER>& rhs)
1255{
1256 return !(rhs < lhs);
1257}
1258
1259template <class ITER1, class ITER2>
1260inline
1261bool operator<=(const reverse_iterator<ITER1>& lhs,
1262 const reverse_iterator<ITER2>& rhs)
1263{
1264 return !(rhs < lhs);
1265}
1266
1267template <class ITER>
1268inline
1269bool operator>=(const reverse_iterator<ITER>& lhs,
1270 const reverse_iterator<ITER>& rhs)
1271{
1272 return !(lhs < rhs);
1273}
1274
1275template <class ITER1, class ITER2>
1276inline
1277bool operator>=(const reverse_iterator<ITER1>& lhs,
1278 const reverse_iterator<ITER2>& rhs)
1279{
1280 return !(lhs < rhs);
1281}
1282
1283template <class ITER>
1284inline
1285typename reverse_iterator<ITER>::difference_type
1286operator-(const reverse_iterator<ITER>& lhs,
1287 const reverse_iterator<ITER>& rhs)
1288{
1289 typedef std::reverse_iterator<
1290 ITER,
1291 typename iterator_traits<ITER>::iterator_category,
1292 typename iterator_traits<ITER>::value_type,
1293 typename iterator_traits<ITER>::reference,
1294 typename iterator_traits<ITER>::pointer> Base;
1295
1296 return std::operator-(static_cast<const Base&>(lhs),
1297 static_cast<const Base&>(rhs));
1298}
1299
1300template <class ITER, class DIFF_TYPE>
1301inline
1302reverse_iterator<ITER>
1303operator+(DIFF_TYPE n, const reverse_iterator<ITER>& rhs)
1304{
1305 return rhs.operator+(n);
1306}
1307
1308#endif // BSLSTL_ITERATOR_IMPLEMENT_CPP11_REVERSE_ITERATOR
1309
1310 // ====
1311 // data
1312 // ====
1313
1314#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_RANGE_FUNCTIONS
1315using std::data;
1316#else // BSLS_LIBRARYFEATURES_HAS_CPP17_RANGE_FUNCTIONS
1317/// Return an pointer providing modifiable access to the first valid element of
1318/// the specified `container`. The `CONTAINER` template parameter type must
1319/// provide a `data` accessor.
1320template <class CONTAINER>
1322#ifdef BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1323auto data(CONTAINER& container) -> decltype(container.data())
1324#else // BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1325typename CONTAINER::value_type *data(CONTAINER& container)
1326#endif // else-of BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1327{
1328 return container.data();
1329}
1330
1331/// Return a pointer providing non-modifiable access to the first valid
1332/// element of the specified `container`. The `CONTAINER` template
1333/// parameter type must provide a `data` accessor.
1334template <class CONTAINER>
1336#ifdef BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1337auto data(const CONTAINER& container) -> decltype(container.data())
1338#else // BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1339typename CONTAINER::value_type const *data(const CONTAINER& container)
1340#endif // else-of BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1341{
1342 return container.data();
1343}
1344
1345/// Return the address of the first element in the specified `array`.
1346template<class T, size_t N>
1348T *data(T (&array)[N])
1349{
1350 return array;
1351}
1352#endif // else-of BSLS_LIBRARYFEATURES_HAS_CPP17_RANGE_FUNCTIONS
1353
1354 // =====
1355 // empty
1356 // =====
1357
1358#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_RANGE_FUNCTIONS
1359using std::empty;
1360#else // BSLS_LIBRARYFEATURES_HAS_CPP17_RANGE_FUNCTIONS
1361# ifdef BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1362/// Return whether or not the specified `container` contains zero elements.
1363/// The `CONTAINER` template parameter type must provide a `empty` accessor.
1364template <class CONTAINER>
1365inline
1366BSLS_KEYWORD_CONSTEXPR auto empty(const CONTAINER& container)->
1367 decltype(container.empty())
1368{
1369 return container.empty();
1370}
1371# else // BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1372
1373/// Return whether or not the specified `container` contains zero elements.
1374/// The `CONTAINER` template parameter type must provide a `empty` accessor.
1375template <class CONTAINER>
1376inline
1377BSLS_KEYWORD_CONSTEXPR bool empty(const CONTAINER& container)
1378{
1379 return container.empty();
1380}
1381# endif // else-of BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
1382
1383/// Return false (Zero-length arrays are not allowed).
1384template <class TYPE, size_t DIMENSION>
1385inline
1386BSLS_KEYWORD_CONSTEXPR bool empty(const TYPE (&)[DIMENSION])
1387{
1388 return false;
1389}
1390
1391#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1392/// Return whether of not the specified `initializerList` contains zero
1393/// elements. This is a separate specialization because
1394/// `std::initializer_list<TYPE>` does not have an `empty` member function.
1395template <class TYPE>
1396inline
1397BSLS_KEYWORD_CONSTEXPR bool empty(std::initializer_list<TYPE> initializerList)
1398{
1399 return 0 == initializerList.size();
1400}
1401#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1402#endif // else-of BSLS_LIBRARYFEATURES_HAS_CPP17_RANGE_FUNCTIONS
1403
1404 // ====
1405 // size
1406 // ====
1407
1408// If the underlying standard library implements `std::size`, then we need to
1409// use it. Consider the following code:
1410// ```
1411// bsl::set<int, std::less<int> > s;
1412// if (size(s) == 0) { .. }
1413// ```
1414// Because the set `s` has hooks into both namespace `bsl` and `std`, an
1415// unqualified call to `size` will find both, and fail to compile. MSVC
1416// provides `std::size` in all language modes.
1417#if defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY) || \
1418 defined(BSLS_PLATFORM_CMP_MSVC)
1419// The implementation has `std::ssize()` defined, we can use it.
1420using std::size;
1421#else // end - we can just use `std::size()`
1422// The implementation does not define `std::size()`, we need to implement it.
1423
1424 // `bsl::size` Overload for Arrays
1425
1426/// Return the dimension of the specified array argument.
1427template <class TYPE, size_t DIMENSION>
1428inline
1430 const TYPE (&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
1431{
1432 return DIMENSION;
1433}
1434
1435 // `bsl::size` Overload for Containers
1436
1437// For containers we have two possible implementations for `bsl::size()`,
1438// depending on the level of compiler support we can use:
1439#if defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE) && \
1440 201103L <= BSLS_COMPILERFEATURES_SUPPORT_CPLUSPLUS
1441// We have both `decltype` and trailing return types, we can deduce the return
1442// type of the `size()` method of containers.
1443
1444/// Return the size of the specified `container`. The `CONTAINER` template
1445/// parameter type must provide a `size` accessor.
1446template <class CONTAINER>
1447inline
1448BSLS_KEYWORD_CONSTEXPR auto size(const CONTAINER& container) ->
1449 decltype(container.size())
1450{
1451 return container.size();
1452}
1453#else // end - `bsl::size()` implementation that deduces the return type
1454// The language features to deduce the return type of the `size()` method of
1455// containers are not present, we fall back to using `bsl::size_t`.
1456
1457/// Return the size of the specified `container`. The `CONTAINER` template
1458/// parameter type must provide a `size` accessor.
1459template <class CONTAINER>
1460inline
1461BSLS_KEYWORD_CONSTEXPR size_t size(const CONTAINER& container)
1462{
1463 return container.size();
1464}
1465#endif // end - cannot deduce return type, return `size_t` from `bsl::size()`
1466#endif // end - have to implement `bsl::size()` ourselves
1467
1468 // =====
1469 // ssize
1470 // =====
1471
1472// If the underlying standard library implements `std::ssize`, then we need to
1473// use it. Consider the following code:
1474// ```
1475// bsl::set<int, std::less<int> > s;
1476// if (ssize(s) == 0) { .. }
1477// ```
1478// Because the set `s` has hooks into both namespace `bsl` and `std`, an
1479// unqualified call to `ssize` will find both, and fail to compile.
1480#if 201703L < BSLS_COMPILERFEATURES_CPLUSPLUS && \
1481 defined(__cpp_lib_ssize) && __cpp_lib_ssize >= 201902L
1482// The implementation has `std::ssize()` defined, we can use it.
1483using std::ssize;
1484#else // end - we can just use `std::ssize()`
1485// The implementation does not define `std::ssize()`, we need to implement it.
1486
1487 // `bsl::ssize` Overload for Arrays
1488
1489/// Return the dimension of the specified array argument.
1490template <class TYPE, std::ptrdiff_t DIMENSION>
1491inline
1493 const TYPE (&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
1494{
1495 return DIMENSION;
1496}
1497
1498 // `bsl::ssize` Overload for Containers
1499
1500// For containers we have two possible implementations for `bsl::ssize()`,
1501// depending on the level of compiler support we can use:
1502#if defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE) && \
1503 201103L <= BSLS_COMPILERFEATURES_SUPPORT_CPLUSPLUS
1504// We have both `decltype` and trailing return types, we can deduce the return
1505// type of the `size()` method of containers, and pick its signed counterpart.
1506
1507// Return the size of the specified `container`. The `CONTAINER` template
1508// parameter type must provide a `size` accessor.
1509template <class CONTAINER>
1510inline
1511BSLS_KEYWORD_CONSTEXPR auto ssize(const CONTAINER& container) ->
1512 std::common_type_t<
1513 std::ptrdiff_t,
1514 std::make_signed_t<decltype(container.size())>>
1515{
1516 return container.size();
1517}
1518#else // end - `bsl::ssize()` implementation that deduces the return type
1519// The language features to deduce the return type of the `size()` method of
1520// containers are not present, we fall back to using `bsl::ptrdiff_t`.
1521
1522/// Return the size of the specified `container`. The `CONTAINER` template
1523/// parameter type must provide a `size` accessor.
1524template <class CONTAINER>
1525inline
1526BSLS_KEYWORD_CONSTEXPR std::ptrdiff_t ssize(const CONTAINER& container)
1527{
1528 return container.size();
1529}
1530# endif // end - cannot deduce return type, return `ptrdiff_t` from `ssize()`
1531#endif // end - have to implement `bsl::ssize()` ourselves
1532
1533#ifdef BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
1534
1535 // --------------------------
1536 // struct IteratorDistanceImp
1537 // --------------------------
1538
1539template <class INPUT_ITER, class DIFFERENCE_TYPE>
1540void IteratorDistanceImp::getDistance(DIFFERENCE_TYPE *ret,
1541 INPUT_ITER start,
1542 INPUT_ITER finish,
1543 input_iterator_tag )
1544{
1545 DIFFERENCE_TYPE count = 0;
1546 for ( ; start != finish; ++start) {
1547 ++count;
1548 }
1549
1550 *ret = count;
1551}
1552
1553template <class FWD_ITER, class DIFFERENCE_TYPE>
1554void IteratorDistanceImp::getDistance(DIFFERENCE_TYPE *ret,
1555 FWD_ITER start,
1556 FWD_ITER finish,
1557 forward_iterator_tag)
1558{
1559 DIFFERENCE_TYPE count = 0;
1560 for ( ; start != finish; ++start) {
1561 ++count;
1562 }
1563
1564 *ret = count;
1565}
1566
1567template <class RANDOM_ITER, class DIFFERENCE_TYPE>
1568inline
1569void IteratorDistanceImp::getDistance(DIFFERENCE_TYPE *ret,
1570 RANDOM_ITER start,
1571 RANDOM_ITER finish,
1572 random_access_iterator_tag)
1573{
1574 *ret = DIFFERENCE_TYPE(finish - start);
1575}
1576
1577template <class ITER>
1578inline
1579typename iterator_traits<ITER>::difference_type
1580distance(ITER start, ITER finish)
1581{
1582 typedef typename bsl::iterator_traits<ITER>::iterator_category tag;
1583
1584 typename iterator_traits<ITER>::difference_type ret;
1585 IteratorDistanceImp::getDistance(&ret, start, finish, tag());
1586 return ret;
1587}
1588#endif // BSLSTL_ITERATOR_PROVIDE_SUN_CPP98_FIXES
1589
1590#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_RANGE_FUNCTIONS
1591template <class T>
1592inline
1593typename T::iterator begin(T& container)
1594{
1595 return container.begin();
1596}
1597
1598template <class T>
1599inline
1600typename T::const_iterator begin(const T& container)
1601{
1602 return container.begin();
1603}
1604
1605template<class T, size_t N>
1606inline
1607T *begin(T (&array)[N])
1608{
1609 return array;
1610}
1611
1612template<class T, size_t N>
1613inline
1614const T *begin(const T (&array)[N])
1615{
1616 return array;
1617}
1618
1619template <class T>
1620inline
1621typename T::iterator end(T& container)
1622{
1623 return container.end();
1624}
1625
1626template <class T>
1627inline
1628typename T::const_iterator end(const T& container)
1629{
1630 return container.end();
1631}
1632
1633template<class T, size_t N>
1634inline
1635T *end(T (&array)[N])
1636{
1637 return array + N;
1638}
1639
1640template<class T, size_t N>
1641inline
1642const T *end(const T (&array)[N])
1643{
1644 return array + N;
1645}
1646#endif // !BSLS_LIBRARYFEATURES_HAS_CPP11_RANGE_FUNCTIONS
1647
1648#ifndef BSLS_LIBRARYFEATURES_HAS_CPP14_RANGE_FUNCTIONS
1649template <class T>
1650inline
1651typename T::const_iterator cbegin(const T& container)
1652{
1653 return begin(container);
1654}
1655
1656template<class T, size_t N>
1657inline
1658const T *cbegin(const T (&array)[N])
1659{
1660 return begin(array);
1661}
1662
1663template <class T>
1664inline
1665typename T::reverse_iterator rbegin(T& container)
1666{
1667 return container.rbegin();
1668}
1669
1670template <class T>
1671inline
1672typename T::const_reverse_iterator rbegin(const T& container)
1673{
1674 return container.rbegin();
1675}
1676
1677template <class T, size_t N>
1678inline
1679reverse_iterator<T *> rbegin(T (&array)[N])
1680{
1681 return reverse_iterator<T *>(array + N);
1682}
1683
1684#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1685template <class T>
1686inline
1687reverse_iterator<const T *> rbegin(std::initializer_list<T> initializerList)
1688{
1689 return reverse_iterator<const T *>(initializerList.end());
1690}
1691#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1692
1693template <class T>
1694inline
1695typename T::const_reverse_iterator crbegin(const T& container)
1696{
1697 return rbegin(container);
1698}
1699
1700template <class T, size_t N>
1701inline
1702reverse_iterator<const T *> crbegin(const T (&array)[N])
1703{
1704 return reverse_iterator<const T *>(array + N);
1705}
1706
1707template <class T>
1708inline
1709typename T::const_iterator cend(const T& container)
1710{
1711 return end(container);
1712}
1713
1714template<class T, size_t N>
1715inline
1716const T *cend(const T (&array)[N])
1717{
1718 return end(array);
1719}
1720
1721template <class T>
1722inline
1723typename T::reverse_iterator rend(T& container)
1724{
1725 return container.rend();
1726}
1727
1728template <class T>
1729inline
1730typename T::const_reverse_iterator rend(const T& container)
1731{
1732 return container.rend();
1733}
1734
1735template <class T, size_t N>
1736inline
1737reverse_iterator<T *> rend(T (&array)[N])
1738{
1739 return reverse_iterator<T *>(array);
1740}
1741
1742#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1743template <class T>
1744inline
1745reverse_iterator<const T *> rend(std::initializer_list<T> initializerList)
1746{
1747 return reverse_iterator<const T *>(initializerList.begin());
1748}
1749#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1750
1751template <class T>
1752typename T::const_reverse_iterator crend(const T& container)
1753{
1754 return rend(container);
1755}
1756
1757template <class T, size_t N>
1758inline
1759reverse_iterator<const T *> crend(const T (&array)[N])
1760{
1761 return reverse_iterator<const T *>(array);
1762}
1763#endif // !BSLS_LIBRARYFEATURES_HAS_CPP14_RANGE_FUNCTIONS
1764
1765#ifndef BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES
1766namespace ranges {
1767
1768using bsl::size;
1769using bsl::ssize;
1770using bsl::empty;
1771using bsl::data;
1772
1773using bsl::advance;
1774using bsl::distance;
1775
1776template <class t_RANGE>
1777inline
1778typename iterator_traits<typename t_RANGE::const_iterator>::difference_type
1779distance(const t_RANGE& range)
1780{
1781 return distance(begin(range), end(range));
1782}
1783
1784template <class T, size_t N>
1785inline
1786ptrdiff_t distance(const T (&)[N])
1787{
1788 return N;
1789}
1790
1791} // close namespace ranges
1792#endif // BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES
1793
1794} // close namespace bsl
1795
1796#endif
1797
1798// ----------------------------------------------------------------------------
1799// Copyright 2013 Bloomberg Finance L.P.
1800//
1801// Licensed under the Apache License, Version 2.0 (the "License");
1802// you may not use this file except in compliance with the License.
1803// You may obtain a copy of the License at
1804//
1805// http://www.apache.org/licenses/LICENSE-2.0
1806//
1807// Unless required by applicable law or agreed to in writing, software
1808// distributed under the License is distributed on an "AS IS" BASIS,
1809// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1810// See the License for the specific language governing permissions and
1811// limitations under the License.
1812// ----------------------------- END-OF-FILE ----------------------------------
1813
1814/** @} */
1815/** @} */
1816/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator<(const MetricId &lhs, const MetricId &rhs)
TransformIterator< FUNCTOR, ITERATOR > operator--(TransformIterator< FUNCTOR, ITERATOR > &iterator, int)
bool operator>=(const Guid &lhs, const Guid &rhs)
FunctionOutputIterator< FUNCTION > & operator++(FunctionOutputIterator< FUNCTION > &iterator)
Do nothing and return specified iterator.
Definition bdlb_functionoutputiterator.h:408
TransformIterator< FUNCTOR, ITERATOR > operator+(const TransformIterator< FUNCTOR, ITERATOR > &iterator, typename TransformIterator< FUNCTOR, ITERATOR >::difference_type offset)
bool operator<=(const Guid &lhs, const Guid &rhs)
bool operator>(const Guid &lhs, const Guid &rhs)
TransformIterator< FUNCTOR, ITERATOR > operator-(const TransformIterator< FUNCTOR, ITERATOR > &iterator, typename TransformIterator< FUNCTOR, ITERATOR >::difference_type offset)
iterator_traits< typenamet_RANGE::const_iterator >::difference_type distance(const t_RANGE &range)
Definition bslstl_iterator.h:1779
Definition bdlat_valuetypefunctions.h:939
T::reverse_iterator rend(T &container)
Definition bslstl_iterator.h:1723
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1709
T::const_reverse_iterator crbegin(const T &container)
Definition bslstl_iterator.h:1695
T::reverse_iterator rbegin(T &container)
Definition bslstl_iterator.h:1665
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
BSLS_KEYWORD_CONSTEXPR std::ptrdiff_t ssize(const TYPE(&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
Return the dimension of the specified array argument.
Definition bslstl_iterator.h:1492
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1651
basic_string< CHAR_TYPE, CHAR_TRAITS, ALLOCATOR > operator+(const basic_string< CHAR_TYPE, CHAR_TRAITS, ALLOCATOR > &lhs, const basic_string< CHAR_TYPE, CHAR_TRAITS, ALLOCATOR > &rhs)
BSLS_KEYWORD_CONSTEXPR size_t size(const TYPE(&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
Return the dimension of the specified array argument.
Definition bslstl_iterator.h:1429
ALLOCATOR & lhs
Definition bslstl_string.h:3917
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1325
BSLS_KEYWORD_CONSTEXPR bool empty(const CONTAINER &container)
Definition bslstl_iterator.h:1377
T::const_reverse_iterator crend(const T &container)
Definition bslstl_iterator.h:1752
Definition bslstl_array.h:293