From 3d4259e6d0ed01425ba9c35f3866fc298631c9e8 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 8 Sep 2004 04:13:02 -0400 Subject: balances and values can now be iterated, to get at the component amounts --- amounts.py | 7 +++++++ balance.cc | 46 ++++++++++++++++++++++++++++++++++++++++------ balance.h | 2 ++ value.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 6 deletions(-) diff --git a/amounts.py b/amounts.py index aa70086c..1d556a1c 100644 --- a/amounts.py +++ b/amounts.py @@ -16,3 +16,10 @@ z = Value ("$1000.45") z += Value(x) print z + +bal = Balance (x) +bal += Amount ("100.8 DM") + +print "balance:", bal +for amt in bal: + print " amount:", amt diff --git a/balance.cc b/balance.cc index 14ce1615..9c4f04aa 100644 --- a/balance.cc +++ b/balance.cc @@ -92,6 +92,38 @@ void balance_t::write(std::ostream& out, using namespace boost::python; using namespace ledger; +unsigned int balance_len(balance_t& bal) +{ + return bal.amounts.size(); +} + +amount_t balance_getitem(balance_t& bal, int i) +{ + std::size_t len = bal.amounts.size(); + + if (abs(i) >= len) { + PyErr_SetString(PyExc_IndexError, "Index out of range"); + throw_error_already_set(); + } + + int x = i < 0 ? len + i : i; + amounts_map::iterator elem = bal.amounts.begin(); + while (--x >= 0) + elem++; + + return (*elem).second; +} + +unsigned int balance_pair_len(balance_pair_t& bal_pair) +{ + return balance_len(bal_pair.quantity); +} + +amount_t balance_pair_getitem(balance_pair_t& bal_pair, int i) +{ + return balance_getitem(bal_pair.quantity, i); +} + void export_balance() { class_< balance_t > ("Balance") @@ -134,9 +166,10 @@ void export_balance() .def(! self) .def(abs(self)) -#if 0 - .def(str(self)) -#endif + .def(self_ns::str(self)) + + .def("__len__", balance_len) + .def("__getitem__", balance_getitem) .def("negate", &balance_t::negate) .def("amount", &balance_t::amount) @@ -200,9 +233,10 @@ void export_balance() .def(! self) .def(abs(self)) -#if 0 - .def(str(self)) -#endif + .def(self_ns::str(self)) + + .def("__len__", balance_pair_len) + .def("__getitem__", balance_pair_getitem) .def("negate", &balance_pair_t::negate) .def("amount", &balance_pair_t::amount) diff --git a/balance.h b/balance.h index e671192f..8eae567d 100644 --- a/balance.h +++ b/balance.h @@ -391,6 +391,7 @@ inline balance_t abs(const balance_t& bal) { inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) { bal.write(out, 12); + return out; } @@ -762,6 +763,7 @@ inline balance_pair_t abs(const balance_pair_t& bal_pair) { inline std::ostream& operator<<(std::ostream& out, const balance_pair_t& bal_pair) { bal_pair.quantity.write(out, 12); + return out; } } // namespace ledger diff --git a/value.cc b/value.cc index 1741964e..fe8c5264 100644 --- a/value.cc +++ b/value.cc @@ -550,6 +550,62 @@ value_t value_t::cost() const using namespace boost::python; using namespace ledger; +unsigned int balance_len(balance_t& bal); +amount_t balance_getitem(balance_t& bal, int i); +unsigned int balance_pair_len(balance_pair_t& bal_pair); +amount_t balance_pair_getitem(balance_pair_t& bal_pair, int i); + +unsigned int value_len(value_t& value) +{ + switch (value.type) { + case value_t::BOOLEAN: + case value_t::INTEGER: + case value_t::AMOUNT: + return 1; + + case value_t::BALANCE: + return balance_len(*((balance_t *) value.data)); + + case value_t::BALANCE_PAIR: + return balance_pair_len(*((balance_pair_t *) value.data)); + + default: + assert(0); + break; + } + assert(0); + return 0; +} + +amount_t value_getitem(value_t& value, int i) +{ + std::size_t len = value_len(value); + + if (abs(i) >= len) { + PyErr_SetString(PyExc_IndexError, "Index out of range"); + throw_error_already_set(); + } + + switch (value.type) { + case value_t::BOOLEAN: + case value_t::INTEGER: + case value_t::AMOUNT: + return value; + + case value_t::BALANCE: + return balance_getitem(*((balance_t *) value.data), i); + + case value_t::BALANCE_PAIR: + return balance_pair_getitem(*((balance_pair_t *) value.data), i); + + default: + assert(0); + break; + } + assert(0); + return 0; +} + void export_value() { class_< value_t > ("Value") @@ -627,6 +683,9 @@ void export_value() .def(abs(self)) .def(self_ns::str(self)) + .def("__len__", value_len) + .def("__getitem__", value_getitem) + .def("cast", &value_t::cast) .def("negate", &value_t::negate) .def("cost", &value_t::cost) -- cgit v1.2.3