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