xref: /aosp_15_r20/external/pigweed/pw_containers/public/pw_containers/wrapped_iterator.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include <cstddef>
17 #include <iterator>
18 
19 namespace pw::containers {
20 
21 // Wraps an iterator with another iterator. This is helpful for creating an
22 // iterator that yields items derived from the original iterator's type. For
23 // example, the derived iterator might return a member of or a value calculated
24 // from the original iterator's value.
25 //
26 // Classes inherit from this and provide operator* and operator-> as
27 // appropriate.
28 template <typename Impl, typename Iterator, typename ValueType>
29 class WrappedIterator {
30  public:
31   using difference_type = std::ptrdiff_t;
32   using value_type = ValueType;
33   using pointer = ValueType*;
34   using reference = ValueType&;
35   using iterator_category = std::bidirectional_iterator_tag;
36 
37   constexpr WrappedIterator(const WrappedIterator&) = default;
38   constexpr WrappedIterator& operator=(const WrappedIterator&) = default;
39 
40   Impl& operator++() {
41     ++iterator_;
42     return static_cast<Impl&>(*this);
43   }
44 
45   Impl operator++(int) {
46     Impl original = static_cast<const Impl&>(*this);
47     ++iterator_;
48     return original;
49   }
50 
51   Impl& operator--() {
52     --iterator_;
53     return static_cast<Impl&>(*this);
54   }
55 
56   Impl operator--(int) {
57     Impl original = static_cast<const Impl&>(*this);
58     --iterator_;
59     return original;
60   }
61 
62   constexpr bool operator==(const WrappedIterator& other) const {
63     return iterator_ == other.iterator_;
64   }
65 
66   constexpr bool operator!=(const WrappedIterator& other) const {
67     return !(*this == other);
68   }
69 
70  protected:
71   constexpr WrappedIterator() = default;
72 
WrappedIterator(const Iterator & it)73   constexpr WrappedIterator(const Iterator& it) : iterator_(it) {}
74 
value()75   const auto& value() const { return *iterator_; }
ptr()76   const auto* ptr() const { return iterator_.operator->(); }
77 
78  private:
79   Iterator iterator_;
80 };
81 
82 }  // namespace pw::containers
83