#ifndef __JSUPPORT__JPARALLELFILESCANNER__ #define __JSUPPORT__JPARALLELFILESCANNER__ #include "JLang/JTypeList.hh" #include "JLang/JNullType.hh" #include "JLang/JMultiPointer.hh" #include "JLang/JException.hh" #include "JSupport/JSingleFileScanner.hh" #include "JSupport/JMultipleFileScanner.hh" /** * \file * Parallel scanning of objects from a single file or multiple files according a format that follows from the file name extension. * \author mdejong */ namespace JSUPPORT {} namespace JPP { using namespace JSUPPORT; } namespace JSUPPORT { using JLANG::JTypeList; using JLANG::JNullType; using JLANG::JMultiPointer; using JLANG::JException; /** * General purpose class for parallel reading of objects from a single file or multiple files. */ template class JFileScanner_t = JSingleFileScanner> class JParallelFileScanner : public JFileScanner_t { public: typedef typename JFileScanner_t::input_type input_type; typedef JMultiPointer multi_pointer_type; /** * Default constructor. */ JParallelFileScanner() {} /** * Constructor. * * \param input input */ JParallelFileScanner(const input_type& input) { this->configure(input, JLimit()); } /** * Constructor. * * \param input input * \param limit limit */ JParallelFileScanner(const input_type& input, const JLimit& limit) { this->configure(input, limit); } /** * Get next element. * * \return multi-pointer to element */ virtual const multi_pointer_type& next() override { ps.set(JFileScanner_t::next()); return ps; } private: multi_pointer_type ps; }; /** * Template specialisation of JParallelFileScanner for multiple data types. */ template class JFileScanner_t> class JParallelFileScanner, JFileScanner_t> : public JParallelFileScanner, public JParallelFileScanner { public: typedef typename JFileScanner_t::input_type input_type; typedef JMultiPointer< JTypeList > multi_pointer_type; using JParallelFileScanner::getFilename; using JParallelFileScanner::getCounter; /** * Default constructor. */ JParallelFileScanner() {} /** * Constructor. * * \param input input */ JParallelFileScanner(const input_type& input) { this->configure(input, JLimit()); } /** * Constructor. * * \param input input * \param limit limit */ JParallelFileScanner(const input_type& input, const JLimit& limit) { this->configure(input, limit); } /** * Rewind.\n * This method rewinds the JParallelFileScanner for each data type. */ virtual void rewind() override { JParallelFileScanner::rewind(); JParallelFileScanner::rewind(); } /** * Check availability of next element.\n * Note that the availability of the next element is tested for each data type. * * \return true if each iteration has more elements; else false */ virtual bool hasNext() override { return (JParallelFileScanner::hasNext() && JParallelFileScanner::hasNext()); } /** * Get next element. * * \return multi-pointer to elements */ virtual const multi_pointer_type& next() override { ps.reset(JParallelFileScanner::next(), JParallelFileScanner::next()); return ps; } /** * Skip items. * * \param ns number of items to skip * \return number of items skipped */ virtual skip_type skip(const skip_type ns) override { const skip_type n1 = JParallelFileScanner::skip(ns); const skip_type n2 = JParallelFileScanner::skip(ns); if (n1 == n2) return n1; else THROW(JException, "JParallelFileScanner<>::skip(): inconsistency."); } private: multi_pointer_type ps; }; /** * Terminator class of recursive JParallelFileScanner class. */ template class JFileScanner_t> class JParallelFileScanner, JFileScanner_t> : public JParallelFileScanner { public: typedef typename JParallelFileScanner::input_type input_type; typedef typename JParallelFileScanner::multi_pointer_type multi_pointer_type; /** * Default constructor. */ JParallelFileScanner() : JParallelFileScanner() {} /** * Constructor. * * \param input input */ JParallelFileScanner(const input_type& input) { this->configure(input, JLimit()); } /** * Constructor. * * \param input input * \param limit limit */ JParallelFileScanner(const input_type& input, const JLimit& limit) { this->configure(input, limit); } }; } #endif