File indexing completed on 2025-01-18 10:11:17
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) 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
0254
0255
0256 inline TIterator* createIterator(bool dir = kIterForward) const
0257 R__DEPRECATED(6,34, "begin(), end() and range-based for loops.") {
0258
0259 return new RooLinkedListIter(makeLegacyIterator(dir));
0260 }
0261
0262
0263
0264 RooLinkedListIter iterator(bool dir = kIterForward) const
0265 R__DEPRECATED(6,34, "begin(), end() and range-based for loops.") {
0266 return RooLinkedListIter(makeLegacyIterator(dir));
0267 }
0268
0269
0270
0271 RooFIter fwdIterator() const
0272 R__DEPRECATED(6,34, "begin(), end() and range-based for loops.") {
0273 return RooFIter(makeLegacyIterator());
0274 }
0275
0276 const_iterator begin() const {
0277 return _list.begin();
0278 }
0279
0280 const_iterator end() const {
0281 return _list.end();
0282 }
0283
0284 Storage_t::const_reverse_iterator rbegin() const {
0285 return _list.rbegin();
0286 }
0287
0288 Storage_t::const_reverse_iterator rend() const {
0289 return _list.rend();
0290 }
0291
0292 Storage_t::size_type size() const {
0293 return _list.size();
0294 }
0295
0296 bool empty() const {
0297 return _list.empty();
0298 }
0299
0300 void reserve(Storage_t::size_type count) {
0301 _list.reserve(count);
0302 }
0303
0304
0305 void clear() {
0306 removeAll();
0307 }
0308
0309
0310 inline Int_t getSize() const R__SUGGEST_ALTERNATIVE("size() returns true size.") {
0311 return _list.size();
0312 }
0313
0314 inline RooAbsArg *first() const {
0315
0316
0317 return _list.empty() ? nullptr : _list.front();
0318 }
0319
0320 RooAbsArg * operator[](Storage_t::size_type i) const {
0321 return _list[i];
0322 }
0323
0324
0325
0326 inline Int_t index(const RooAbsArg* arg) const {
0327 auto item = std::find(_list.begin(), _list.end(), arg);
0328 return item != _list.end() ? item - _list.begin() : -1;
0329 }
0330
0331
0332 inline Int_t index(const RooAbsArg& arg) const {
0333 return index(&arg);
0334 }
0335
0336 Int_t index(const char* name) const;
0337
0338 inline void Print(Option_t *options= nullptr) const override {
0339
0340 printStream(defaultPrintStream(),defaultPrintContents(options),defaultPrintStyle(options));
0341 }
0342 std::string contentsString() const ;
0343
0344
0345 void printName(std::ostream& os) const override ;
0346 void printTitle(std::ostream& os) const override ;
0347 void printClassName(std::ostream& os) const override ;
0348 void printValue(std::ostream& os) const override ;
0349 void printMultiline(std::ostream& os, Int_t contents, bool verbose=false, TString indent="") const override ;
0350
0351 Int_t defaultPrintContents(Option_t* opt) const override ;
0352
0353
0354 void printLatex(const RooCmdArg& arg1={}, const RooCmdArg& arg2={},
0355 const RooCmdArg& arg3={}, const RooCmdArg& arg4={},
0356 const RooCmdArg& arg5={}, const RooCmdArg& arg6={},
0357 const RooCmdArg& arg7={}, const RooCmdArg& arg8={}) const ;
0358 void printLatex(std::ostream& ofs, Int_t ncol, const char* option="NEYU", Int_t sigDigit=1,
0359 const RooLinkedList& siblingLists=RooLinkedList(), const RooCmdArg* formatCmd=nullptr) const ;
0360
0361 void setName(const char *name) {
0362
0363 _name= name;
0364 }
0365 const char* GetName() const override {
0366
0367 return _name.Data() ;
0368 }
0369 bool isOwning() const {
0370
0371 return _ownCont ;
0372 }
0373
0374 bool allInRange(const char* rangeSpec) const ;
0375
0376 void dump() const ;
0377
0378 void releaseOwnership() { _ownCont = false ; }
0379 void takeOwnership() { _ownCont = true ; }
0380
0381 void sort(bool reverse = false);
0382 void sortTopologically();
0383
0384 void RecursiveRemove(TObject *obj) override;
0385
0386 void useHashMapForFind(bool flag) const;
0387
0388
0389
0390 struct RooAbsArgPtrOrDouble {
0391 RooAbsArgPtrOrDouble(RooAbsArg & arg) : ptr{&arg}, hasPtr{true} {}
0392 RooAbsArgPtrOrDouble(double x) : val{x}, hasPtr{false} {}
0393
0394 RooAbsArg * ptr = nullptr;
0395 double val = 0.0;
0396 bool hasPtr = false;
0397 };
0398
0399 protected:
0400 Storage_t _list;
0401 using LegacyIterator_t = TIteratorToSTLInterface<Storage_t>;
0402
0403 bool _ownCont = false;
0404 TString _name;
0405 bool _allRRV = true;
0406
0407 void deleteList() ;
0408
0409 inline TNamed* structureTag() { if (_structureTag==nullptr) makeStructureTag() ; return _structureTag ; }
0410 inline TNamed* typedStructureTag() { if (_typedStructureTag==nullptr) makeTypedStructureTag() ; return _typedStructureTag ; }
0411
0412 mutable TNamed* _structureTag{nullptr};
0413 mutable TNamed* _typedStructureTag{nullptr};
0414
0415 inline void clearStructureTags() { _structureTag = nullptr ; _typedStructureTag = nullptr ; }
0416
0417 void makeStructureTag() {}
0418 void makeTypedStructureTag() {}
0419
0420
0421 virtual bool canBeAdded(const RooAbsArg& arg, bool silent) const = 0;
0422
0423 template<class T>
0424 static void assert_is_no_temporary(T &&) {
0425 static_assert(!std::is_rvalue_reference<T&&>::value,
0426 "A reference to a temporary RooAbsArg will be passed to a RooAbsCollection constructor! "
0427 "This is not allowed, because the collection will not own the arguments. "
0428 "Hence, the collection will contain dangling pointers when the temporary goes out of scope."
0429 );
0430 }
0431
0432 private:
0433
0434 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 34, 00)
0435
0436
0437 friend class RooWorkspace;
0438 std::unique_ptr<LegacyIterator_t> makeLegacyIterator (bool forward = true) const;
0439 #else
0440 #error "Please remove this unneeded code."
0441 #endif
0442
0443 bool replaceImpl(const RooAbsArg& var1, const RooAbsArg& var2);
0444
0445 using HashAssistedFind = RooFit::Detail::HashAssistedFind;
0446 mutable std::unique_ptr<HashAssistedFind> _hashAssistedFind;
0447 std::size_t _sizeThresholdForMapSearch = 100;
0448
0449 void insert(RooAbsArg*);
0450
0451 static void throwAddTypedException(TClass *klass, RooAbsArg *arg);
0452
0453 const RooFit::UniqueId<RooAbsCollection> _uniqueId;
0454
0455 ClassDefOverride(RooAbsCollection,3)
0456 };
0457
0458 #endif