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
|
#ifndef DataFormats_Common_PtrVectorBase_h
#define DataFormats_Common_PtrVectorBase_h
// -*- C++ -*-
//
// Package: Common
// Class : PtrVectorBase
//
/**\class edm::PtrVectorBase
Description: Base class for PtrVector
Usage:
This class defines the common behavior for the PtrVector template class instances
*/
//
// Original Author: Chris Jones
// Created: Wed Oct 24 15:26:45 EDT 2007
//
// user include files
#include "DataFormats/Common/interface/RefCore.h"
// system include files
#include <typeinfo>
#include <vector>
#include <cassert>
// forward declarations
namespace edm {
class PtrVectorBase {
public:
typedef unsigned long key_type;
typedef key_type size_type;
explicit PtrVectorBase(ProductID const& productID,
void const* prodPtr = nullptr,
EDProductGetter const* prodGetter = nullptr)
: core_(productID, prodPtr, prodGetter, false), indicies_(), cachedItems_(nullptr) {}
PtrVectorBase(const PtrVectorBase&);
PtrVectorBase& operator=(const PtrVectorBase&) = delete;
virtual ~PtrVectorBase();
// ---------- const member functions ---------------------
/// Checks for null
bool isNull() const { return !isNonnull(); }
/// Checks for non-null
//bool isNonnull() const {return id().isValid(); }
bool isNonnull() const { return core_.isNonnull(); }
/// Checks for null
bool operator!() const { return isNull(); }
/// Accessor for product ID.
ProductID id() const { return core_.id(); }
/// Accessor for product getter.
EDProductGetter const* productGetter() const { return core_.productGetter(); }
bool hasCache() const { return cachedItems_; }
/// True if the data is in memory or is available in the Event
/// No type checking is done.
bool isAvailable() const;
/// Is the RefVector empty
bool empty() const { return indicies_.empty(); }
/// Size of the RefVector
size_type size() const { return indicies_.size(); }
/// Capacity of the RefVector
size_type capacity() const { return indicies_.capacity(); }
/// Clear the PtrVector
void clear() {
core_ = RefCore();
indicies_.clear();
if (cachedItems_) {
delete cachedItems_.load();
cachedItems_.store(nullptr);
}
}
bool operator==(PtrVectorBase const& iRHS) const;
// ---------- static member functions --------------------
// ---------- member functions ---------------------------
/// Reserve space for RefVector
void reserve(size_type n) {
indicies_.reserve(n);
if (cachedItems_) {
(*cachedItems_).reserve(n);
}
}
void setProductGetter(EDProductGetter* iGetter) const { core_.setProductGetter(iGetter); }
bool isTransient() const { return core_.isTransient(); }
void const* product() const { return nullptr; }
protected:
PtrVectorBase();
/// swap
void swap(PtrVectorBase& other);
void push_back_base(RefCore const& core, key_type iKey, void const* iData);
std::vector<void const*>::const_iterator void_begin() const {
getProduct_();
if (not checkCachedItems()) {
return emptyCache().begin();
}
return (*cachedItems_).begin();
}
std::vector<void const*>::const_iterator void_end() const {
getProduct_();
if (not checkCachedItems()) {
return emptyCache().end();
}
return (*cachedItems_).end();
}
template <typename TPtr>
TPtr makePtr(unsigned long iIndex) const {
if (isTransient()) {
return TPtr(reinterpret_cast<typename TPtr::value_type const*>((*cachedItems_)[iIndex]), indicies_[iIndex]);
}
if (hasCache() && ((*cachedItems_)[iIndex] != nullptr || productGetter() == nullptr)) {
return TPtr(
this->id(), reinterpret_cast<typename TPtr::value_type const*>((*cachedItems_)[iIndex]), indicies_[iIndex]);
}
return TPtr(this->id(), indicies_[iIndex], productGetter());
}
template <typename TPtr>
TPtr makePtr(std::vector<void const*>::const_iterator const iIt) const {
if (isTransient()) {
return TPtr(reinterpret_cast<typename TPtr::value_type const*>(*iIt), indicies_[iIt - (*cachedItems_).begin()]);
}
if (hasCache() && (*iIt != nullptr || productGetter() == nullptr)) {
return TPtr(this->id(),
reinterpret_cast<typename TPtr::value_type const*>(*iIt),
indicies_[iIt - (*cachedItems_).begin()]);
}
return TPtr(this->id(), indicies_[iIt - (*cachedItems_).begin()], productGetter());
}
private:
void getProduct_() const;
//virtual std::type_info const& typeInfo() const = 0;
virtual std::type_info const& typeInfo() const {
assert(false);
return typeid(void);
}
//returns false if the cache is not yet set
bool checkCachedItems() const;
//Used when we need an iterator but cache is not yet set
static const std::vector<void const*>& emptyCache();
// ---------- member data --------------------------------
RefCore core_;
std::vector<key_type> indicies_;
mutable std::atomic<std::vector<void const*>*> cachedItems_; //! transient
};
} // namespace edm
#endif
|