#include <libwccl/ops/functions/bool/iteration.h> #include <libwccl/ops/functions/bool/predicate.h> namespace Wccl { #ifndef _MSC_VER const int Iteration::MatchAll; #endif Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context) const { const boost::shared_ptr<const Position>& range_begin = range_begin_expr_->apply(context); const boost::shared_ptr<const Position>& range_end = range_end_expr_->apply(context); const boost::shared_ptr<Position>& iter_var = context.variables()->get_fast(iter_var_acc_); const SentenceContext& sc = context.sentence_context(); int abs_begin = sc.get_abs_position(*range_begin); int abs_end = sc.get_abs_position(*range_end); // Proceed only if range positions are not "nowhere". if (abs_begin != Position::Nowhere && abs_end != Position::Nowhere) { // Trim range to sentence boundaries if (abs_begin < 0) { abs_begin = 0; } if (abs_end >= sc.size()) { abs_end = sc.size() - 1; } int range_size = abs_begin - abs_end + 1; // Proceed only if range isn't empty if (range_size > 0) { int n = (match_count_ == MatchAll) ? range_size : match_count_; // Proceed only if the range actually has enough positions to match if (n <= range_size) { if (direction_ == Forward) { if (iterate(abs_begin, abs_end, 1, *iter_var, context)) { return Predicate::True(context); } } if (iterate(abs_end, abs_begin, -1, *iter_var, context)) { return Predicate::True(context); } } } } // In case of failure, set iteration variable to Nowhere and return False iter_var->set_value(Position::Nowhere); return Predicate::False(context); } bool Iteration::iterate(int start, int stop, int step, Position &p, const FunExecContext &context) const { //TODO: implement return false; } } /* end ns Wccl */