From aa35399f3167eb6d7fee002f8832465f145e6569 Mon Sep 17 00:00:00 2001
From: Adam Wardynski <award@.(win7-laptop)>
Date: Tue, 19 Apr 2011 09:27:54 +0200
Subject: [PATCH] "empty" op/predicate for Match and TSet/StrSet too.

---
 .../ops/functions/bool/predicates/isempty.h   |  81 +++++++++++
 tests/CMakeLists.txt                          |   4 +
 tests/isempty.cpp                             | 126 ++++++++++++++++++
 3 files changed, 211 insertions(+)
 create mode 100644 libwccl/ops/functions/bool/predicates/isempty.h
 create mode 100644 tests/isempty.cpp

diff --git a/libwccl/ops/functions/bool/predicates/isempty.h b/libwccl/ops/functions/bool/predicates/isempty.h
new file mode 100644
index 0000000..eedf061
--- /dev/null
+++ b/libwccl/ops/functions/bool/predicates/isempty.h
@@ -0,0 +1,81 @@
+#ifndef LIBWCCL_OPS_FUNCTIONS_BOOL_PREDICATES_ISEMPTY_H
+#define LIBWCCL_OPS_FUNCTIONS_BOOL_PREDICATES_ISEMPTY_H
+
+#include <libwccl/ops/functions/bool/predicate.h>
+#include <libwccl/ops/formatters.h>
+
+namespace Wccl {
+
+class StrSet;
+class TSet;
+class Match;
+
+/**
+ * Predicate that checks for emptiness of a Value type (works
+ * for Match, TSet, StrSet).
+ */
+template <class T>
+class IsEmpty : public Predicate
+{
+	BOOST_MPL_ASSERT(( boost::mpl::count<boost::mpl::list<StrSet, TSet, Match>, T> ));
+public:
+	typedef boost::shared_ptr<Function<T> > ArgFunctionPtr;
+
+	IsEmpty(const ArgFunctionPtr& arg_expr)
+		: arg_expr_(arg_expr)
+	{
+		BOOST_ASSERT(arg_expr_);
+	}
+
+	/**
+	 * @returns String representation of the function
+	 */
+	std::string to_string(const Corpus2::Tagset& tagset) const;
+
+	/**
+	 * @returns Name of the function
+	 */
+	std::string raw_name() const {
+		return "empty";
+	}
+
+protected:
+	const ArgFunctionPtr arg_expr_;
+
+	/**
+	 * Take value of argument and return True if it is empty, False otherwise.
+	 */
+	BaseRetValPtr apply_internal(const FunExecContext& context) const;
+
+	/**
+	 * Writes raw string representation of the function
+	 * @note This version does not require tagset but may be incomplete
+	 * and/or contain internal info.
+	 * @returns Stream written to.
+	 */
+	std::ostream& write_to(std::ostream& ostream) const;
+};
+
+
+//
+// ----- Implementation -----
+//
+
+template <class T>
+FunctionBase::BaseRetValPtr IsEmpty<T>::apply_internal(const FunExecContext& context) const {	
+	return Predicate::evaluate(this->arg_expr_->apply(context)->empty(), context);
+}
+
+template <class T>
+std::string IsEmpty<T>::to_string(const Corpus2::Tagset &tagset) const {
+	return UnaryFunctionFormatter::to_string(tagset, *this, *arg_expr_);
+}
+
+template <class T>
+std::ostream& IsEmpty<T>::write_to(std::ostream &os) const {
+	return os << this->raw_name() << "(" << *this->arg_expr_ << ")";
+}
+
+} /* end ns Wccl */
+
+#endif // LIBWCCL_OPS_FUNCTIONS_BOOL_PREDICATES_ISEMPTY_H
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 4cd9787..d975c0c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -11,6 +11,9 @@ find_package(ANTLR REQUIRED QUIET)
 include_directories(${ANTLR_INCLUDE_DIR})
 set(LIBS ${LIBS} ${ANTLR_LIBRARY})
 
+find_package(Loki REQUIRED QUIET)
+set(LIBS ${LIBS} loki)
+
 include_directories( ${CMAKE_SOURCE_DIR} )
 
 add_definitions(-DLIBWCCL_TEST_DATA_DIR="${PROJECT_SOURCE_DIR}/")
