#ifndef __JSUPPORT__JTREESCANNERINTERFACE__ #define __JSUPPORT__JTREESCANNERINTERFACE__ #include "JLang/JObjectIterator.hh" #include "JLang/JNullType.hh" #include "JLang/JEquals.hh" #include "JLang/JBidirectionalIterator.hh" #include "JSupport/JMultipleFileScanner.hh" #include "JSupport/JLimit.hh" /** * \author mdejong */ namespace JSUPPORT {} namespace JPP { using namespace JSUPPORT; } namespace JSUPPORT { using JLANG::JEquals; using JLANG::JBidirectionalIterator; using JLANG::JRewindableObjectIterator; using JLANG::JNullType; /** * Auxiliary interface for direct access of elements in ROOT TChain. * * The optional second template argument is used to the determine the value of an element * which defines the apparent order the elements in the TChain. */ template struct JTreeScannerInterface; /** * Specialiation of interface JTreeScannerInterface for unordered direct access of elements in ROOT TChain. * * This interface provives for STD compatible iterators.\n * Note that a pointer to the parent JTreeScannerInterface is used for the iteration. * The user should therefore make separate copies of the read data when data are modified or multiple iterators are simultaneously used. * * This interface extends the JLANG::JRewindableObjectIterator interface and the JSUPPORT::JLimit class. */ template struct JTreeScannerInterface : public JRewindableObjectIterator, public JLimit { private: /** * Base class for STD compatible iterator. */ template struct basic_iterator : public JEquals, public JBidirectionalIterator { /** * Equality of iterator. * * \param cursor iterator * \return true if equal; else false */ virtual bool equals(const T& cursor) const { return index == cursor.index; } /** * Increment iterator. * * \return true if valid; else false */ virtual bool increment() override { return ++index < pTreeScanner->getEntries(); } /** * Decrement iterator. * * \return true if valid; else false */ virtual bool decrement() override { return --index >= 0; } /** * Increment iterator. * * \param offset offset * \return true if incremented; else false */ virtual bool increment(const size_t offset) override { return (index += offset) < pTreeScanner->getEntries(); } /** * Decrement iterator. * * \param offset offset * \return true if decremented; else false */ virtual bool decrement(const size_t offset) override { return (index -= offset) >= 0; } /** * Get index. * * \return index */ counter_type get() const { return index; } protected: /** * Default constructor. */ basic_iterator() : pTreeScanner(NULL), index(-1) {} /** * Constructor. * * \param p pointer to tree scanner interface * \param i start index */ basic_iterator(JTreeScannerInterface* p, const counter_type i) : pTreeScanner(p), index(i) {} JTreeScannerInterface* pTreeScanner; counter_type index; }; public: typedef JClass_t data_type; typedef typename JRewindableObjectIterator::pointer_type pointer_type; /** * Configure. * * \param file_list file list * \param limit limit */ virtual void configure(const JMultipleFileScanner_t& file_list, const JLimit& limit) = 0; /** * Configure. * * \param file_list file list */ void configure(const JMultipleFileScanner_t& file_list) { this->configure(file_list, JLimit()); } /** * Get number of entries. * * \return number of entries */ virtual Long64_t getEntries() const = 0; /** * Get entry at given index. * * \param index index * \return pointer to object (may be NULL) */ virtual JClass_t* getEntry(Long64_t index) = 0; /** * Get internal counter. * * \return counter */ virtual counter_type getCounter() const = 0; /** * Get actual class name. * * \return class name */ virtual const char* getClassName() const { return JClass_t::Class_Name(); } /** * STD compatible iterator. */ struct iterator : public basic_iterator { typedef counter_type difference_type; friend class JTreeScannerInterface; /** * Default constructor. */ iterator() {} /** * Smart pointer operator. * * \return pointer to object */ const data_type* operator->() { return this->pTreeScanner->getEntry(this->index); } /** * Dereference operator. * * \return reference to object */ const data_type& operator*() { return *(this->pTreeScanner->getEntry(this->index)); } /** * Get distance between two iterators. * * \param first first iterator * \param second second iterator * \return distance */ friend inline difference_type distance(const iterator& first, const iterator& second) { return second.index - first.index; } private: /** * Constructor. * * \param p pointer to tree scanner interface * \param i start index */ iterator(JTreeScannerInterface* p, const counter_type i) : basic_iterator(p, i) {} }; /** * STD compatible reverse iterator. */ struct reverse_iterator : public basic_iterator { typedef counter_type difference_type; friend class JTreeScannerInterface; /** * Default constructor. */ reverse_iterator() {} /** * Smart pointer operator. * * \return pointer to object */ const data_type* operator->() { return (this->pTreeScanner->getEntry(this->pTreeScanner->getEntries() - this->index - 1)); } /** * Dereference operator. * * \return reference to object */ const data_type& operator*() { return *(this->pTreeScanner->getEntry(this->pTreeScanner->getEntries() - this->index - 1)); } /** * Get distance between two iterators. * * \param first first iterator * \param second second iterator * \return distance */ friend inline difference_type distance(const reverse_iterator& first, const reverse_iterator& second) { return second.index - first.index; } private: /** * Constructor. * * \param p pointer to tree scanner interface * \param i start index */ reverse_iterator(JTreeScannerInterface* p, const counter_type i) : basic_iterator(p, i) {} }; /** * Check emptyness. * * \return true if empty; else false */ bool empty() const { return getEntries() == 0; } /** * Get iterator to begin of data. * * \return iterator */ iterator begin() { return iterator(this, this->getLowerLimit()); } /** * Get iterator to end of data. * * \return iterator */ iterator end() { return iterator(this, this->getUpperLimit() < this->getEntries() ? this->getUpperLimit() : this->getEntries()); } /** * Get reverse iterator to begin of data. * * \return reverse iterator */ reverse_iterator rbegin() { return reverse_iterator(this, this->getLowerLimit()); } /** * Get reverse iterator to end of data. * * \return reverse iterator */ reverse_iterator rend() { return reverse_iterator(this, this->getUpperLimit() < this->getEntries() ? this->getUpperLimit() : this->getEntries()); } }; /** * Specialiation of interface JTreeScannerInterface for ordered direct access of elements in ROOT TChain. * * This interface extends the JTreeScannerInterface interface * with the additional interface method to find a corresponding entry in the ROOT TChain. */ template struct JTreeScannerInterface : public virtual JTreeScannerInterface { /** * Constructor. * * \param evaluator evaluator */ JTreeScannerInterface(const JEvaluator_t& evaluator = JEvaluator_t()) : getValue(evaluator) {} /** * Find index of element that is closest in value to given value. * * \param value value * \return index (-1 in case of error) */ virtual Long64_t find(const double value) const = 0; /** * Find index of element that is closest in value to given object. * * \param object object * \return index (-1 in case of error) */ template Long64_t find(const T& object) const { return this->find(getValue(object)); } /** * Get evaluator. * * \return evaluator */ const JEvaluator_t& getEvaluator() const { return getValue; } protected: JEvaluator_t getValue; }; } #endif