]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/stl_interfaces/example/reverse_iterator.cpp
1 // Copyright (C) 2019 T. Zachary Laine
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 #include <boost/stl_interfaces/iterator_interface.hpp>
16 // In all the previous examples, we only had to implement a subset of the six
17 // possible user-defined basis operations that was needed for one particular
18 // iterator concept. For reverse_iterator, we want to support bidirectional,
19 // random access, and contiguous iterators. We therefore need to provide all
20 // the basis operations that might be needed.
21 template<typename BidiIter
>
22 struct reverse_iterator
23 : boost::stl_interfaces::iterator_interface
<
24 reverse_iterator
<BidiIter
>,
25 #if 201703L < __cplusplus && defined(__cpp_lib_ranges)
26 boost::stl_interfaces::v2::detail::iter_concept_t
<BidiIter
>,
28 typename
std::iterator_traits
<BidiIter
>::iterator_category
,
30 typename
std::iterator_traits
<BidiIter
>::value_type
>
32 reverse_iterator() : it_() {}
33 reverse_iterator(BidiIter it
) : it_(it
) {}
35 using ref_t
= typename
std::iterator_traits
<BidiIter
>::reference
;
36 using diff_t
= typename
std::iterator_traits
<BidiIter
>::difference_type
;
38 ref_t
operator*() const { return *std::prev(it_
); }
40 // These three are used only when BidiIter::iterator_category is
41 // std::bidirectional_iterator_tag.
42 bool operator==(reverse_iterator other
) const { return it_
== other
.it_
; }
44 // Even though iterator_interface-derived bidirectional iterators are
45 // usually given operator++() and operator--() members, it turns out that
46 // operator+=() below amounts to the same thing. That's good, since
47 // having operator++() and operator+=() in this class would have lead to
48 // ambiguities in iterator_interface.
50 // These two are only used when BidiIter::iterator_category is
51 // std::random_access_iterator_tag or std::contiguous_iterator_tag. Even
52 // so, they need to compile even when BidiIter::iterator_category is
53 // std::bidirectional_iterator_tag. That means we have to use
54 // std::distance() and std::advance() instead of operator-() and
57 // Don't worry, the O(n) bidirectional implementations of std::distance()
58 // and std::advance() are dead code, because compare() and advance() are
59 // never even called when BidiIter::iterator_category is
60 // std::bidirectional_iterator_tag.
61 diff_t
operator-(reverse_iterator other
) const
63 return -std::distance(other
.it_
, it_
);
65 reverse_iterator
& operator+=(diff_t n
)
67 std::advance(it_
, -n
);
71 // No need for a using declaration to make
72 // iterator_interface::operator++(int) visible, because we're not defining
73 // operator++() in this template.
79 using rev_bidi_iter
= reverse_iterator
<std::list
<int>::iterator
>;
80 using rev_ra_iter
= reverse_iterator
<std::vector
<int>::iterator
>;
86 std::list
<int> ints
= {4, 3, 2};
87 std::list
<int> ints_copy
;
89 rev_bidi_iter(ints
.end()),
90 rev_bidi_iter(ints
.begin()),
91 std::back_inserter(ints_copy
));
92 std::reverse(ints
.begin(), ints
.end());
93 assert(ints_copy
== ints
);
97 std::vector
<int> ints
= {4, 3, 2};
98 std::vector
<int> ints_copy(ints
.size());
100 rev_ra_iter(ints
.end()),
101 rev_ra_iter(ints
.begin()),
103 std::reverse(ints
.begin(), ints
.end());
104 assert(ints_copy
== ints
);
108 using rev_ptr_iter
= reverse_iterator
<int *>;
110 int ints
[3] = {4, 3, 2};
113 rev_ptr_iter(std::end(ints
)),
114 rev_ptr_iter(std::begin(ints
)),
115 std::begin(ints_copy
));
116 std::reverse(std::begin(ints
), std::end(ints
));
118 std::begin(ints_copy
),