1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://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,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef API_BASE_CONTAINERS_GENERIC_ITERATOR_H
17 #define API_BASE_CONTAINERS_GENERIC_ITERATOR_H
18 
19 #include <base/containers/type_traits.h>
20 #include <base/containers/unique_ptr.h>
21 #include <base/namespace.h>
22 
BASE_BEGIN_NAMESPACE()23 BASE_BEGIN_NAMESPACE()
24 
25 template<typename container>
26 class IGenericIterator {
27 public:
28     using Val = typename container::IteratorValue;
29     using Ptr = unique_ptr<IGenericIterator, void (*)(IGenericIterator*)>;
30     // Returns the container where this iterator points to.
31     virtual const container* GetOwner() const = 0;
32     // Compares two IGenericIterators
33     // Returns true if they point to same.
34     virtual bool Compare(const Ptr&) const = 0;
35     // Advances the iterator to next element
36     // returns false if end reached.
37     virtual bool Next() = 0;
38     // Returns current value. (default if at end)
39     virtual Val Get() const = 0;
40     // Creates a clone of current iterator.
41     virtual Ptr Clone() const = 0;
42 
43 protected:
44     IGenericIterator() = default;
45     IGenericIterator(const IGenericIterator&) = delete;
46     IGenericIterator(IGenericIterator&&) = delete;
47     IGenericIterator& operator=(const IGenericIterator&) = delete;
48     virtual ~IGenericIterator() = default;
49 };
50 
51 template<typename Type>
52 class IIterator {
53 public:
54     IIterator() = default;
55     ~IIterator() = default;
56 
IIterator(const IIterator & it)57     IIterator(const IIterator& it)
58     {
59         if (it.it_) {
60             it_ = it.it_->Clone();
61         }
62     }
IIterator(const typename Type::Ptr & it)63     IIterator(const typename Type::Ptr& it)
64     {
65         if (it) {
66             it_ = it->Clone();
67         }
68     }
69 
IIterator(IIterator && it)70     IIterator(IIterator&& it) noexcept : it_(move(it.it_)) {}
IIterator(typename Type::Ptr && it)71     IIterator(typename Type::Ptr&& it) noexcept : it_(move(it)) {}
72 
73     auto& operator=(const IIterator& it)
74     {
75         if (it.it_) {
76             it_ = it.it_->Clone();
77         } else {
78             it_.reset();
79         }
80         return *this;
81     }
82     auto& operator=(IIterator&& it) noexcept
83     {
84         it_ = move(it.it_);
85         return *this;
86     }
87     bool operator==(const IIterator& other) const
88     {
89         if ((it_ == nullptr) && (other.it_ == nullptr)) {
90             return true;
91         }
92         if (it_) {
93             return it_->Compare(other.it_);
94         }
95         return false;
96     }
97     bool operator!=(const IIterator& other)
98     {
99         return !(*this == other);
100     }
101     IIterator& operator++()
102     {
103         if (it_) {
104             it_->Next();
105         }
106         return *this;
107     }
108     typename Type::Val operator*() const
109     {
110         if (it_) {
111             return it_->Get();
112         }
113         return {};
114     }
115 
116 protected:
117     typename Type::Ptr it_;
118 };
119 
120 BASE_END_NAMESPACE()
121 #endif
122