An error occurred while loading the file. Please try again.
-
Adam Wardynski authored2bf3081b
opsequence.h 8.95 KiB
#ifndef LIBWCCL_OPS_OPSEQUENCE_H
#define LIBWCCL_OPS_OPSEQUENCE_H
#include <vector>
#include <sstream>
#include <boost/lexical_cast.hpp>
#include <boost/make_shared.hpp>
#include <libpwrutils/foreach.h>
#include <libwccl/ops/operator.h>
namespace Wccl {
class FunctionalOpSequence : public Expression
{
public:
typedef boost::shared_ptr<FunctionalOperator> fun_op_ptr_t;
typedef boost::shared_ptr<const FunctionalOperator> fun_op_ptr_c_t;
typedef std::pair<std::string, fun_op_ptr_t> name_op_pair_t;
typedef std::pair<std::string, fun_op_ptr_c_t> name_op_pair_c_t;
typedef std::vector<name_op_pair_t> name_op_v_t;
typedef std::vector<name_op_pair_c_t> name_op_v_c_t;
std::string name() const {
return name_;
}
virtual size_t size() const = 0;
virtual bool empty() const = 0;
virtual FunctionalOperator& get(size_t idx) = 0;
virtual const FunctionalOperator& get(size_t idx) const = 0;
virtual fun_op_ptr_t get_untyped_ptr(size_t idx) = 0;
virtual fun_op_ptr_c_t get_untyped_ptr(size_t idx) const = 0;
name_op_v_t& add_name_op_pairs_untyped(name_op_v_t& pairs);
name_op_v_c_t& add_name_op_pairs_untyped(name_op_v_c_t& pairs) const;
name_op_v_t gen_name_op_pairs_untyped() {
name_op_v_t v;
return add_name_op_pairs_untyped(v);
}
name_op_v_c_t gen_name_op_pairs_untyped() const {
name_op_v_c_t v;
return add_name_op_pairs_untyped(v);
}
std::string gen_op_name(size_t idx) const {
return name_ + "-" + boost::lexical_cast<std::string, size_t>(idx);
}
name_op_pair_t gen_name_op_pair_untyped(size_t idx) {
return name_op_pair_t(gen_op_name(idx), get_untyped_ptr(idx));
}
name_op_pair_c_t gen_name_op_pair_untyped(size_t idx) const {
return name_op_pair_c_t(gen_op_name(idx), get_untyped_ptr(idx));
}
boost::shared_ptr<FunctionalOpSequence> clone() const {
return boost::shared_ptr<FunctionalOpSequence>(clone_internal());
}
virtual ~FunctionalOpSequence() {
}
protected:
FunctionalOpSequence(const std::string& name)
: name_(name) {
}
virtual FunctionalOpSequence* clone_internal() const = 0;
std::string name_;
};
class UntypedOpSequence : public FunctionalOpSequence
{
public:
typedef FunctionalOperator op_t;
UntypedOpSequence(const std::string& name)
: FunctionalOpSequence(name),
ops_()
{
}
bool empty() const {
return ops_.empty();
}
size_t size() const {
return ops_.size();
}
void append(const fun_op_ptr_t& op) {
ops_.push_back(op);
}
op_t& get(size_t idx) {
if(idx >= ops_.size()) {
throw InvalidArgument("idx", "Index out of range.");
}
return *ops_[idx];
}
const op_t& get(size_t idx) const {
return *get_ptr(idx);
}
fun_op_ptr_t get_untyped_ptr(size_t idx) {
return get_ptr(idx);
}
fun_op_ptr_c_t get_untyped_ptr(size_t idx) const {
return get_ptr(idx);
}
fun_op_ptr_t get_ptr(size_t idx) {
if(idx >= ops_.size()) {
throw InvalidArgument("idx", "Index out of range.");
}
return ops_[idx];
}
fun_op_ptr_c_t get_ptr(size_t idx) const {
if(idx >= ops_.size()) {
throw InvalidArgument("idx", "Index out of range.");
}
return ops_[idx];
}
name_op_v_t& add_name_op_pairs(name_op_v_t& pairs) {
return add_name_op_pairs_untyped(pairs);
}
name_op_v_c_t& add_name_op_pairs(name_op_v_c_t& pairs) const {
return add_name_op_pairs_untyped(pairs);
}
name_op_v_t gen_name_op_pairs() {
return gen_name_op_pairs_untyped();
}
name_op_v_c_t gen_name_op_pairs() const {
return gen_name_op_pairs_untyped();
}
name_op_pair_t gen_name_op_pair(size_t idx) {
return gen_name_op_pair_untyped(idx);
}
name_op_pair_c_t gen_name_op_pair(size_t idx) const {
return gen_name_op_pair_untyped(idx);
}
std::string to_string(const Corpus2::Tagset& tagset) const;
UntypedOpSequence(const UntypedOpSequence& seq);
boost::shared_ptr<UntypedOpSequence> clone() const {
return boost::make_shared<UntypedOpSequence>(*this);
}
protected:
std::ostream& write_to(std::ostream& ostream) const;
UntypedOpSequence* clone_internal() const {
return new UntypedOpSequence(*this);
}
private:
std::vector<fun_op_ptr_t> ops_;
};
template<class T>
class OpSequence : public FunctionalOpSequence
{
BOOST_MPL_ASSERT( (boost::is_base_of<Value, T>) );
BOOST_MPL_ASSERT_NOT( (boost::is_same<Value, T>) );
public:
typedef Operator<T> op_t;
typedef typename boost::shared_ptr<Operator<T> > op_ptr_t;
typedef typename boost::shared_ptr<const Operator<T> > op_ptr_c_t;
typedef typename std::pair<std::string, op_ptr_t> name_op_pair_t;
typedef typename std::pair<std::string, op_ptr_c_t> name_op_pair_c_t;
typedef typename std::vector<name_op_pair_t> name_op_v_t;
typedef typename std::vector<name_op_pair_c_t> name_op_v_c_t;
OpSequence(const std::string& name)
: FunctionalOpSequence(name),
ops_()
{
}
bool empty() const {
return ops_.empty();
}
size_t size() const {
return ops_.size();
}
void append(const op_ptr_t& op) {
ops_.push_back(op);
}
op_t& get(size_t idx) {
return *get_ptr(idx);
}
const op_t& get(size_t idx) const {
return *get_ptr(idx);
}
op_ptr_t get_ptr(size_t idx) {
if(idx >= ops_.size()) {
throw InvalidArgument("idx", "Index out of range.");
}
return ops_[idx];
}
op_ptr_c_t get_ptr(size_t idx) const {
if(idx >= ops_.size()) {
throw InvalidArgument("idx", "Index out of range.");
}
return ops_[idx];
}
FunctionalOpSequence::fun_op_ptr_t get_untyped_ptr(size_t idx) {
return get_ptr(idx);
}
FunctionalOpSequence::fun_op_ptr_c_t get_untyped_ptr(size_t idx) const {
return get_ptr(idx);
}
name_op_v_t gen_name_op_pairs();
name_op_v_c_t gen_name_op_pairs() const;
name_op_v_t& add_name_op_pairs(name_op_v_t& pairs);
name_op_v_c_t& add_name_op_pairs(name_op_v_c_t& pairs) const;
name_op_pair_t gen_name_op_pair(size_t idx);
name_op_pair_c_t gen_name_op_pair(size_t idx) const;
std::string to_string(const Corpus2::Tagset& tagset) const;
OpSequence(const OpSequence<T>& seq);
boost::shared_ptr<OpSequence<T> > clone() const;
protected:
std::ostream& write_to(std::ostream& os) const;
virtual OpSequence<T>* clone_internal() const;
private:
std::vector<op_ptr_t> ops_;
};
} /* end ns Wccl */
//
// Implementation details
//
namespace Wccl {
template<class T> inline
typename OpSequence<T>::name_op_pair_t OpSequence<T>::gen_name_op_pair(
size_t idx)
{
return name_op_pair_t(gen_op_name(idx), get_ptr(idx));
}
template<class T> inline
typename OpSequence<T>::name_op_pair_c_t OpSequence<T>::gen_name_op_pair(
size_t idx) const
{
return name_op_pair_c_t(gen_op_name(idx), get_ptr(idx));
}
template<class T> inline
typename OpSequence<T>::name_op_v_t& OpSequence<T>::add_name_op_pairs(
name_op_v_t& pairs)
{
for(size_t i = 0; i < size(); ++i) {
pairs.push_back(gen_name_op_pair(i));
}
return pairs;
}
template<class T> inline
typename OpSequence<T>::name_op_v_c_t& OpSequence<T>::add_name_op_pairs(
name_op_v_c_t& pairs) const
{
for(size_t i = 0; i < size(); ++i) {
pairs.push_back(gen_name_op_pair(i));
}
return pairs;
}
template<class T> inline
typename OpSequence<T>::name_op_v_t OpSequence<T>::gen_name_op_pairs() {
name_op_v_t v;
return add_name_op_pairs(v);
}
template<class T> inline
typename OpSequence<T>::name_op_v_c_t OpSequence<T>::gen_name_op_pairs() const {
name_op_v_c_t v;
return add_name_op_pairs(v);
}
template<class T> inline
OpSequence<T>::OpSequence(const OpSequence<T>& seq)
: FunctionalOpSequence(seq.name_),
ops_(seq.size())
{
foreach(const op_ptr_t& op, seq.ops_) {
ops_.push_back(op->clone_ptr());
}
}
template<class T> inline
OpSequence<T>* OpSequence<T>::clone_internal() const
{
return new OpSequence(*this);
}
template<class T> inline
typename boost::shared_ptr<OpSequence<T> > OpSequence<T>::clone() const
{
return boost::make_shared<OpSequence<T> >(*this);
}
namespace detail {
template<class T>
class SectionStrProvider;
template<>
class SectionStrProvider<Position>
{
public:
static std::string typed_section_str() {
return "@p:";
}
};
template<>
class SectionStrProvider<Bool>
{
public:
static std::string typed_section_str() {
return "@b:";
}
};
template<>
class SectionStrProvider<StrSet>
{
public:
static std::string typed_section_str() {
return "@s:";
}
};
template<>
class SectionStrProvider<TSet>
{
public:
static std::string typed_section_str() {
return "@t:";
}
};
template<>
class SectionStrProvider<Match>
{
public:
static std::string typed_section_str() {
return "@m:";
}
};
} /* end ns detail */
template<class T> inline
std::string OpSequence<T>::to_string(const Corpus2::Tagset& tagset) const
{
std::ostringstream os;
os << detail::SectionStrProvider<T>::typed_section_str() << name() << " (";
for (size_t i = 0; i < size(); ++i) {
if (i != 0) {
os << ", ";
}
os << ops_[i]->to_string(tagset);
}
os << ")";
return os.str();
}
template<class T> inline
std::ostream& OpSequence<T>::write_to(std::ostream& os) const
{
os << detail::SectionStrProvider<T>::typed_section_str() << name() << " (";
for (size_t i = 0; i < size(); ++i) {
if (i != 0) {
os << ", ";
}
os << *ops_[i];
}
return os << ")";
}
} /* end ns Wccl */
#endif // LIBWCCL_OPS_OPSEQUENCE_H