1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_LIBDEXFILE_DEX_CLASS_ITERATOR_H_
18 #define ART_LIBDEXFILE_DEX_CLASS_ITERATOR_H_
19 
20 #include <android-base/logging.h>
21 
22 namespace art {
23 
24 class ClassAccessor;
25 class ClassIterator;
26 class DexFile;
27 
28 // Holder class, used to construct ClassAccessors.
29 class ClassIteratorData {
30  public:
ClassIteratorData(const DexFile & dex_file,uint32_t class_def_idx)31   ClassIteratorData(const DexFile& dex_file, uint32_t class_def_idx)
32       : dex_file_(dex_file),
33         class_def_idx_(class_def_idx) {}
34 
35  private:
36   const DexFile& dex_file_;
37   uint32_t class_def_idx_ = 0u;
38 
39   friend class ClassAccessor;
40   friend class ClassIterator;
41 };
42 
43 // Iterator for visiting classes in a Dex file.
44 class ClassIterator {
45  public:
46   using iterator_category = std::forward_iterator_tag;
47   using value_type = ClassIteratorData;
48   using difference_type = ptrdiff_t;
49   using pointer = void;
50   using reference = void;
51 
ClassIterator(const DexFile & dex_file,uint32_t class_def_idx)52   ClassIterator(const DexFile& dex_file, uint32_t class_def_idx)
53       : data_(dex_file, class_def_idx) {}
54 
55   // Value after modification.
56   ClassIterator& operator++() {
57     ++data_.class_def_idx_;
58     return *this;
59   }
60 
61   // Value before modification.
62   ClassIterator operator++(int) {
63     ClassIterator temp = *this;
64     ++*this;
65     return temp;
66   }
67 
68   const value_type& operator*() const {
69     return data_;
70   }
71 
72   bool operator==(const ClassIterator& rhs) const {
73     DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files.";
74     return data_.class_def_idx_ == rhs.data_.class_def_idx_;
75   }
76 
77   bool operator!=(const ClassIterator& rhs) const {
78     return !(*this == rhs);
79   }
80 
81   bool operator<(const ClassIterator& rhs) const {
82     DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files.";
83     return data_.class_def_idx_ < rhs.data_.class_def_idx_;
84   }
85 
86   bool operator>(const ClassIterator& rhs) const {
87     return rhs < *this;
88   }
89 
90   bool operator<=(const ClassIterator& rhs) const {
91     return !(rhs < *this);
92   }
93 
94   bool operator>=(const ClassIterator& rhs) const {
95     return !(*this < rhs);
96   }
97 
98  protected:
99   ClassIteratorData data_;
100 };
101 
102 }  // namespace art
103 
104 #endif  // ART_LIBDEXFILE_DEX_CLASS_ITERATOR_H_
105