File indexing completed on 2025-09-15 09:12:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef ROO_ABS_COLLECTION
0017 #define ROO_ABS_COLLECTION
0018
0019 #include <RooAbsArg.h>
0020 #include <RooCmdArg.h>
0021 #include <RooFit/UniqueId.h>
0022 #include <RooLinkedListIter.h>
0023 #include <RooPrintable.h>
0024
0025
0026
0027
0028 #include <ROOT/RRangeCast.hxx>
0029
0030 #include <ROOT/RSpan.hxx>
0031
0032 #include <TClass.h>
0033 #include <TObject.h>
0034 #include <TString.h>
0035
0036 #include <string>
0037 #include <unordered_map>
0038 #include <vector>
0039 #include <type_traits>
0040 #include <memory>
0041
0042
0043
0044 template <typename T, typename Range_t>
0045 ROOT::RRangeCast<T, false, Range_t> static_range_cast(Range_t &&coll)
0046 {
0047 return ROOT::RangeStaticCast<T>(std::forward<Range_t>(coll));
0048 }
0049
0050
0051
0052 template <typename T, typename Range_t>
0053 ROOT::RRangeCast<T, true, Range_t> dynamic_range_cast(Range_t &&coll)
0054 {
0055 return ROOT::RangeDynCast<T>(std::forward<Range_t>(coll));
0056 }
0057
0058
0059 namespace RooFit {
0060 namespace Detail {
0061 struct HashAssistedFind;
0062 }
0063 }
0064
0065 class RooAbsCollection : public TObject, public RooPrintable {
0066 public:
0067 using Storage_t = std::vector<RooAbsArg*>;
0068 using const_iterator = Storage_t::const_iterator;
0069
0070
0071
0072 RooAbsCollection();
0073 RooAbsCollection(const char *name);
0074 virtual TObject* clone(const char* newname=nullptr) const = 0 ;
0075 virtual TObject* create(const char* newname) const = 0 ;
0076 TObject* Clone(const char* newname=nullptr) const override {
0077 return clone(newname?newname:GetName()) ;
0078 }
0079 ~RooAbsCollection() override;
0080
0081
0082
0083
0084 RooAbsCollection(const RooAbsCollection& other, const char *name="");
0085 RooAbsCollection& operator=(const RooAbsCollection& other);
0086
0087 void assign(const RooAbsCollection& other) const;
0088 RooAbsCollection &assignValueOnly(const RooAbsCollection& other, bool forceIfSizeOne=false);
0089 void assignFast(const RooAbsCollection& other, bool setValDirty=true) const;
0090
0091
0092 RooAbsCollection(RooAbsCollection && other);
0093
0094
0095
0096
0097
0098 RooFit::UniqueId<RooAbsCollection> const& uniqueId() const { return _uniqueId; }
0099
0100
0101 RooAbsCollection *snapshot(bool deepCopy=true) const ;
0102 bool snapshot(RooAbsCollection& output, bool deepCopy=true) const ;
0103
0104
0105
0106 void setHashTableSize(Int_t number) {
0107 _sizeThresholdForMapSearch = number;
0108 }
0109
0110
0111 Int_t getHashTableSize() const {
0112 return _sizeThresholdForMapSearch;
0113 }
0114
0115
0116 Storage_t const& get() const { return _list; }
0117
0118
0119 virtual bool add(const RooAbsArg& var, bool silent=false) ;
0120
0121
0122
0123 #ifdef ROOFIT_MEMORY_SAFE_INTERFACES
0124 protected:
0125 #endif
0126 virtual bool addOwned(RooAbsArg& var, bool silent=false);
0127 #ifdef ROOFIT_MEMORY_SAFE_INTERFACES
0128 public:
0129 #endif
0130 bool addOwned(std::unique_ptr<RooAbsArg> var, bool silent=false);
0131 virtual RooAbsArg *addClone(const RooAbsArg& var, bool silent=false) ;
0132 virtual bool replace(const RooAbsArg& var1, const RooAbsArg& var2) ;
0133 bool replace(RooAbsArg* var1, std::unique_ptr<RooAbsArg> var2) ;
0134 virtual bool remove(const RooAbsArg& var, bool silent=false, bool matchByNameOnly=false) ;
0135 virtual void removeAll() ;
0136
0137 template<typename Iterator_t,
0138 typename value_type = typename std::remove_pointer<typename std::iterator_traits<Iterator_t>::value_type>,
0139 typename = std::enable_if<std::is_convertible<const value_type*, const RooAbsArg*>::value> >
0140 bool add(Iterator_t beginIt, Iterator_t endIt, bool silent=false) {
0141 bool result = false ;
0142 _list.reserve(_list.size() + std::distance(beginIt, endIt));
0143 for (auto it = beginIt; it != endIt; ++it) {
0144 result |= add(**it,silent);
0145 }
0146 return result;
0147 }
0148
0149
0150
0151 bool add(const RooAbsCollection& list, bool silent=false) {
0152 return add(list._list.begin(), list._list.end(), silent);
0153 }
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170 template <class Arg_t>
0171 bool addTyped(const RooAbsCollection &list, bool silent = false)
0172 {
0173 for (RooAbsArg *arg : list) {
0174 if (!dynamic_cast<Arg_t *>(arg)) {
0175 throwAddTypedException(Arg_t::Class(), arg);
0176 }
0177 }
0178 return add(list, silent);
0179 }
0180 virtual bool addOwned(const RooAbsCollection& list, bool silent=false);
0181 bool addOwned(RooAbsCollection&& list, bool silent=false);
0182 virtual void addClone(const RooAbsCollection& list, bool silent=false);
0183 bool replace(const RooAbsCollection &other);
0184 bool remove(const RooAbsCollection& list, bool silent=false, bool matchByNameOnly=false) ;
0185 template<class forwardIt>
0186 void remove(forwardIt rangeBegin, forwardIt rangeEnd, bool silent = false, bool matchByNameOnly = false) {
0187 for (forwardIt it = rangeBegin; it != rangeEnd; ++it) {
0188 static_assert(std::is_same<
0189 typename std::iterator_traits<forwardIt>::value_type,
0190 RooAbsArg*>::value, "Can only remove lists of RooAbsArg*.");
0191 auto castedElm = static_cast<RooAbsArg*>(*it);
0192 remove(*castedElm, silent, matchByNameOnly);
0193 }
0194 }
0195
0196
0197 double getRealValue(const char* name, double defVal=0.0, bool verbose=false) const ;
0198 const char* getCatLabel(const char* name, const char* defVal="", bool verbose=false) const ;
0199 Int_t getCatIndex(const char* name, Int_t defVal=0, bool verbose=false) const ;
0200 const char* getStringValue(const char* name, const char* defVal="", bool verbose=false) const ;
0201 bool setRealValue(const char* name, double newVal=0.0, bool verbose=false) ;
0202 bool setCatLabel(const char* name, const char* newVal="", bool verbose=false) ;
0203 bool setCatIndex(const char* name, Int_t newVal=0, bool verbose=false) ;
0204 bool setStringValue(const char* name, const char* newVal="", bool verbose=false) ;
0205
0206
0207 void setAttribAll(const Text_t* name, bool value=true) ;
0208
0209
0210 RooAbsArg *find(const char *name) const ;
0211 RooAbsArg *find(const RooAbsArg&) const ;
0212
0213
0214 TObject* FindObject(const char* name) const override { return find(name); }
0215
0216
0217 TObject* FindObject(const TObject* obj) const override { auto arg = dynamic_cast<const RooAbsArg*>(obj); return (arg) ? find(*arg) : nullptr; }
0218
0219
0220
0221 bool contains(const RooAbsArg& var) const {
0222 return find(var) != nullptr;
0223 }
0224
0225 virtual bool containsInstance(const RooAbsArg& var) const {
0226 return std::find(_list.begin(), _list.end(), &var) != _list.end();
0227 }
0228 RooAbsCollection* selectByAttrib(const char* name, bool value) const ;
0229 bool selectCommon(const RooAbsCollection& refColl, RooAbsCollection& outColl) const ;
0230 RooAbsCollection* selectCommon(const RooAbsCollection& refColl) const ;
0231 RooAbsCollection* selectByName(const char* nameList, bool verbose=false) const ;
0232 bool equals(const RooAbsCollection& otherColl) const ;
0233 bool hasSameLayout(const RooAbsCollection& other) const;
0234
0235 template<typename Iterator_t,
0236 typename value_type = typename std::remove_pointer<typename std::iterator_traits<Iterator_t>::value_type>,
0237 typename = std::enable_if<std::is_convertible<const value_type*, const RooAbsArg*>::value> >
0238 bool overlaps(Iterator_t otherCollBegin, Iterator_t otherCollEnd) const {
0239 for (auto it = otherCollBegin; it != otherCollEnd; ++it) {
0240 if (find(**it)) {
0241 return true ;
0242 }
0243 }
0244 return false ;
0245 }
0246
0247
0248
0249 bool overlaps(const RooAbsCollection& otherColl) const {
0250 return overlaps(otherColl._list.begin(), otherColl._list.end());
0251 }
0252
0253 const_iterator begin() const {
0254 return _list.begin();
0255 }
0256
0257 const_iterator end() const {
0258 return _list.end();
0259 }
0260
0261 Storage_t::const_reverse_iterator rbegin() const {
0262 return _list.rbegin();
0263 }
0264
0265 Storage_t::const_reverse_iterator rend() const {
0266 return _list.rend();
0267 }
0268
0269 Storage_t::size_type size() const {
0270 return _list.size();
0271 }
0272
0273 bool empty() const {
0274 return _list.empty();
0275 }
0276
0277 void reserve(Storage_t::size_type count) {
0278 _list.reserve(count);
0279 }
0280
0281
0282 void clear() {
0283 removeAll();
0284 }
0285
0286
0287 inline Int_t getSize() const R__SUGGEST_ALTERNATIVE("size() returns true size.") {
0288 return _list.size();
0289 }
0290
0291 inline RooAbsArg *first() const {
0292
0293
0294 return _list.empty() ? nullptr : _list.front();
0295 }
0296
0297 RooAbsArg * operator[](Storage_t::size_type i) const {
0298 return _list[i];
0299 }
0300
0301
0302
0303 inline Int_t index(const RooAbsArg* arg) const {
0304 auto item = std::find(_list.begin(), _list.end(), arg);
0305 return item != _list.end() ? item - _list.begin() : -1;
0306 }
0307
0308
0309 inline Int_t index(const RooAbsArg& arg) const {
0310 return index(&arg);
0311 }
0312
0313 Int_t index(const char* name) const;
0314
0315 inline void Print(Option_t *options= nullptr) const override {
0316
0317 printStream(defaultPrintStream(),defaultPrintContents(options),defaultPrintStyle(options));
0318 }
0319 std::string contentsString() const ;
0320
0321
0322 void printName(std::ostream& os) const override ;
0323 void printTitle(std::ostream& os) const override ;
0324 void printClassName(std::ostream& os) const override ;
0325 void printValue(std::ostream& os) const override ;
0326 void printMultiline(std::ostream& os, Int_t contents, bool verbose=false, TString indent="") const override ;
0327
0328 Int_t defaultPrintContents(Option_t* opt) const override ;
0329
0330
0331 void printLatex(const RooCmdArg& arg1={}, const RooCmdArg& arg2={},
0332 const RooCmdArg& arg3={}, const RooCmdArg& arg4={},
0333 const RooCmdArg& arg5={}, const RooCmdArg& arg6={},
0334 const RooCmdArg& arg7={}, const RooCmdArg& arg8={}) const ;
0335 void printLatex(std::ostream& ofs, Int_t ncol, const char* option="NEYU", Int_t sigDigit=1,
0336 const RooLinkedList& siblingLists=RooLinkedList(), const RooCmdArg* formatCmd=nullptr) const ;
0337
0338 void setName(const char *name) {
0339
0340 _name= name;
0341 }
0342 const char* GetName() const override {
0343
0344 return _name.Data() ;
0345 }
0346 bool isOwning() const {
0347
0348 return _ownCont ;
0349 }
0350
0351 bool allInRange(const char* rangeSpec) const ;
0352
0353 void dump() const ;
0354
0355 void releaseOwnership() { _ownCont = false ; }
0356 void takeOwnership() { _ownCont = true ; }
0357
0358 void sort(bool reverse = false);
0359 void sortTopologically();
0360
0361 void RecursiveRemove(TObject *obj) override;
0362
0363 void useHashMapForFind(bool flag) const;
0364
0365
0366
0367 struct RooAbsArgPtrOrDouble {
0368 RooAbsArgPtrOrDouble(RooAbsArg & arg) : ptr{&arg}, hasPtr{true} {}
0369 RooAbsArgPtrOrDouble(double x) : val{x}, hasPtr{false} {}
0370
0371 RooAbsArg * ptr = nullptr;
0372 double val = 0.0;
0373 bool hasPtr = false;
0374 };
0375
0376 protected:
0377 Storage_t _list;
0378 using LegacyIterator_t = TIteratorToSTLInterface<Storage_t>;
0379
0380 bool _ownCont = false;
0381 TString _name;
0382 bool _allRRV = true;
0383
0384 void deleteList() ;
0385
0386 inline TNamed* structureTag() { if (_structureTag==nullptr) makeStructureTag() ; return _structureTag ; }
0387 inline TNamed* typedStructureTag() { if (_typedStructureTag==nullptr) makeTypedStructureTag() ; return _typedStructureTag ; }
0388
0389 mutable TNamed* _structureTag{nullptr};
0390 mutable TNamed* _typedStructureTag{nullptr};
0391
0392 inline void clearStructureTags() { _structureTag = nullptr ; _typedStructureTag = nullptr ; }
0393
0394 void makeStructureTag() {}
0395 void makeTypedStructureTag() {}
0396
0397
0398 virtual bool canBeAdded(const RooAbsArg& arg, bool silent) const = 0;
0399
0400 template<class T>
0401 static void assert_is_no_temporary(T &&) {
0402 static_assert(!std::is_rvalue_reference<T&&>::value,
0403 "A reference to a temporary RooAbsArg will be passed to a RooAbsCollection constructor! "
0404 "This is not allowed, because the collection will not own the arguments. "
0405 "Hence, the collection will contain dangling pointers when the temporary goes out of scope."
0406 );
0407 }
0408
0409 private:
0410
0411 bool replaceImpl(const RooAbsArg& var1, const RooAbsArg& var2);
0412
0413 using HashAssistedFind = RooFit::Detail::HashAssistedFind;
0414 mutable HashAssistedFind *_hashAssistedFind = nullptr;
0415 std::size_t _sizeThresholdForMapSearch = 100;
0416
0417 void insert(RooAbsArg*);
0418
0419 static void throwAddTypedException(TClass *klass, RooAbsArg *arg);
0420
0421 const RooFit::UniqueId<RooAbsCollection> _uniqueId;
0422
0423 ClassDefOverride(RooAbsCollection,3)
0424 };
0425
0426 #endif