#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:
*
* .. | ..
*
*
* 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 JPipe :
public virtual JObjectIterator
{
public:
typedef typename JObjectIterator::pointer_type pointer_type;
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
* \param selector object selector
* \param regulator regulator
*/
JPipe(JObjectIterator& input,
const JValve& valve,
const JObjectSelector& 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& in;
const JValve& valve;
const JObjectSelector& 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; and
* - JPipe.
*/
template
class JPipe< JTypeList > :
public JPipe,
public JPipe,
public virtual JObjectIterator< JTypeList >
{
public:
typedef JTypeList typelist;
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
* \param selector object selector
* \param regulator regulator
*/
JPipe(JObjectIterator& input,
const JValve& valve,
const JObjectSelector& selector,
const JRegulator& regulator) :
JPipe(input, valve, selector, regulator),
JPipe(input, valve, selector, regulator)
{}
};
/**
* Terminator class of recursive JPipe class.
*/
template
class JPipe< JTypeList > :
public JPipe
{
public:
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
* \param selector object selector
* \param regulator regulator
*/
JPipe(JObjectIterator& input,
const JValve& valve,
const JObjectSelector& selector,
const JRegulator& regulator) :
JPipe(input, valve, selector, regulator)
{}
};
/**
* Auxiliary class for object iteration via multiple pipes, e.g.\ operator:
*
* .. | .. | ..
*
*/
template
class JMultiPipe :
public JPipe
{
public:
/**
* Constructor.
*
* \param input object iterator
*/
JMultiPipe(JObjectIterator& input) :
JPipe(input, JValve::getDefault(), JObjectSelector::getDefault(), JRegulator::getDefault())
{}
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
*/
JMultiPipe(JObjectIterator& input,
const JValve& valve) :
JPipe(input, valve, JObjectSelector::getDefault(), JRegulator::getDefault())
{}
/**
* Constructor.
*
* \param input object iterator
* \param selector object selector
*/
JMultiPipe(JObjectIterator& input,
const JObjectSelector& selector) :
JPipe(input, JValve::getDefault(), selector, JRegulator::getDefault())
{}
/**
* Constructor.
*
* \param input object iterator
* \param regulator regulator
*/
JMultiPipe(JObjectIterator& input,
const JRegulator& regulator) :
JPipe(input, JValve::getDefault(), JObjectSelector::getDefault(), regulator)
{}
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
* \param selector object selector
* \param regulator regulator
*/
JMultiPipe(JObjectIterator& input,
const JValve& valve,
const JObjectSelector& selector,
const JRegulator& regulator) :
JPipe(input, valve, selector, regulator)
{}
/**
* Pipe terminator.
*
* \param left pipe
* \param right object output
*/
friend inline void operator|(JMultiPipe& left, JObjectOutput& right)
{
left >> right;
}
/**
* Recursive expansion of multi-pipe.
*
* \param left multi-pipe
* \param right object valve
* \return multi-pipe
*/
friend inline JMultiPipe& operator|(JMultiPipe& left, const JValve& right)
{
JMultiPipe::pipe.reset(new JMultiPipe(left, right));
return *JMultiPipe::pipe;
}
/**
* Recursive expansion of multi-pipe.
*
* \param left multi-pipe
* \param right object selector
* \return multi-pipe
*/
friend inline JMultiPipe& operator|(JMultiPipe& left, const JObjectSelector& right)
{
JMultiPipe::pipe.reset(new JMultiPipe(left, right));
return *JMultiPipe::pipe;
}
/**
* Recursive expansion of multi-pipe.
*
* \param left multi-pipe
* \param right regulator
* \return multi-pipe
*/
friend inline JMultiPipe& operator|(JMultiPipe& left, const JRegulator& right)
{
JMultiPipe::pipe.reset(new JMultiPipe(left, right));
return *JMultiPipe::pipe;
}
/**
* Pipe operator for multiplexing.
*
* \param left object iterator
* \param right data type
* \return object multiplexer
*/
template
friend inline JObjectMultiplexer& operator|(JMultiPipe& left, const JType& right)
{
JObjectMultiplexer::multiplexer.reset(new JObjectMultiplexer(left));
return *JObjectMultiplexer::multiplexer;
}
static JSinglePointer< JMultiPipe > pipe; //!< Declaration of common pipe
};
/**
* Definition of common pipe.
*/
template
JSinglePointer< JMultiPipe > JMultiPipe::pipe;
}
#endif