RefVectorHolderBase

const_iterator

const_iterator_imp

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
#ifndef DataFormats_Common_RefVectorHolderBase_h
#define DataFormats_Common_RefVectorHolderBase_h

#include "DataFormats/Common/interface/RefHolderBase.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include <cstddef>
#include <memory>

namespace edm {
  template <typename T>
  class RefToBase;
  namespace reftobase {
    class RefVectorHolderBase {
    public:
      virtual ~RefVectorHolderBase() {}
      using size_type = size_t;
      using value_type = RefHolderBase;
      void swap(RefVectorHolderBase&) {}  // nothing to swap
      virtual bool empty() const = 0;
      virtual size_type size() const = 0;
      virtual void clear() = 0;
      virtual void reserve(size_type n) = 0;
      virtual ProductID id() const = 0;
      virtual EDProductGetter const* productGetter() const = 0;
      virtual RefVectorHolderBase* clone() const = 0;
      virtual RefVectorHolderBase* cloneEmpty() const = 0;
      virtual void push_back(RefHolderBase const* r) = 0;
      // the following structure is public
      // to allow dictionary to compile
      //    protected:
      struct const_iterator_imp {
        using difference_type = ptrdiff_t;
        const_iterator_imp() {}
        virtual ~const_iterator_imp() {}
        virtual const_iterator_imp* clone() const = 0;
        virtual void increase() = 0;
        virtual void decrease() = 0;
        virtual void increase(difference_type d) = 0;
        virtual void decrease(difference_type d) = 0;
        virtual bool equal_to(const_iterator_imp const*) const = 0;
        virtual bool less_than(const_iterator_imp const*) const = 0;
        virtual void assign(const_iterator_imp const*) = 0;
        virtual std::shared_ptr<RefHolderBase> deref() const = 0;
        virtual difference_type difference(const_iterator_imp const*) const = 0;
      };

      struct const_iterator {
        using iterator_category = std::random_access_iterator_tag;
        using value_type = std::shared_ptr<RefHolderBase>;
        using pointer = void**;
        using reference = void*&;
        using difference_type = std::ptrdiff_t;
        const_iterator() : i(nullptr) {}
        const_iterator(const_iterator_imp* it) : i(it) {}
        const_iterator(const_iterator const& it) : i(it.isValid() ? it.i->clone() : nullptr) {}
        ~const_iterator() { delete i; }
        const_iterator& operator=(const_iterator const& it) {
          if (isInvalid())
            i = it.i;
          else
            i->assign(it.i);
          return *this;
        }
        const_iterator& operator++() {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
          i->increase();
          return *this;
        }
        const_iterator operator++(int) {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to postincrement an inavlid RefToBaseVector<T>::const_iterator\n");
          const_iterator ci = *this;
          i->increase();
          return ci;
        }
        const_iterator& operator--() {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
          i->decrease();
          return *this;
        }
        const_iterator operator--(int) {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to postdecrement an inavlid RefToBaseVector<T>::const_iterator\n");
          const_iterator ci = *this;
          i->decrease();
          return ci;
        }
        difference_type operator-(const_iterator const& o) const {
          if (isInvalid() && o.isInvalid())
            return 0;
          if (isInvalid() || o.isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
          return i->difference(o.i);
        }
        const_iterator operator+(difference_type n) const {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to compute sum with an inavlid RefToBaseVector<T>::const_iterator\n");
          const_iterator_imp* ii = i->clone();
          ii->increase(n);
          return const_iterator(ii);
        }
        const_iterator operator-(difference_type n) const {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
          const_iterator_imp* ii = i->clone();
          ii->decrease(n);
          return const_iterator(ii);
        }
        bool operator<(const_iterator const& o) const {
          if (isInvalid() && o.isInvalid())
            return false;
          if (isInvalid() || o.isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to compute < operator with an inavlid RefToBaseVector<T>::const_iterator\n");
          return i->less_than(o.i);
        }
        bool operator==(const const_iterator& ci) const {
          if (isInvalid() && ci.isInvalid())
            return true;
          if (isInvalid() || ci.isInvalid())
            return false;
          return i->equal_to(ci.i);
        }
        bool operator!=(const const_iterator& ci) const {
          if (isInvalid() && ci.isInvalid())
            return false;
          if (isInvalid() || ci.isInvalid())
            return true;
          return !i->equal_to(ci.i);
        }
        value_type operator*() const {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to dereference an inavlid RefToBaseVector<T>::const_iterator\n");
          return i->deref();
        }
        const_iterator& operator-=(difference_type d) {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
          i->decrease(d);
          return *this;
        }
        const_iterator& operator+=(difference_type d) {
          if (isInvalid())
            Exception::throwThis(errors::InvalidReference,
                                 "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
          i->increase(d);
          return *this;
        }
        bool isValid() const { return i != nullptr; }
        bool isInvalid() const { return i == nullptr; }

      private:
        const_iterator_imp* i;
      };

      virtual const_iterator begin() const = 0;
      virtual const_iterator end() const = 0;
      template <typename T>
      RefToBase<T> getRef(size_t idx) const;
      virtual size_t keyForIndex(size_t idx) const = 0;

      /// Checks if product collection is in memory or available
      /// in the Event. No type checking is done.
      virtual bool isAvailable() const = 0;

    private:
      virtual std::shared_ptr<reftobase::RefHolderBase> refBase(size_t idx) const = 0;
    };

    template <typename T>
    RefToBase<T> RefVectorHolderBase::getRef(size_t idx) const {
      std::shared_ptr<reftobase::RefHolderBase> rb = refBase(idx);
      return RefToBase<T>(rb);
    }

    // Free swap function
    inline void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) { lhs.swap(rhs); }
  }  // namespace reftobase
}  // namespace edm

#endif