#ifndef __JLANG__JOBJECTSAMPLER__ #define __JLANG__JOBJECTSAMPLER__ #include "JLang/JObjectIterator.hh" #include "JLang/JPointer.hh" #include "JLang/JSampler.hh" /** * \author mdejong */ namespace JLANG {} namespace JPP { using namespace JLANG; } namespace JLANG { /** * Auxiliary class to sample objects from a JRewindableObjectIterator. * * This class can be used for iterations that are different than strict sequential. * The first template parameter corresponds to the data type of the iteration and the second to the sampler.\n * The sampling is defined by the number of objects to be skipped. * The number of objects to be skipped is returned by the function object operator * of the sampler which takes the actual object as input.\n * The default JSampler corresponds to zero elements to be skipped, * which in turn corresponds to the iteration of all objects in sequential order. * * The JObjectSampler class implements the JObjectIterator * using a reference to a JRewindableObjectIterator object so that * the sampling of objects can continue ad infinitum. * * Method JObjectSampler::hasNext normally returns true, unless * - there are no available objects; or * - given sampler rejects every object. * * Note that the internal sampler is a copy of the specified sampler and not a reference thereof. */ template class JSampler_t = JSampler> class JObjectSampler : public JObjectIterator { public: typedef typename JObjectIterator::pointer_type pointer_type; /** * Constructor. * * \param input input */ JObjectSampler(JRewindableObjectIterator& input) : in (input), has_next(false) {} /** * Constructor. * * \param input input * \param sampler sampler */ JObjectSampler(JRewindableObjectIterator& input, const JSampler_t& sampler) : in (input), has_next(false) { this->sampler = sampler; } /** * Check availability of next element. * * \return true if the iteration has more elements; else false */ virtual bool hasNext() override { while (!has_next) { if (!in.hasNext()) { in.rewind(); } if (in.hasNext()) { ps.set(in.next()); skip_type ns = sampler(*ps); if (ns == 0) { has_next = true; } else { while ((ns -= in.skip(ns)) != 0) { in.rewind(); } } } else { // nothing to sample break; } } return has_next; } /** * Get next element. * * \return pointer to element */ virtual const pointer_type& next() override { if (!has_next) { ps.reset(NULL); } has_next = false; return ps; } /** * Get sampler. * * \return sampler */ const JSampler_t& getSampler() const { return sampler; } /** * Get sampler. * * \return sampler */ JSampler_t& getSampler() { return sampler; } protected: JRewindableObjectIterator& in; JSampler_t sampler; JPointer ps; bool has_next; }; } #endif