#include <libwccl/values/matchvector.h> #include <libwccl/values/match.h> #include <libpwrutils/foreach.h> #include <sstream> #include <libwccl/exception.h> namespace Wccl { std::string MatchVector::to_raw_string() const { std::stringstream ss; ss << "MATCH("; bool comma = false; foreach (const boost::shared_ptr<Match>& m, matches_) { if (comma) { ss << ","; } ss << m->to_raw_string(); comma = true; } ss << ")"; return ss.str(); } int MatchVector::first_token(const boost::shared_ptr<Corpus2::AnnotatedSentence>& s) const { if (matches_.empty()) { return Position::Nowhere; } else { // Negative positions are invalid, including specials like Nowhere, // so we can't just find minimum value but minimum *non-negative* value. // Note: yes, the code assumes the special values like Nowhere are indeed negative. int p = matches_.front()->first_token(s); size_t i = 1; while ((p < 0) && (i < matches_.size())) { p = matches_[i]->first_token(s); ++i; } while (i < matches_.size()) { int c = matches_[i]->first_token(s); if ((c >= 0) && (c < p)) { p = c; } ++i; } return p >= 0 ? p : Position::Nowhere; } } int MatchVector::last_token(const boost::shared_ptr<Corpus2::AnnotatedSentence>& s) const { if (matches_.empty()) { return Position::Nowhere; } else { int p = matches_.front()->last_token(s); for (size_t i = 1; i < matches_.size(); ++i) { int c = matches_[i]->last_token(s); if (c > p) { p = c; } } return p >= 0 ? p : Position::Nowhere; } } bool MatchVector::empty() const { foreach (const boost::shared_ptr<Match>& m, matches_) { if (!m->empty()) { return false; } } return true; } void MatchVector::append(const boost::shared_ptr<Match> &m) { matches_.push_back(m); } void MatchVector::append(const boost::shared_ptr<MatchVector> &m) { matches_.push_back(boost::shared_ptr<Match>(new Match(m))); } void MatchVector::append(const boost::shared_ptr<TokenMatch> &m) { matches_.push_back(boost::shared_ptr<Match>(new Match(m))); } void MatchVector::append(const boost::shared_ptr<AnnotationMatch> &m) { matches_.push_back(boost::shared_ptr<Match>(new Match(m))); } void MatchVector::append(const boost::shared_ptr<MatchData> &m) { matches_.push_back(boost::shared_ptr<Match>(new Match(m))); } const boost::shared_ptr<const Match> MatchVector::submatch(size_t idx) const { if ((idx < matches_.size() + 1) || (idx == 0)) { return matches_[idx - 1]; } else { throw Wccl::WcclError("Match vector index out of range."); } } const boost::shared_ptr<Match>& MatchVector::submatch(size_t idx) { if ((idx < matches_.size() + 1) || (idx == 0)) { return matches_[idx - 1]; } else { throw Wccl::WcclError("Match vector index out of range."); } } } /* end ns Wccl */