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