@@ -25,6 +28,7 @@ add_executable(tests
 	getsymbols.cpp
 	getsymbolsinrange.cpp
 	getorth.cpp
+	isempty.cpp
 	logicalpredicates.cpp
 	main.cpp
 	mark.cpp
diff --git a/tests/isempty.cpp b/tests/isempty.cpp
new file mode 100644
index 0000000..11fcee8
--- /dev/null
+++ b/tests/isempty.cpp
@@ -0,0 +1,126 @@
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <libcorpus2/sentence.h>
+
+#include <libwccl/ops/functions/bool/predicates/isempty.h>
+#include <libwccl/sentencecontext.h>
+#include <libwccl/values/match.h>
+#include <libwccl/values/strset.h>
+#include <libwccl/values/tset.h>
+
+using namespace Wccl;
+
+BOOST_AUTO_TEST_SUITE(isstuffempty)
+
+struct IsEmptyFix
+{
+	IsEmptyFix()
+		: sc(boost::make_shared<Corpus2::AnnotatedSentence>()),
+		  tagset(),
+		  cx(sc, boost::make_shared<Variables>())
+	{
+	}
+	SentenceContext sc;
+	Corpus2::Tagset tagset;
+	FunExecContext cx;
+};
+
+BOOST_FIXTURE_TEST_CASE(empty_strset, IsEmptyFix)
+{
+	StrSet empty_set;
+	boost::shared_ptr<Function<StrSet> > empty_set_expr(new Constant<StrSet>(empty_set));
+	IsEmpty<StrSet> e(empty_set_expr);
+	BOOST_CHECK(e.apply(cx)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(full_strset, IsEmptyFix)
+{
+	StrSet full_set;
+	full_set.insert("word");
+	boost::shared_ptr<Function<StrSet> > full_set_expr(new Constant<StrSet>(full_set));
+	IsEmpty<StrSet> e(full_set_expr);
+	BOOST_CHECK(!e.apply(cx)->get_value());
+}
+
+
+BOOST_FIXTURE_TEST_CASE(empty_tset, IsEmptyFix)
+{
+	TSet empty_set;
+	boost::shared_ptr<Function<TSet> > empty_set_expr(new Constant<TSet>(empty_set));
+	IsEmpty<TSet> e(empty_set_expr);
+	BOOST_CHECK(e.apply(cx)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(full_tset, IsEmptyFix)
+{
+	TSet full_set(Corpus2::Tag(1));
+	boost::shared_ptr<Function<TSet> > full_set_expr(new Constant<TSet>(full_set));
+	IsEmpty<TSet> e(full_set_expr);
+	BOOST_CHECK(!e.apply(cx)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(default_match, IsEmptyFix)
+{
+	Match default_match;
+	boost::shared_ptr<Function<Match> > default_match_expr(new Constant<Match>(default_match));
+	IsEmpty<Match> e(default_match_expr);
+	BOOST_CHECK(e.apply(cx)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(token_match, IsEmptyFix)
+{
+	Match token_match(TokenMatch(Position(0)));
+	boost::shared_ptr<Function<Match> > match_expr(new Constant<Match>(token_match));
+	IsEmpty<Match> e(match_expr);
+	BOOST_CHECK(!e.apply(cx)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(ann_match, IsEmptyFix)
+{
+	Match ann_match(AnnotationMatch(0, "foo"));
+	boost::shared_ptr<Function<Match> > match_expr(new Constant<Match>(ann_match));
+	IsEmpty<Match> e(match_expr);
+	BOOST_CHECK(!e.apply(cx)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(empty_matchvector, IsEmptyFix)
+{
+	MatchVector v;
+	Match v_match(v);
+	boost::shared_ptr<Function<Match> > match_expr(new Constant<Match>(v_match));
+	IsEmpty<Match> e(match_expr);
+	BOOST_CHECK(!e.apply(cx)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(full_matchvector, IsEmptyFix)
+{
+	MatchVector v;
+	v.append(boost::shared_ptr<TokenMatch>(new TokenMatch(0)));
+	Match v_match(v);
+	boost::shared_ptr<Function<Match> > match_expr(new Constant<Match>(v_match));
+	IsEmpty<Match> e(match_expr);
+	BOOST_CHECK(e.apply(cx)->get_value());
+}
+
+//------------ To string ----------
+
+BOOST_FIXTURE_TEST_CASE(empty_strset_tostring, IsEmptyFix)
+{
+	StrSet full_set;
+	full_set.insert("word");
+	boost::shared_ptr<Function<StrSet> > full_set_expr(new Constant<StrSet>(full_set));
+	IsEmpty<StrSet> e(full_set_expr);
+	BOOST_CHECK_EQUAL("empty([\"word\"])", e.to_string(tagset));
+}
+
+BOOST_AUTO_TEST_CASE(empty_strset_tostring_to_raw_string)
+{
+	StrSet full_set;
+	full_set.insert("word");
+	boost::shared_ptr<Function<StrSet> > full_set_expr(new Constant<StrSet>(full_set));
+	IsEmpty<StrSet> e(full_set_expr);
+	BOOST_CHECK_EQUAL("empty([\"word\"])", e.to_raw_string());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
-- 
GitLab