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 31 SharedNullableIterator() {} 32 SharedNullableIterator(const std::shared_ptr<CollectionType>& coll) : coll_(coll) { init(); } 33 SharedNullableIterator(std::shared_ptr<CollectionType>&& coll) : coll_(coll) { init(); } 34 35 SharedNullableIterator(const SharedNullableIterator& other) 36 : coll_(other.coll_), cur_(other.cur_) {} 37 SharedNullableIterator(SharedNullableIterator&& other) 38 : coll_(std::move(other.coll_)), cur_(std::move(other.cur_)) {} 39 40 SharedNullableIterator& operator++() { 41 inc(); 42 return *this; 43 } 44 SharedNullableIterator operator++(int) { 45 SharedNullableIterator retval(*this); 46 ++(*this); 47 return retval; 48 } 49 T& operator*() const { return **cur_; } 50 51 T* operator->() const { return &**cur_; } 52 53 bool operator==(const SharedNullableIterator& other) const { 54 return cur_ == other.cur_ || (is_end() && other.is_end()); 55 } 56 bool operator!=(const SharedNullableIterator& other) const { return !(*this == other); } 57 58 SharedNullableIterator& operator=(const SharedNullableIterator&) = default; 59 SharedNullableIterator& operator=(SharedNullableIterator&&) = default; 60 61 private: 62 inline bool is_end() const { return !coll_ || cur_ == coll_->end(); } 63 inline void inc() { 64 if (!is_end()) { 65 do { 66 ++cur_; 67 // move forward to the next non null member or stay at end 68 } while (cur_ != coll_->end() && !(*cur_)); 69 } 70 } 71 void init() { 72 if (coll_) { 73 // move forward to the first non null member 74 for (cur_ = coll_->begin(); cur_ != coll_->end() && !(*cur_); ++cur_) { 75 } 76 } 77 } 78 79 CollectionPtr coll_; 80 typename CollectionType::iterator cur_; 81 }; 82 83 } // namespace security 84 } // namespace android 85 86 namespace std { 87 template <typename T, template <typename...> class COLL> 88 struct iterator_traits<android::security::SharedNullableIterator<T, COLL>> { 89 typedef T& reference; 90 typedef T value_type; 91 typedef T* pointer; 92 typedef forward_iterator_tag iterator_category; 93 }; 94 } 95 96 #endif // KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_ 97