Home | History | Annotate | Download | only in keystore
      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