#ifndef __JLANG__JPIPE__ #define __JLANG__JPIPE__ #include "JLang/JType.hh" #include "JLang/JTypeList.hh" #include "JLang/JNullType.hh" #include "JLang/JValve.hh" #include "JLang/JObjectSelector.hh" #include "JLang/JRegulator.hh" #include "JLang/JObjectMultiplexer.hh" #include "JLang/JSinglePointer.hh" /** * \file * * Implementation of pipe operation for object iterators. * \author mdejong */ namespace JLANG { /** * Auxiliary class for object iteration via pipe, i.e.\ operator: * <pre> * .. | .. * </pre> * * A pipe consists of an object iterator, a valve, an object selector and a common regulator.\n * The objects are first passed through a valve which can be opened and closed.\n * The object selector can be used to filter specific objects/values.\n * Finally, the regulator can be used to control the throughput. * * This class implements the JLANG::JObjectIterator interface. */ template<class T> class JPipe : public virtual JObjectIterator<T> { public: typedef typename JObjectIterator<T>::pointer_type pointer_type; /** * Constructor. * * \param input object iterator * \param valve valve * \param selector object selector * \param regulator regulator */ JPipe(JObjectIterator<T>& input, const JValve<T>& valve, const JObjectSelector<T>& selector, const JRegulator& regulator) : in (input), valve (valve), selector (selector), regulator(regulator) {} /** * Check availability of next element. * * \return true if the iteration has more elements; else false */ virtual bool hasNext() override { if (!p.is_valid()) { if (valve.is_open()) { while (in.hasNext()) { p = in.next(); if (selector.accept(*p)) { if (regulator.accept()) { return true; } } } } p = NULL; // invalid pointer for next round return false; } else { return true; } } /** * Get next element. * * \return pointer to element */ virtual const pointer_type& next() override { ps = p; p.reset(); 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 { return in.skip(ns); } protected: JObjectIterator<T>& in; const JValve<T>& valve; const JObjectSelector<T>& selector; const JRegulator& regulator; private: pointer_type ps; pointer_type p; }; /** * Implementation of object iterator for multiple data types. * * This class recursively defines the JLANG::JObjectIterator interface * for all data types by deriving from: * - JPipe<JHead_t>; and * - JPipe<JTail_t>. */ template<class JHead_t, class JTail_t> class JPipe< JTypeList<JHead_t, JTail_t> > : public JPipe<JHead_t>, public JPipe<JTail_t>, public virtual JObjectIterator< JTypeList<JHead_t, JTail_t> > { public: typedef JTypeList<JHead_t, JTail_t> typelist; /** * Constructor. * * \param input object iterator * \param valve valve * \param selector object selector * \param regulator regulator */ JPipe(JObjectIterator<typelist>& input, const JValve<typelist>& valve, const JObjectSelector<typelist>& selector, const JRegulator& regulator) : JPipe<JHead_t>(input, valve, selector, regulator), JPipe<JTail_t>(input, valve, selector, regulator) {} }; /** * Terminator class of recursive JPipe class. */ template<class JHead_t> class JPipe< JTypeList<JHead_t, JNullType> > : public JPipe<JHead_t> { public: /** * Constructor. * * \param input object iterator * \param valve valve * \param selector object selector * \param regulator regulator */ JPipe(JObjectIterator<JHead_t>& input, const JValve<JHead_t>& valve, const JObjectSelector<JHead_t>& selector, const JRegulator& regulator) : JPipe<JHead_t>(input, valve, selector, regulator) {} }; /** * Auxiliary class for object iteration via multiple pipes, e.g.\ operator: * <pre> * .. | .. | .. * </pre> */ template<class T, int N> class JMultiPipe : public JPipe<T> { public: /** * Constructor. * * \param input object iterator */ JMultiPipe(JObjectIterator<T>& input) : JPipe<T>(input, JValve<T>::getDefault(), JObjectSelector<T>::getDefault(), JRegulator::getDefault()) {} /** * Constructor. * * \param input object iterator * \param valve valve */ JMultiPipe(JObjectIterator<T>& input, const JValve<T>& valve) : JPipe<T>(input, valve, JObjectSelector<T>::getDefault(), JRegulator::getDefault()) {} /** * Constructor. * * \param input object iterator * \param selector object selector */ JMultiPipe(JObjectIterator<T>& input, const JObjectSelector<T>& selector) : JPipe<T>(input, JValve<T>::getDefault(), selector, JRegulator::getDefault()) {} /** * Constructor. * * \param input object iterator * \param regulator regulator */ JMultiPipe(JObjectIterator<T>& input, const JRegulator& regulator) : JPipe<T>(input, JValve<T>::getDefault(), JObjectSelector<T>::getDefault(), regulator) {} /** * Constructor. * * \param input object iterator * \param valve valve * \param selector object selector * \param regulator regulator */ JMultiPipe(JObjectIterator<T>& input, const JValve<T>& valve, const JObjectSelector<T>& selector, const JRegulator& regulator) : JPipe<T>(input, valve, selector, regulator) {} /** * Pipe terminator. * * \param left pipe * \param right object output */ friend inline void operator|(JMultiPipe& left, JObjectOutput<T>& right) { left >> right; } /** * Recursive expansion of multi-pipe. * * \param left multi-pipe * \param right object valve * \return multi-pipe */ friend inline JMultiPipe<T, N+1>& operator|(JMultiPipe& left, const JValve<T>& right) { JMultiPipe<T, N+1>::pipe.reset(new JMultiPipe<T, N+1>(left, right)); return *JMultiPipe<T, N+1>::pipe; } /** * Recursive expansion of multi-pipe. * * \param left multi-pipe * \param right object selector * \return multi-pipe */ friend inline JMultiPipe<T, N+1>& operator|(JMultiPipe& left, const JObjectSelector<T>& right) { JMultiPipe<T, N+1>::pipe.reset(new JMultiPipe<T, N+1>(left, right)); return *JMultiPipe<T, N+1>::pipe; } /** * Recursive expansion of multi-pipe. * * \param left multi-pipe * \param right regulator * \return multi-pipe */ friend inline JMultiPipe<T, N+1>& operator|(JMultiPipe& left, const JRegulator& right) { JMultiPipe<T, N+1>::pipe.reset(new JMultiPipe<T, N+1>(left, right)); return *JMultiPipe<T, N+1>::pipe; } /** * Pipe operator for multiplexing. * * \param left object iterator * \param right data type * \return object multiplexer */ template<class JBase_t> friend inline JObjectMultiplexer<T, JBase_t>& operator|(JMultiPipe& left, const JType<JBase_t>& right) { JObjectMultiplexer<T, JBase_t>::multiplexer.reset(new JObjectMultiplexer<T, JBase_t>(left)); return *JObjectMultiplexer<T, JBase_t>::multiplexer; } static JSinglePointer< JMultiPipe<T, N> > pipe; //!< Declaration of common pipe }; /** * Definition of common pipe. */ template<class T, int N> JSinglePointer< JMultiPipe<T, N> > JMultiPipe<T, N>::pipe; } #endif