From 81e857817a040c6afd2d9be2b02b07be8d1886fa Mon Sep 17 00:00:00 2001 From: Adam Wardynski <award@.(B-4.4.46a)> Date: Fri, 10 Dec 2010 17:29:19 +0100 Subject: [PATCH] Factor out code that gets absolute range with validity check. --- libwccl/ops/functions/bool/iteration.cpp | 26 +++------ .../bool/predicates/strongagreement.cpp | 15 +---- .../bool/predicates/weakagreement.cpp | 15 +---- libwccl/ops/functions/tset/agrfilter.cpp | 15 +---- .../ops/functions/tset/getsymbolsinrange.cpp | 18 ++---- libwccl/sentencecontext.h | 56 +++++++++++++++++++ 6 files changed, 74 insertions(+), 71 deletions(-) diff --git a/libwccl/ops/functions/bool/iteration.cpp b/libwccl/ops/functions/bool/iteration.cpp index e9be9e8..c91fc17 100644 --- a/libwccl/ops/functions/bool/iteration.cpp +++ b/libwccl/ops/functions/bool/iteration.cpp @@ -34,25 +34,13 @@ Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context if (range_left->get_value() != Position::Nowhere) { const boost::shared_ptr<const Position>& range_right = right_pos_expr_->apply(context); - if (range_right->get_value() != Position::Nowhere) { - // Get absolute values for left and right extremes of the range. - int right = sc.get_abs_position(*range_right); - int left = sc.get_abs_position(*range_left); - // Trim range to sentence boundaries - if (left < 0) { - left = 0; - } - if (right >= sc.size()) { - right = sc.size() - 1; - } - // Proceed only if range isn't empty - if (left <= right) { - // Change range from absolute to relative and iterate - left -= sc.get_position(); - right -= sc.get_position(); - if (iterate(left, right, *iter_var, context)) { - return Predicate::True(context); - } + int left, right; + if (sc.validate_range(*range_left, *range_right, left, right)) { + // Change range from absolute to relative and iterate + left -= sc.get_position(); + right -= sc.get_position(); + if (iterate(left, right, *iter_var, context)) { + return Predicate::True(context); } } } diff --git a/libwccl/ops/functions/bool/predicates/strongagreement.cpp b/libwccl/ops/functions/bool/predicates/strongagreement.cpp index 8678cf4..908def3 100644 --- a/libwccl/ops/functions/bool/predicates/strongagreement.cpp +++ b/libwccl/ops/functions/bool/predicates/strongagreement.cpp @@ -33,21 +33,10 @@ StrongAgreement::BaseRetValPtr StrongAgreement::apply_internal(const FunExecCont if (range_right->get_value() == Position::Nowhere) { return Predicate::False(context); } - // Get absolute values for left and right extremes of the range. - int abs_left = sc.get_abs_position(*range_left); - int abs_right = sc.get_abs_position(*range_right); - // Trim range to sentence boundaries - if (abs_left < 0) { - abs_left = 0; - } - if (abs_right >= sc.size()) { - abs_right = sc.size() - 1; - } - // Proceed only if range isn't empty (range outside of sentence or empty sentence are covered) - if (abs_left > abs_right) { + int abs_left, abs_right; + if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) { return Predicate::False(context); } - const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context); int min_card = attribs->categories_count(tagset_); diff --git a/libwccl/ops/functions/bool/predicates/weakagreement.cpp b/libwccl/ops/functions/bool/predicates/weakagreement.cpp index 2282812..b7f4b66 100644 --- a/libwccl/ops/functions/bool/predicates/weakagreement.cpp +++ b/libwccl/ops/functions/bool/predicates/weakagreement.cpp @@ -33,21 +33,10 @@ WeakAgreement::BaseRetValPtr WeakAgreement::apply_internal(const FunExecContext& if (range_right->get_value() == Position::Nowhere) { return Predicate::False(context); } - // Get absolute values for left and right extremes of the range. - int abs_left = sc.get_abs_position(*range_left); - int abs_right = sc.get_abs_position(*range_right); - // Trim range to sentence boundaries - if (abs_left < 0) { - abs_left = 0; - } - if (abs_right >= sc.size()) { - abs_right = sc.size() - 1; - } - // Proceed only if range isn't empty (range outside of sentence or empty sentence are covered) - if (abs_left > abs_right) { + int abs_left, abs_right; + if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) { return Predicate::False(context); } - const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context); int min_card = attribs->categories_count(tagset_); diff --git a/libwccl/ops/functions/tset/agrfilter.cpp b/libwccl/ops/functions/tset/agrfilter.cpp index 21b6661..ef56fa5 100644 --- a/libwccl/ops/functions/tset/agrfilter.cpp +++ b/libwccl/ops/functions/tset/agrfilter.cpp @@ -35,21 +35,10 @@ AgrFilter::BaseRetValPtr AgrFilter::apply_internal(const FunExecContext& context if (range_right->get_value() == Position::Nowhere) { return detail::DefaultFunction<TSet>()->apply(context); } - // Get absolute values for left and right extremes of the range. - int abs_left = sc.get_abs_position(*range_left); - int abs_right = sc.get_abs_position(*range_right); - // Trim range to sentence boundaries - if (abs_left < 0) { - abs_left = 0; - } - if (abs_right >= sc.size()) { - abs_right = sc.size() - 1; - } - // Proceed only if range isn't empty (range outside of sentence or empty sentence are covered) - if (abs_left > abs_right) { + int abs_left, abs_right; + if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) { return detail::DefaultFunction<TSet>()->apply(context); } - const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context); const boost::shared_ptr<const TSet>& mask = mask_expr_->apply(context); diff --git a/libwccl/ops/functions/tset/getsymbolsinrange.cpp b/libwccl/ops/functions/tset/getsymbolsinrange.cpp index 13cfce9..2897b69 100644 --- a/libwccl/ops/functions/tset/getsymbolsinrange.cpp +++ b/libwccl/ops/functions/tset/getsymbolsinrange.cpp @@ -26,22 +26,14 @@ std::ostream& GetSymbolsInRange::write_to(std::ostream& os) const GetSymbolsInRange::BaseRetValPtr GetSymbolsInRange::apply_internal(const FunExecContext& context) const { const boost::shared_ptr<const Position>& range_begin = rbegin_expr_->apply(context); - const boost::shared_ptr<const Position>& range_end = rend_expr_->apply(context); const SentenceContext& sc = context.sentence_context(); - int abs_begin = sc.get_abs_position(*range_begin); - int abs_end = sc.get_abs_position(*range_end); - // Trim range to sentence boundaries - if ((abs_begin != Position::Nowhere) && (abs_begin < 0)) { - abs_begin = 0; - } - if ((abs_end != Position::Nowhere) && (abs_end >= sc.size())) { - abs_end = sc.size() - 1; + if (range_begin->get_value() == Position::Nowhere ) { + return detail::DefaultFunction<TSet>()->apply(context); } - // If range is empty, return an empty set - note the below also - // covers ranges without overlap with actual sentence range - // (including an empty sentence). - if((abs_begin == Position::Nowhere) || (abs_end == Position::Nowhere) || (abs_begin > abs_end)) { + const boost::shared_ptr<const Position>& range_end = rend_expr_->apply(context); + int abs_begin, abs_end; + if (!sc.validate_range(*range_begin, *range_end, abs_begin, abs_end)) { return detail::DefaultFunction<TSet>()->apply(context); } diff --git a/libwccl/sentencecontext.h b/libwccl/sentencecontext.h index 1fecb3f..0f61c0f 100644 --- a/libwccl/sentencecontext.h +++ b/libwccl/sentencecontext.h @@ -72,6 +72,26 @@ public: return !is_inside(get_abs_position(pos)); } + /** + * Checks if range is valid, i.e. non-empty and not outside of sentence, + * and at the same time finds absolute values of passed Positions + * @param left Position specyfing left extreme of the range + * @param right Position specyfing right extreme of the range + * @param abs_left reference to int value that will hold absolute + * value for left position + * @param abs_right reference to int value that will hold absolute + * value for right position + * @returns true if range is valid; in this case abs_left and abs_right + * are set to absolute positions values for left and right Position. + * False is returned otherwise; in this case abs_left and abs_right + * are set to Nowhere + */ + bool validate_range( + const Position& left, + const Position& right, + int& abs_left, + int& abs_right) const; + /// Position setter void set_position(int new_position) { position_ = new_position; @@ -152,6 +172,42 @@ private: int position_; }; + +inline +bool SentenceContext::validate_range( + const Position& left, + const Position& right, + int& abs_left, + int& abs_right) const +{ + abs_left = get_abs_position(left); + + if (abs_left == Position::Nowhere) { + abs_right = Position::Nowhere; + return false; + } + abs_right = get_abs_position(right); + if (abs_right == Position::Nowhere) { + abs_left = Position::Nowhere; + return false; + } + // Trim range to sentence boundaries + if (abs_left < 0) { + abs_left = 0; + } + if (abs_right >= size()) { + abs_right = size() - 1; + } + // is range valid? this covers "crossed" range, an empty sentence, + // and range outside boundaries of sentence + if (abs_left > abs_right) { + abs_left = Position::Nowhere; + abs_right = Position::Nowhere; + return false; + } + return true; +} + // TODO ConstSentenceContext ? } /* end ns Wccl */ -- GitLab