From 03427611253516e2c8315eff73e19268ce6f0e6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adam=20Wardy=C5=84ski?= <no@email>
Date: Thu, 4 Nov 2010 15:50:51 +0100
Subject: [PATCH] Some abstract base classes for functional operators

---
 libwccl/ops/functions.h | 183 ++++++++++++++++++++++++++++++++++++++++
 libwccl/ops/operator.h  |  50 +++++++++++
 2 files changed, 233 insertions(+)
 create mode 100644 libwccl/ops/functions.h
 create mode 100644 libwccl/ops/operator.h

diff --git a/libwccl/ops/functions.h b/libwccl/ops/functions.h
new file mode 100644
index 0000000..7e4779a
--- /dev/null
+++ b/libwccl/ops/functions.h
@@ -0,0 +1,183 @@
+#ifndef FUNCTIONS_H
+#define FUNCTIONS_H
+
+#include <boost/shared_ptr.hpp>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+#include <libwccl/ops/operator.h>
+#include <libwccl/values/value.h>
+#include <libwccl/sentencecontext.h>
+
+namespace Wccl {
+
+/**
+ * Abstract base class for WCCL operators that are functions returning a Value
+ */
+class FunctionBase : public Operator {
+protected:
+	typedef boost::shared_ptr<Value> BaseRetValPtr;
+	/**
+	 * Applies the function, given the sentence context.
+	 */
+	virtual BaseRetValPtr apply_internal(const SentenceContext& context) const = 0;
+};
+
+/**
+ * Abstract base class template for functional WCCL operators that are functions
+ * returning a value of given type
+ */
+template<class TRet>
+class Function : public FunctionBase {
+	BOOST_MPL_ASSERT( (boost::is_base_of<Value, TRet>) );
+	BOOST_MPL_ASSERT_NOT( (boost::is_same<Value, TRet>) );
+public:
+	/**
+	 * Type returned after application of function (shared pointer to
+	 * a variable of the specified return type)
+	 */
+	typedef boost::shared_ptr<TRet> RetValPtr;
+
+	/**
+	 * Applies the function, given the sentence context, returning specific
+	 * type of Value (as shared pointer). Uses apply_internal which has to
+	 * be specified in derived classes.
+	 */
+	RetValPtr apply(const SentenceContext& context) const {
+		RetValPtr v = boost::dynamic_pointer_cast<TRet>(apply_internal(context));
+		BOOST_ASSERT(v);
+		return v;
+	}
+};
+
+/**
+ * Abstract base class template for functional WCCL operators returning
+ * a value of given type, while taking a single argument of selected type.
+ * The argument is actually realised as a functional expression that returns
+ * value of the specified type, per the unary function requirements.
+ */
+template<class TArg, class TRet>
+class UnaryFunction : public Function<TRet> {
+public:
+	/**
+	 * Shared pointer type of expression that returns argument for
+	 * our unary function application
+	 */
+	typedef boost::shared_ptr<Function<TArg> > ArgExprPtr;
+
+	UnaryFunction(const ArgExprPtr& arg_expr)
+		: arg_expr_(arg_expr)
+	{
+		BOOST_ASSERT(arg_expr_);
+	}
+
+	/**
+	 * String representation of the unary function, realised by default
+	 * as "operator_name(argument_string)" (using open and close
+	 * brackets supplied by open_bracket() and close_bracket())
+	 */
+	virtual std::string to_string(const Corpus2::Tagset& tagset) const {
+		std::string returnValue(this->operator_name(tagset));
+		returnValue.append(open_bracket());
+		returnValue.append(arg_expr_->to_string(tagset));
+		returnValue.append(close_bracket());
+		return returnValue;
+	}
+	/**
+	 * String representation of the unary function, that does not
+	 * require tagset. May be incomplete and/or contain internal info.
+	 * Realised by default as "raw_operator_name(raw_argument_string)"
+	 * (using open and close brackets supplied by open_bracket()
+	 * and close_bracket())
+	 */
+	virtual std::string to_raw_string() const {
+		std::string returnValue(this->raw_operator_name());
+		returnValue.append(open_bracket());
+		returnValue.append(arg_expr_->to_raw_string());
+		returnValue.append(close_bracket());
+		return returnValue;
+	}
+protected:
+	const ArgExprPtr arg_expr_;
+
+	/**
+	 * Opening bracket to use in string representation.
+	 * By default it is "(", but some operators use "["
+	 */
+	virtual const char* open_bracket() {
+		return "(";
+	}
+	/**
+	 * Closing bracket to use in string representation.
+	 * By default it is ")", but some operators use "]"
+	 */
+	virtual const char* close_bracket() {
+		return ")";
+	}
+};
+
+/**
+ * Abstract base class template for functional WCCL operators returning
+ * a value of given type, while taking two arguments of selected types.
+ * The arguments are actually realised as functions that return
+ * value of a specified type, per the binary function requirements.
+ */
+template<class TArg1, class TArg2, class TRet>
+class BinaryFunction : public Function<TRet> {
+public:
+	/**
+	 * Shared pointer type of expression that returns first argument for
+	 * our binary function application
+	 */
+	typedef boost::shared_ptr<Function<TArg1> > Arg1ExprPtr;
+	/**
+	 * Shared pointer type of expression that returns second argument for
+	 * our binary function application
+	 */
+	typedef boost::shared_ptr<Function<TArg2> > Arg2ExprPtr;
+
+	BinaryFunction(const Arg1ExprPtr& arg1_expr, const Arg2ExprPtr& arg2_expr)
+		: arg1_expr_(arg1_expr), arg2_expr_(arg2_expr)
+	{
+		BOOST_ASSERT(arg1_expr_);
+		BOOST_ASSERT(arg2_expr_);
+	}
+
+	/**
+	 * String representation of the binary function, realised by default
+	 * as "operator_name(arg1_string, arg2_string)"
+	 */
+	virtual std::string to_string(const Corpus2::Tagset& tagset) const {
+		std::string returnValue(this->operator_name(tagset));
+		returnValue.append("(");
+		returnValue.append(arg1_expr_->to_string(tagset));
+		returnValue.append(", ");
+		returnValue.append(arg2_expr_->to_string(tagset));
+		returnValue.append(")");
+		return returnValue;
+	}
+
+	/**
+	 * String representation of the binary function, that does not
+	 * require tagset. May be incomplete and/or contain internal info.
+	 * Realised by default as "raw_operator_name(raw_arg1_string, raw_arg2_string)"
+	 */
+	virtual std::string to_raw_string() const {
+		std::string returnValue(this->raw_operator_name());
+		returnValue.append("(");
+		returnValue.append(arg1_expr_->to_raw_string());
+		returnValue.append(", ");
+		returnValue.append(arg2_expr_->to_raw_string());
+		returnValue.append(")");
+		return returnValue;
+	}
+protected:
+	const Arg1ExprPtr arg1_expr_;
+	const Arg2ExprPtr arg2_expr_;
+
+};
+
+} /* end ns Wccl */
+
+#endif // FUNCTIONS_H
diff --git a/libwccl/ops/operator.h b/libwccl/ops/operator.h
new file mode 100644
index 0000000..46ae2ec
--- /dev/null
+++ b/libwccl/ops/operator.h
@@ -0,0 +1,50 @@
+#ifndef OPERATOR_H
+#define OPERATOR_H
+
+#include <libcorpus2/tagset.h>
+#include <unicode/unistr.h>
+#include <boost/noncopyable.hpp>
+
+namespace Wccl {
+
+/**
+ * Abstract base class for WCCL operators
+ */
+class Operator : public boost::noncopyable {
+public:
+	/**
+	 * Name of the Operator, in general a tagset is required,
+	 * but some classes might not need that, so by default just forward
+	 * to raw_operator_name();
+	 */
+	virtual const std::string operator_name(const Corpus2::Tagset& /*tagset*/) const {
+		return raw_operator_name();
+	}
+	/**
+	 * Name of the Operator that does not require a tagset,
+	 * might be incomplete and/or contain internal info.
+	 *
+	 * Prefer operator_name(tagset).
+	 */
+	virtual const std::string raw_operator_name() const = 0;
+	/**
+	 * String representation of the operator, by default it's just
+	 * the name of the operator returned by operator_name(tagset)
+	 */
+	virtual std::string to_string(const Corpus2::Tagset& tagset) const {
+		return operator_name(tagset);
+	}
+	/**
+	 * String representation of the operator that does not require a tagset,
+	 * might be incomplete and/or contain internal info.
+	 *
+	 * By default it is just the raw_operator_name()
+	 */
+	virtual std::string to_raw_string() const {
+		return raw_operator_name();
+	}
+};
+
+} /* end ns Wccl */
+
+#endif // OPERATOR_H
-- 
GitLab