#ifndef __JLANG__JOBJECTMULTIPLEXER__
#define __JLANG__JOBJECTMULTIPLEXER__
#include "JLang/JObjectIterator.hh"
#include "JLang/JObjectOutput.hh"
#include "JLang/JValve.hh"
#include "JLang/JTypeList.hh"
#include "JLang/JNullType.hh"
#include "JLang/JBaseClass.hh"
#include "JLang/JSinglePointer.hh"
/**
* \author mdejong
*/
namespace JLANG {}
namespace JPP { using namespace JLANG; }
namespace JLANG {
/**
* Auxiliary class for multiplexing object iterators.
*
* The template argument JDerived_t refers to a list of
* multiple object iterators which are sequentially processed.\n
* The template argument JBase_t refers to a single object iterator
* which provides for a common interface to the multiple object iterators.
*
* This class implements the JLANG::JObjectIterator interface.
*/
template::data_type>
class JObjectMultiplexer :
public virtual JObjectIterator
{
public:
typedef JObjectIterator iterator_type;
typedef typename JObjectIterator::pointer_type pointer_type;
typedef JSinglePointer< JObjectMultiplexer > multiplexer_type;
typedef JValve valve_type;
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
*/
JObjectMultiplexer(iterator_type& input,
const valve_type& valve = valve_type()) :
valve(valve),
in(input)
{}
/**
* Check availability of next element.
*
* \return true if the valve is open and the iteration has more elements; else false
*/
virtual bool hasNext() override
{
if (valve.is_open())
return in.hasNext();
else
return false;
}
/**
* Get next element.
*
* \return pointer to element
*/
virtual const pointer_type& next() override
{
ps.reset(in.next());
return ps;
}
/**
* Pipe operator.
*
* \param in object multiplexer
* \param out object output
*/
friend inline void operator|(JObjectMultiplexer& in, JObjectOutput& out)
{
in >> out;
}
valve_type valve;
static multiplexer_type multiplexer;
private:
iterator_type& in;
pointer_type ps;
};
/**
* Multiplexer.
*/
template
JSinglePointer< JObjectMultiplexer >
JObjectMultiplexer::multiplexer;
/**
* Template specialisation of JObjectMultiplexer for multiple object iterators.
* Implementation of object multiplexing for multiple data types.
*
* This class recursively extends the JLANG::JObjectMultiplexer class
* for all data types by deriving from:
* - JObjectMultiplexer; and
* - JObjectMultiplexer.
*
* This class implements the JLANG::JObjectIterator interface.
*/
template
class JObjectMultiplexer, JBase_t> :
public JObjectMultiplexer,
public JObjectMultiplexer,
public virtual JObjectIterator
{
public:
typedef JTypeList typelist;
typedef JObjectIterator iterator_type;
typedef typename JObjectIterator::pointer_type pointer_type;
typedef JSinglePointer< JObjectMultiplexer > multiplexer_type;
typedef JValve valve_type;
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
*/
JObjectMultiplexer(iterator_type& input,
const valve_type& valve = valve_type()) :
JObjectMultiplexer(input, valve),
JObjectMultiplexer(input, valve)
{}
/**
* Check availability of next element.
*
* \return true if the iteration has more elements; else false
*/
virtual bool hasNext() override
{
return (JObjectMultiplexer::hasNext() ||
JObjectMultiplexer::hasNext());
}
/**
* Get next element.
*
* \return pointer to element
*/
virtual const pointer_type& next() override
{
if (JObjectMultiplexer::hasNext())
ps.reset(JObjectMultiplexer::next());
else
ps.reset(JObjectMultiplexer::next());
return ps;
}
/**
* Pipe operator.
*
* \param in object multiplexer
* \param out object output
*/
friend inline void operator|(JObjectMultiplexer& in, JObjectOutput& out)
{
in >> out;
}
static multiplexer_type multiplexer;
private:
pointer_type ps;
};
/**
* Multiplexer.
*/
template
JSinglePointer< JObjectMultiplexer, JBase_t> >
JObjectMultiplexer, JBase_t>::multiplexer;
/**
* Terminator class of recursive JObjectMultiplexer class.
*/
template
class JObjectMultiplexer, JBase_t> :
public JObjectMultiplexer
{
public:
typedef JObjectIterator iterator_type;
typedef typename JObjectIterator::pointer_type pointer_type;
typedef JSinglePointer< JObjectMultiplexer > multiplexer_type;
typedef JValve valve_type;
/**
* Constructor.
*
* \param input object iterator
* \param valve valve
*/
JObjectMultiplexer(iterator_type& input,
const valve_type& valve = valve_type()) :
JObjectMultiplexer(input, valve)
{}
};
}
#endif