FwdPtr

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
#ifndef DataFormats_Common_FwdPtr_h
#define DataFormats_Common_FwdPtr_h
// -*- C++ -*-
//
// Package:     Common
// Class  :     FwdPtr
//
/**\class edm::FwdPtr FwdPtr.h DataFormats/Common/interface/FwdPtr.h

 Description: Persistent 'pointer' to an item in a collection where the collection is in the edm::Event

 Usage:
    <usage>

*/
//
// Original Author:  Salvatore Rappoccio
//         Created:  Fri Feb  5 14:58:49 CST 2010
//

// user include files
#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
#include "DataFormats/Common/interface/EDProductGetter.h"
#include "DataFormats/Common/interface/GetProduct.h"
#include "DataFormats/Common/interface/Handle.h"
#include "DataFormats/Common/interface/OrphanHandle.h"
#include "DataFormats/Common/interface/Ptr.h"
#include "DataFormats/Common/interface/RefCore.h"
#include "DataFormats/Common/interface/TestHandle.h"
#include "DataFormats/Common/interface/traits.h"

#include "FWCore/Utilities/interface/EDMException.h"

// system include files
#include <cassert>

// forward declarations
namespace edm {
  template <typename T>
  class FwdPtr {
    friend class FwdPtrVectorBase;

  public:
    typedef unsigned long key_type;
    typedef T value_type;

    // General purpose constructor from two Ptrs.
    template <typename C>
    FwdPtr(const Ptr<C>& f, const Ptr<C>& b) : ptr_(f), backPtr_(b) {
      assert(f.isNull() == b.isNull());
    }

    FwdPtr() : ptr_(), backPtr_() {}

    /*     template<typename U> */
    /*     FwdPtr(FwdPtr<U> const& iOther, typename boost::enable_if_c<boost::is_base_of<T, U>::value>::type * t = 0): */
    /*     ptr_(iOther.ptr_, t), backPtr_(iOther.backPtr_,t) */
    /*     { */
    /*     } */

    /*     template<typename U> */
    /*     explicit */
    /*     FwdPtr(FwdPtr<U> const& iOther, typename boost::enable_if_c<boost::is_base_of<U, T>::value>::type * t = 0): */
    /*     ptr_(iOther.ptr_,t), backPtr_(iOther.backPtr_,t){} */

    /// Destructor
    ~FwdPtr() {}

    /// Dereference operator
    T const& operator*() const { return ptr_.isAvailable() ? ptr_.operator*() : backPtr_.operator*(); }

    /// Member dereference operator
    T const* operator->() const { return ptr_.isAvailable() ? ptr_.operator->() : backPtr_.operator->(); }

    /// Returns C++ pointer to the item
    T const* get() const { return ptr_.isAvailable() ? ptr_.get() : backPtr_.get(); }

    /// Checks for null
    bool isNull() const { return !isNonnull(); }

    /// Checks for non-null
    //bool isNonnull() const {return id().isValid(); }
    bool isNonnull() const { return ptr_.isNonnull() || backPtr_.isNonnull(); }
    /// Checks for null
    bool operator!() const { return isNull(); }

    /// Checks if collection is in memory or available
    /// in the event. No type checking is done.
    bool isAvailable() const { return ptr_.isAvailable() || backPtr_.isAvailable(); }

    /// Checks if this FwdPtr is transient (i.e. not persistable).
    bool isTransient() const { return ptr_.isTransient(); }

    /// Accessor for product ID.
    ProductID id() const { return ptr_.isNonnull() ? ptr_.id() : backPtr_.id(); }

    /// Accessor for product getter.
    EDProductGetter const* productGetter() const {
      //another thread might cause productGetter() to change its value
      EDProductGetter const* getter = ptr_.productGetter();
      if (getter)
        return getter;
      else
        return backPtr_.productGetter();
    }

    key_type key() const { return ptr_.isNonnull() ? ptr_.key() : backPtr_.key(); }

    bool hasProductCache() const { return ptr_.hasProductCache() || backPtr_.hasProductCache(); }

    RefCore const& refCore() const { return ptr_.isNonnull() ? ptr_.refCore() : backPtr_.refCore(); }
    // ---------- member functions ---------------------------

    void const* product() const { return nullptr; }

    Ptr<value_type> const& ptr() const { return ptr_; }
    Ptr<value_type> const& backPtr() const { return backPtr_; }

    //Used by ROOT storage
    CMS_CLASS_VERSION(10)

  private:
    Ptr<value_type> ptr_;
    Ptr<value_type> backPtr_;
  };

  template <typename T>
  inline bool operator==(FwdPtr<T> const& lhs, FwdPtr<T> const& rhs) {
    return (lhs.ptr() == rhs.ptr() || lhs.backPtr() == rhs.ptr() || lhs.ptr() == rhs.backPtr() ||
            lhs.backPtr() == rhs.backPtr());
  }

  template <typename T>
  inline bool operator!=(FwdPtr<T> const& lhs, FwdPtr<T> const& rhs) {
    return !(lhs == rhs);
  }

  template <typename T>
  inline bool operator<(FwdPtr<T> const& lhs, FwdPtr<T> const& rhs) {
    /// The ordering of integer keys guarantees that the ordering of FwdPtrs within
    /// a collection will be identical to the ordering of the referenced objects in the collection.
    return (lhs.ptr() < rhs.ptr());
  }

}  // namespace edm
#endif