1 /*
2 * Copyright (C) 2024 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 #pragma once
17
18 #include <android/content/AttributionSourceState.h>
19
20 #include <iterator>
21
22 // AttributionSourceState are essentially an intrusive linked list, where the next field carries
23 // the pointer to the next element. These iterator helpers allow for convenient iteration over the
24 // entire attribution chain. Usage:
25 // std::for_each(AttrSourceIter::begin(mAttributionSourceState), AttrSourceIter::end(), ...)
26 namespace android::media::permission::AttrSourceIter {
27
28 class ConstIter {
29 public:
30 using iterator_category = std::forward_iterator_tag;
31 using difference_type = std::ptrdiff_t;
32 using value_type = ::android::content::AttributionSourceState;
33 using pointer = const value_type*;
34 using reference = const value_type&;
35
ConstIter(const::android::content::AttributionSourceState * attr)36 ConstIter(const ::android::content::AttributionSourceState* attr) : mAttr(attr) {}
37
38 reference operator*() const { return *mAttr; }
39 pointer operator->() const { return mAttr; }
40
41 ConstIter& operator++() {
42 mAttr = !mAttr->next.empty() ? mAttr->next.data() : nullptr;
43 return *this;
44 }
45 ConstIter operator++(int) {
46 ConstIter tmp = *this;
47 ++(*this);
48 return tmp;
49 }
50
51 friend bool operator==(const ConstIter& a, const ConstIter& b) = default;
52
end()53 static ConstIter end() { return ConstIter(nullptr); }
54
55 private:
56 const ::android::content::AttributionSourceState* mAttr;
57 };
58
59 /**
60 * Non-const iterator. Note, AttributionSourceState is conceptually a linked list on the next field.
61 * Be very careful if `next` is modified over iteration, as it can go wrong easily.
62 */
63 class Iter {
64 public:
65 using iterator_category = std::forward_iterator_tag;
66 using difference_type = std::ptrdiff_t;
67 using value_type = ::android::content::AttributionSourceState;
68 using pointer = value_type*;
69 using reference = value_type&;
70
Iter(::android::content::AttributionSourceState * attr)71 Iter(::android::content::AttributionSourceState* attr) : mAttr(attr) {}
72
73 reference operator*() const { return *mAttr; }
74 pointer operator->() const { return mAttr; }
75
76 Iter& operator++() {
77 mAttr = !mAttr->next.empty() ? mAttr->next.data() : nullptr;
78 return *this;
79 }
80 Iter operator++(int) {
81 Iter tmp = *this;
82 ++(*this);
83 return tmp;
84 }
85
86 friend bool operator==(const Iter& a, const Iter& b) = default;
87
ConstIter()88 operator ConstIter() const { return ConstIter(mAttr); }
89
end()90 static Iter end() { return Iter(nullptr); }
91
92 private:
93 ::android::content::AttributionSourceState* mAttr;
94 };
95
begin(::android::content::AttributionSourceState & a)96 inline Iter begin(::android::content::AttributionSourceState& a) {
97 return Iter(&a);
98 }
end()99 inline Iter end() {
100 return Iter::end();
101 }
cbegin(const::android::content::AttributionSourceState & a)102 inline ConstIter cbegin(const ::android::content::AttributionSourceState& a) {
103 return ConstIter(&a);
104 }
cend()105 inline ConstIter cend() {
106 return ConstIter::end();
107 }
108 } // namespace com::android::media::permission::AttrSourceIter
109