Newer
Older
Adam Wardyński
committed
#ifndef LIBWCCL_OPS_CONDITIONAL_H
#define LIBWCCL_OPS_CONDITIONAL_H
Adam Wardyński
committed
#include <boost/mpl/list.hpp>
#include <boost/mpl/count.hpp>
#include <sstream>
#include <boost/format.hpp>
#include <libwccl/ops/predicate.h>
#include <libwccl/ops/constant.h>
#include <libwccl/ops/formatters.h>
Adam Wardyński
committed
namespace Wccl {
/**
* Template class for conditional operators, returning value
* depending on evaluation of some predicate.
* This class is targeted towards if..then..else expression
*/
template<class T>
class Conditional : public Function<T> {
public:
typedef boost::shared_ptr<Function<T> > ArgFunctionPtr;
typedef boost::shared_ptr<Function<Bool> > BoolFunctionPtr;
Adam Wardyński
committed
Adam Wardyński
committed
Conditional(
const BoolFunctionPtr& cond_expr,
const ArgFunctionPtr& iftrue_expr,
Adam Wardyński
committed
const ArgFunctionPtr& iffalse_expr = Default())
Adam Wardyński
committed
: cond_expr_(cond_expr), iftrue_expr_(iftrue_expr), iffalse_expr_(iffalse_expr)
{
BOOST_ASSERT(cond_expr_);
BOOST_ASSERT(iftrue_expr_);
BOOST_ASSERT(iffalse_expr_);
}
/**
* String representation of conditional operator in form of:
* "if cond_expr_string then iftrue_expr_string else iffalse_expr_string"
*/
virtual std::string to_string(const Corpus2::Tagset& tagset) const;
Adam Wardyński
committed
/**
* String representation of conditional operator in form of:
* "if cond_expr_raw_s then iftrue_expr_raw_s else iffalse_expr_raw_s"
* This version does not require tagset, but may be inclomplete
* and/or contain internal info.
*/
virtual std::string to_raw_string() const;
Adam Wardyński
committed
virtual const std::string raw_operator_name() const {
return "if";
}
protected:
const BoolFunctionPtr cond_expr_;
const ArgFunctionPtr iftrue_expr_;
const ArgFunctionPtr iffalse_expr_;
Adam Wardyński
committed
static const ArgFunctionPtr& Default() {
static ArgFunctionPtr x(new Constant<T>(T()));
return x;
}
Adam Wardyński
committed
typedef FunctionBase::BaseRetValPtr BaseRetValPtr;
/**
* Evaluate the predicate. If it is true, evaluate and return value of
* iftrue_expression. If predicate is false, evalute and return value
* of iffalse_expression.
*/
virtual BaseRetValPtr apply_internal(const FunExecContext& context) const {
Adam Wardyński
committed
if(this->cond_expr_->apply(context)->get_value()) {
return iftrue_expr_->apply(context);
}
return iffalse_expr_->apply(context);
}
};
/**
* Template class for conditional operator targeted
* towards the operator "? if_true_value ? predicate"
* Difference between base Conditional<T> is that
* the if_false_value is always default,
* and string representation is different.
*/
template<class T>
class ConditionalOp : public Conditional<T> {
public:
typedef typename Conditional<T>::ArgFunctionPtr ArgFunctionPtr;
typedef boost::shared_ptr<Function<Bool> > BoolFunctionPtr;
ConditionalOp(
const BoolFunctionPtr& cond_expr,
const ArgFunctionPtr& iftrue_expr)
: Conditional<T>(cond_expr, iftrue_expr)
{
}
/**
* String representation of conditional operator in form of:
* "? if_true_expr_string ? cond_expr_string"
*/
virtual std::string to_string(const Corpus2::Tagset& tagset) const;
Adam Wardyński
committed
/**
* String representation of conditional operator in form of:
* "? if_true_expr_raw_string ? cond_expr_raw_string"
* This version does not require tagset, but may be inclomplete
* and/or contain internal info.
*/
virtual std::string to_raw_string() const;
Adam Wardyński
committed
virtual const std::string raw_operator_name() const {
return "?";
}
};
template<class T>
std::string Conditional<T>::to_raw_string() const
{
std::stringstream ss;
ss << boost::format("%1%(%2%, %3%, %4%)")
% this->raw_operator_name()
% this->cond_expr_->to_raw_string()
% this->iftrue_expr_->to_raw_string()
% this->iffalse_expr_->to_raw_string();
return ss.str();
}
template<class T>
std::string Conditional<T>::to_string(const Corpus2::Tagset &tagset) const
{
std::stringstream ss;
ss << boost::format("%1%(%2%, %3%, %4%)")
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
% this->operator_name(tagset)
% this->cond_expr_->to_string(tagset)
% this->iftrue_expr_->to_string(tagset)
% this->iffalse_expr_->to_string(tagset);
return ss.str();
}
template<class T>
std::string ConditionalOp<T>::to_raw_string() const
{
std::stringstream ss;
ss << boost::format("%1% %2% ? %3%")
% this->raw_operator_name()
% this->iftrue_expr_->to_raw_string()
% this->cond_expr_->to_raw_string();
return ss.str();
}
template<class T>
std::string ConditionalOp<T>::to_string(const Corpus2::Tagset &tagset) const
{
std::stringstream ss;
ss << boost::format("%1% %2% ? %3%")
% this->operator_name(tagset)
% this->iftrue_expr_->to_string(tagset)
% this->cond_expr_->to_string(tagset);
return ss.str();
}
Adam Wardyński
committed
} /* end ns Wccl */
Adam Wardyński
committed
#endif // LIBWCCL_OPS_CONDITIONAL_H