diff options
Diffstat (limited to 'project2/variables.cpp')
-rw-r--r-- | project2/variables.cpp | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/project2/variables.cpp b/project2/variables.cpp index 09ea36e..c6a65f1 100644 --- a/project2/variables.cpp +++ b/project2/variables.cpp @@ -8,6 +8,9 @@ #include <boost/tokenizer.hpp> #include <boost/foreach.hpp> #include <boost/algorithm/string/predicate.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/function.hpp> +#include <boost/bind.hpp> class VariableLiteral : public VariableImpl { public: @@ -19,6 +22,7 @@ class VariableLiteral : public VariableImpl { class VariableImplDyn : public VariableImpl { public: VariableImplDyn(const Glib::ustring & src) : VariableImpl(src), cacheValid(false) { } + VariableImplDyn(const Glib::ustring & src, boost::optional<Glib::ustring> def) : VariableImpl(src, def), cacheValid(false) { } virtual const Glib::ustring & value() const = 0; protected: @@ -94,6 +98,15 @@ class VariableParent : public VariableImplDyn, public RowUser { depth(src.length() - source.length()), dep(d) { + bind(); + } + VariableParent(const Glib::ustring & name, unsigned int d) : + VariableImplDyn(name, NULL), + row(NULL), + depth(d), + dep(NULL) + { + bind(); } ~VariableParent() { @@ -120,7 +133,7 @@ class VariableParent : public VariableImplDyn, public RowUser { row->use(dep); } } - cache = row->getCurrentValue(name); + getValue(cache, row); } catch (PerRowValues::ParentOutOfRange) { if (!defaultValue) { @@ -143,9 +156,31 @@ class VariableParent : public VariableImplDyn, public RowUser { cacheValid = false; } protected: + static void assignHelper(Glib::ustring & dest, const Glib::ustring & src) { + dest = src; + } + void bind() + { + if (name[0] == '!') { + if (name == "!rownum") { + getValue = boost::bind(&assignHelper, _1, + boost::bind(&boost::lexical_cast<Glib::ustring, unsigned int>, + boost::bind(&PerRowValues::getRowNum, _2))); + } + else { + throw PerRowValues::FieldDoesNotExist(); + } + } + else { + typedef const Glib::ustring & (PerRowValues::*gCV)(const Glib::ustring &) const; + getValue = boost::bind(&assignHelper, _1, + boost::bind((gCV)&PerRowValues::getCurrentValue, _2, name)); + } + } mutable const PerRowValues * row; const size_t depth; const RowUser * dep; + boost::function2<void, Glib::ustring &, const PerRowValues *> getValue; }; class VariableParse : public VariableImplDyn, public RowUser { @@ -190,16 +225,21 @@ Variable::Variable(const Glib::ustring & s) : { } -Variable::Variable(xmlpp::Attribute * a) : +Variable::Variable(const xmlpp::Attribute * a) : var(create(a->get_value())) { } -Variable::Variable(xmlpp::Element * e) : +Variable::Variable(const xmlpp::Element * e) : var(create(e->get_child_text()->get_content())) { } +Variable::Variable(VariableImpl * v) : + var(v) +{ +} + Variable::VariableImplPtr Variable::create(const Glib::ustring & s, RowUser * dep) { @@ -224,6 +264,19 @@ Variable::create(const Glib::ustring & s, RowUser * dep) } } +Variable +Variable::makeParent(const Glib::ustring & n, unsigned int d) +{ + return Variable(new VariableParent(n, d)); +} + +VariableImpl::VariableImpl(const Glib::ustring & src, boost::optional<Glib::ustring> def) : + source(src), + name(src), + defaultValue(def) +{ +} + VariableImpl::VariableImpl(const Glib::ustring & src) : source(src) { |