• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // TODO: Insert description here. (generated by jdanis)
2 
3 #ifndef KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
4 #define KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
5 
6 #include <iterator>
7 #include <memory>
8 #include <optional>
9 #include <vector>
10 
11 namespace android {
12 namespace security {
13 
14 /*
15  * This iterator abstracts from a collection of the form
16  * std::shared_ptr<COLLECTION_TYPE<std::optional<T>>>
17  * such that it is defined both for nulled outer pointer and
18  * nulled entries. If shared_ptr(nullptr) is passed in, the iterator behaves
19  * like the end iterator yielding an empty collection. Nulled
20  * entries are skipped so that the iterator is always dereferencable unless
21  * it is equal to end.
22  * The default constructor always yields an iterator equal to end.
23  * The same iterator invalidation rules apply as they do for the iterators
24  * of the corresponding collection.
25  */
26 template <typename T, template <typename...> class Coll = std::vector>
27 class SharedNullableIterator {
28   public:
29     typedef Coll<std::optional<typename std::remove_const<T>::type>> CollectionType;
30     typedef std::shared_ptr<CollectionType> CollectionPtr;
31 
SharedNullableIterator()32     SharedNullableIterator() {}
SharedNullableIterator(const std::shared_ptr<CollectionType> & coll)33     explicit SharedNullableIterator(const std::shared_ptr<CollectionType>& coll) : coll_(coll) {
34         init();
35     }
SharedNullableIterator(std::shared_ptr<CollectionType> && coll)36     explicit SharedNullableIterator(std::shared_ptr<CollectionType>&& coll) : coll_(coll) {
37         init();
38     }
39 
SharedNullableIterator(const SharedNullableIterator & other)40     SharedNullableIterator(const SharedNullableIterator& other)
41         : coll_(other.coll_), cur_(other.cur_) {}
SharedNullableIterator(SharedNullableIterator && other)42     SharedNullableIterator(SharedNullableIterator&& other) noexcept
43         : coll_(std::move(other.coll_)), cur_(std::move(other.cur_)) {}
44 
45     SharedNullableIterator& operator++() {
46         inc();
47         return *this;
48     }
49     SharedNullableIterator operator++(int) {
50         SharedNullableIterator retval(*this);
51         ++(*this);
52         return retval;
53     }
54     T& operator*() const { return **cur_; }
55 
56     T* operator->() const { return &**cur_; }
57 
58     bool operator==(const SharedNullableIterator& other) const {
59         return cur_ == other.cur_ || (is_end() && other.is_end());
60     }
61     bool operator!=(const SharedNullableIterator& other) const { return !(*this == other); }
62 
63     SharedNullableIterator& operator=(const SharedNullableIterator&) = default;
64     SharedNullableIterator& operator=(SharedNullableIterator&&) noexcept = default;
65 
66   private:
is_end()67     inline bool is_end() const { return !coll_ || cur_ == coll_->end(); }
inc()68     inline void inc() {
69         if (!is_end()) {
70             do {
71                 ++cur_;
72                 // move forward to the next non null member or stay at end
73             } while (cur_ != coll_->end() && !(*cur_));
74         }
75     }
init()76     void init() {
77         if (coll_) {
78             // move forward to the first non null member
79             for (cur_ = coll_->begin(); cur_ != coll_->end() && !(*cur_); ++cur_) {
80             }
81         }
82     }
83 
84     CollectionPtr coll_;
85     typename CollectionType::iterator cur_;
86 };
87 
88 }  // namespace security
89 }  // namespace android
90 
91 namespace std {
92 template <typename T, template <typename...> class COLL>
93 struct iterator_traits<android::security::SharedNullableIterator<T, COLL>> {
94     typedef T& reference;
95     typedef T value_type;
96     typedef T* pointer;
97     typedef forward_iterator_tag iterator_category;
98 };
99 }
100 
101 #endif  // KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
102