18#ifndef ROOFIT_ROOFITCORE_INC_ROOSTLREFCOUNTLIST_H_
19#define ROOFIT_ROOFITCORE_INC_ROOSTLREFCOUNTLIST_H_
44 using Container_t = std::vector<T*>;
46 static constexpr std::size_t minSizeForNamePointerOrdering = 7;
51 if(_renameCounter ==
nullptr) _renameCounter =
62 void Add(T * obj, std::size_t initialCount = 1) {
64 if(initialCount == 0)
return;
66 auto foundItem = findByPointer(obj);
68 if (foundItem != _storage.end()) {
69 _refCount[foundItem - _storage.begin()] += initialCount;
72 if(!_orderedStorage.empty()) {
73 _orderedStorage.insert(lowerBoundByNamePointer(obj), obj);
75 _storage.push_back(obj);
76 _refCount.push_back(initialCount);
82 std::size_t refCount(
typename Container_t::const_iterator item)
const {
83 assert(_storage.size() == _refCount.size());
85 return item != _storage.end() ? _refCount[item - _storage.begin()] : 0;
90 template<
typename Obj_t>
91 std::size_t refCount(
const Obj_t * obj)
const {
92 return refCount(findByPointer(obj));
96 typename Container_t::const_iterator begin()
const {
97 return _storage.begin();
101 typename Container_t::const_iterator
end()
const {
102 return _storage.end();
106 typename Container_t::value_type operator[](std::size_t
index)
const {
107 return _storage[
index];
112 const Container_t& containedObjects()
const {
118 std::size_t
size()
const {
119 assert(_storage.size() == _refCount.size());
121 return _storage.size();
124 void reserve(std::size_t amount) {
125 _storage.reserve(amount);
126 _refCount.reserve(amount);
127 _orderedStorage.reserve(amount);
133 return _storage.empty();
138 template<
typename Obj_t>
139 typename Container_t::const_iterator findByPointer(
const Obj_t * item)
const {
140 return std::find(_storage.begin(), _storage.end(), item);
145 typename Container_t::const_iterator findByName(
const char *
name)
const {
148 const std::string theName(
name);
149 auto byName = [&theName](
const T * element) {
150 return element->GetName() == theName;
153 return std::find_if(_storage.begin(), _storage.end(), byName);
158 inline T* findByNamePointer(
const T * item)
const {
159 return findByNamePointer(item->namePtr());
162 T* findByNamePointer(
TNamed const* namePtr)
const {
163 if(
size() < minSizeForNamePointerOrdering) {
164 auto byNamePointer = [namePtr](
const T * element) {
165 return element->namePtr() == namePtr;
168 auto found = std::find_if(_storage.begin(), _storage.end(), byNamePointer);
169 return found != _storage.end() ? *found :
nullptr;
173 auto first = lowerBoundByNamePointer(namePtr);
174 if(first == _orderedStorage.end())
return nullptr;
175 if(namePtr != (*first)->namePtr())
return nullptr;
182 template<
typename Obj_t>
183 bool containsByPointer(
const Obj_t * obj)
const {
184 return findByPointer(obj) != _storage.end();
189 bool containsByNamePtr(
const T * obj)
const {
190 return findByNamePointer(obj);
195 bool containsSameName(
const char *
name)
const {
196 return findByName(
name) != _storage.end();
207 int Remove(
const T * obj,
bool force =
false) {
208 auto item = findByPointer(obj);
210 if (item != _storage.end()) {
211 const std::size_t pos = item - _storage.begin();
213 const UInt_t origRefCount = _refCount[pos];
215 if (force || --_refCount[pos] == 0) {
218 _storage.erase(_storage.begin() + pos);
219 _refCount.erase(_refCount.begin() + pos);
220 if(!_orderedStorage.empty()) {
227 _orderedStorage.erase(std::find(_orderedStorage.begin(), _orderedStorage.end(), obj));
242 int Replace(
const T * oldObj, T * newObj) {
243 auto item = findByPointer(oldObj);
245 if (item != _storage.end()) {
246 const std::size_t pos = item - _storage.begin();
247 _storage[pos] = newObj;
249 _orderedStorage.clear();
250 return _refCount[pos];
258 void RemoveAll(
const T * obj) {
267 inline typename std::vector<T*>::const_iterator lowerBoundByNamePointer(
const T * item)
const {
268 return lowerBoundByNamePointer(item->namePtr());
271 typename std::vector<T*>::const_iterator lowerBoundByNamePointer(
TNamed const* namePtr)
const {
275 if(orderedStorageNeedsSorting() || _orderedStorage.size() != _storage.size()) initializeOrderedStorage();
277 return std::lower_bound(_orderedStorage.begin(), _orderedStorage.end(), namePtr,
278 [](
const auto&
x,
TNamed const* npt) ->
bool {
279 return x->namePtr() < npt;
283 bool orderedStorageNeedsSorting()
const {
290 return _renameCounterForLastSorting != *_renameCounter;
293 void initializeOrderedStorage()
const {
294 _orderedStorage.clear();
295 _orderedStorage.reserve(_storage.size());
296 for(std::size_t i = 0; i < _storage.size(); ++i) {
297 _orderedStorage.push_back(_storage[i]);
299 std::sort(_orderedStorage.begin(), _orderedStorage.end(),
300 [](
auto&
a,
auto&
b) {
301 return a->namePtr() != b->namePtr() ? a->namePtr() < b->namePtr() : a < b;
303 _renameCounterForLastSorting = *_renameCounter;
306 Container_t _storage;
307 std::vector<UInt_t> _refCount;
308 mutable std::vector<T*> _orderedStorage;
309 mutable unsigned long _renameCounterForLastSorting = 0;
314 static std::size_t
const* _renameCounter;
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define ClassDef(name, id)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Binding & operator=(OUT(*fun)(void))
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
static const std::size_t & renameCounter()
renamed in this RooFit process.
The TNamed class is the base class for all named ROOT classes.
void convert(R1 const &, R2 const)
TMatrixT< Element > & Add(TMatrixT< Element > &target, Element scalar, const TMatrixT< Element > &source)
Modify addition: target += scalar * source.