Finished documentation for balance_pair_t.

This commit is contained in:
John Wiegley 2007-05-22 07:23:38 +00:00
parent ce4ed2b25c
commit 5054147043
2 changed files with 162 additions and 123 deletions

View file

@ -77,14 +77,12 @@ class balance_t
public: public:
typedef std::map<const commodity_t *, amount_t> amounts_map; typedef std::map<const commodity_t *, amount_t> amounts_map;
protected:
amounts_map amounts; amounts_map amounts;
// jww (2007-05-20): Remove these two by adding access methods // jww (2007-05-20): Remove these two by adding access methods
friend class value_t; friend class value_t;
friend class entry_base_t; friend class entry_base_t;
public:
/** /**
* Constructors. balance_t supports similar forms of construction * Constructors. balance_t supports similar forms of construction
* to amount_t. * to amount_t.
@ -233,7 +231,8 @@ public:
balance_t& operator-=(const balance_t& bal); balance_t& operator-=(const balance_t& bal);
balance_t& operator-=(const amount_t& amt); balance_t& operator-=(const amount_t& amt);
balance_t& operator*=(const amount_t& amt); virtual balance_t& operator*=(const amount_t& amt);
balance_t& operator*=(const double val) { balance_t& operator*=(const double val) {
return *this *= amount_t(val); return *this *= amount_t(val);
} }
@ -244,7 +243,8 @@ public:
return *this *= amount_t(val); return *this *= amount_t(val);
} }
balance_t& operator/=(const amount_t& amt); virtual balance_t& operator/=(const amount_t& amt);
balance_t& operator/=(const double val) { balance_t& operator/=(const double val) {
return *this /= amount_t(val); return *this /= amount_t(val);
} }
@ -294,7 +294,7 @@ public:
temp.in_place_negate(); temp.in_place_negate();
return temp; return temp;
} }
balance_t& in_place_negate() { virtual balance_t& in_place_negate() {
for (amounts_map::iterator i = amounts.begin(); for (amounts_map::iterator i = amounts.begin();
i != amounts.end(); i != amounts.end();
i++) i++)
@ -319,10 +319,10 @@ public:
temp.in_place_reduce(); temp.in_place_reduce();
return temp; return temp;
} }
balance_t& in_place_reduce() { virtual balance_t& in_place_reduce() {
balance_t temp;
// A temporary must be used here because reduction may cause // A temporary must be used here because reduction may cause
// multiple component amounts to collapse to the same commodity. // multiple component amounts to collapse to the same commodity.
balance_t temp;
for (amounts_map::const_iterator i = amounts.begin(); for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end(); i != amounts.end();
i++) i++)
@ -335,10 +335,10 @@ public:
temp.in_place_unreduce(); temp.in_place_unreduce();
return temp; return temp;
} }
balance_t& in_place_unreduce() { virtual balance_t& in_place_unreduce() {
balance_t temp;
// A temporary must be used here because unreduction may cause // A temporary must be used here because unreduction may cause
// multiple component amounts to collapse to the same commodity. // multiple component amounts to collapse to the same commodity.
balance_t temp;
for (amounts_map::const_iterator i = amounts.begin(); for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end(); i != amounts.end();
i++) i++)
@ -499,7 +499,7 @@ public:
out << ")"; out << ")";
} }
bool valid() const { virtual bool valid() const {
for (amounts_map::const_iterator i = amounts.begin(); for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end(); i != amounts.end();
i++) i++)

View file

@ -97,9 +97,18 @@ public:
balance_pair_t(const balance_t& bal) : balance_t(bal) { balance_pair_t(const balance_t& bal) : balance_t(bal) {
TRACE_CTOR(balance_pair_t, "const balance_t&"); TRACE_CTOR(balance_pair_t, "const balance_t&");
} }
balance_pair_t(const balance_t& bal,
const balance_t& cost_bal)
: balance_t(bal), cost(cost_bal) {
TRACE_CTOR(balance_pair_t, "const balance_t&, const balance_t&");
}
balance_pair_t(const amount_t& amt) : balance_t(amt) { balance_pair_t(const amount_t& amt) : balance_t(amt) {
TRACE_CTOR(balance_pair_t, "const amount_t&"); TRACE_CTOR(balance_pair_t, "const amount_t&");
} }
balance_pair_t(const amount_t& amt, const amount_t& cost_amt)
: balance_t(amt), cost(cost_amt) {
TRACE_CTOR(balance_pair_t, "const amount_t&, const amount_t&");
}
balance_pair_t(const double val) : balance_t(val) { balance_pair_t(const double val) : balance_t(val) {
TRACE_CTOR(balance_pair_t, "const double"); TRACE_CTOR(balance_pair_t, "const double");
} }
@ -161,12 +170,17 @@ public:
* subtraction of other balance pairs, balances or amounts, but * subtraction of other balance pairs, balances or amounts, but
* multiplication and division are restricted to uncommoditized * multiplication and division are restricted to uncommoditized
* amounts only. * amounts only.
*
* There is also an additional additive method called `add' which
* allows for adding an amount and an associated cost
* simultaneously. The signature is:
* add(amount_t amount, optional<amount_t> cost)
*/ */
balance_pair_t& operator+=(const balance_pair_t& bal_pair) { balance_pair_t& operator+=(const balance_pair_t& bal_pair) {
balance_t::operator+=(bal_pair); balance_t::operator+=(bal_pair);
if (bal_pair.cost) { if (bal_pair.cost) {
if (! cost) if (! cost)
*cost = quantity(); cost = quantity();
*cost += *bal_pair.cost; *cost += *bal_pair.cost;
} }
return *this; return *this;
@ -175,49 +189,124 @@ public:
balance_t::operator+=(bal_pair); balance_t::operator+=(bal_pair);
if (bal_pair.cost) { if (bal_pair.cost) {
if (! cost) if (! cost)
*cost = quantity(); cost = quantity();
*cost += *bal_pair.cost; *cost += *bal_pair.cost;
} }
return *this; return *this;
} }
balance_pair_t& operator*=(const amount_t& amt) { virtual balance_pair_t& operator*=(const amount_t& amt) {
balance_t::operator*=(amt); balance_t::operator*=(amt);
if (cost) if (cost)
*cost *= amt; *cost *= amt;
return *this; return *this;
} }
balance_pair_t& operator*=(const double val) {
return *this *= amount_t(val); virtual balance_pair_t& operator/=(const amount_t& amt) {
}
balance_pair_t& operator*=(const unsigned long val) {
return *this *= amount_t(val);
}
balance_pair_t& operator*=(const long val) {
return *this *= amount_t(val);
}
balance_pair_t& operator/=(const amount_t& amt) {
balance_t::operator/=(amt); balance_t::operator/=(amt);
if (cost) if (cost)
*cost /= amt; *cost /= amt;
return *this; return *this;
} }
// comparison balance_pair_t& add(const amount_t& amt,
bool operator==(const balance_pair_t& bal_pair) const { const optional<amount_t>& a_cost = none) {
return quantity() == bal_pair.quantity(); if (a_cost && ! cost)
} cost = quantity();
bool operator==(const balance_t& bal) const {
return quantity() == bal; *this += amt;
}
bool operator==(const amount_t& amt) const { if (cost)
return quantity() == amt; *cost += a_cost ? *a_cost : amt;
return *this;
} }
/** /**
* The `quantity' method provides direct access to the balance_t * Unary arithmetic operators. There are only a few unary methods
* base-class part of the balance pair. * supported for balance pairs (otherwise, the operators inherited
* from balance_t are used):
*
* abs() returns the absolute value of both the quantity and the
* cost of a balance pair.
*
* in_place_negate() negates all the amounts in both the quantity
* and the cost.
*
* in_place_reduce() reduces all the amounts in both the quantity
* and the cost.
*
* in_place_unreduce() unreduces all the amounts in both the
* quantity and the cost.
*
* quantity() returns the balance part of a balance. It is the same
* as doing a downcast<balance_t>(balance_pair).
*/ */
balance_pair_t abs() const {
balance_t temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++)
temp += i->second.abs();
if (cost) {
balance_t cost_temp;
for (amounts_map::const_iterator i = cost->amounts.begin();
i != cost->amounts.end();
i++)
cost_temp += i->second.abs();
return balance_pair_t(temp, cost_temp);
}
return temp;
}
virtual balance_t& in_place_negate() {
balance_t::in_place_negate();
if (cost)
cost->in_place_negate();
return *this;
}
virtual balance_t& in_place_reduce() {
// A temporary must be used here because reduction may cause
// multiple component amounts to collapse to the same commodity.
balance_t temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++)
temp += i->second.reduce();
if (cost) {
balance_t cost_temp;
for (amounts_map::const_iterator i = cost->amounts.begin();
i != cost->amounts.end();
i++)
cost_temp += i->second.reduce();
return *this = balance_pair_t(temp, cost_temp);
}
return *this = temp;
}
virtual balance_t& in_place_unreduce() {
// A temporary must be used here because unreduction may cause
// multiple component amounts to collapse to the same commodity.
balance_t temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++)
temp += i->second.unreduce();
if (cost) {
balance_t cost_temp;
for (amounts_map::const_iterator i = cost->amounts.begin();
i != cost->amounts.end();
i++)
cost_temp += i->second.unreduce();
return *this = balance_pair_t(temp, cost_temp);
}
return *this = temp;
}
balance_t& quantity() { balance_t& quantity() {
return *this; return *this;
} }
@ -225,104 +314,54 @@ public:
return *this; return *this;
} }
// unary negation /**
void in_place_negate() { * Truth tests. An balance pair may be truth tested by comparison
#if 0 * to another balance pair, or by using one of the inherited
quantity.in_place_negate(); * operators from balance_t.
if (cost) */
cost->in_place_negate(); bool operator==(const balance_pair_t& bal_pair) const {
#endif if (quantity() != bal_pair.quantity())
} return false;
balance_pair_t negate() const {
balance_pair_t temp = *this; if ((cost && ! bal_pair.cost) ||
temp.in_place_negate(); (! cost && bal_pair.cost))
return temp; return false;
}
balance_pair_t operator-() const { if (*cost != *bal_pair.cost)
return negate(); return false;
return true;
} }
// test for non-zero (use ! for zero) bool operator==(const balance_t& bal) const {
operator bool() const { return balance_t::operator==(bal);
return quantity(); }
bool operator==(const amount_t& amt) const {
return balance_t::operator==(amt);
}
template <typename T>
bool operator==(const T& val) const {
return balance_t::operator==(val);
} }
bool is_realzero() const { /**
#if 0 * Debugging methods. There is only one method specifically for
return ((! cost || cost->is_realzero()) && quantity.is_realzero()); * balance pairs to help with debugging:
#else *
return false; * valid() returns true if the balances within the balance pair are
#endif * valid.
} */
virtual bool valid() {
if (! balance_t::valid())
return false;
balance_pair_t abs() const { if (cost && ! cost->valid())
#if 0 return false;
balance_pair_t temp = *this;
temp.quantity = temp.quantity.abs();
if (temp.cost)
temp.cost = temp.cost->abs();
return temp;
#else
return balance_pair_t();
#endif
}
optional<amount_t> return true;
commodity_amount(const optional<const commodity_t&>& commodity = none) const {
return quantity().commodity_amount(commodity);
} }
optional<balance_t> value(const optional<moment_t>& moment = none) const {
return quantity().value(moment);
}
balance_t
strip_annotations(const bool keep_price = amount_t::keep_price,
const bool keep_date = amount_t::keep_date,
const bool keep_tag = amount_t::keep_tag) const {
return quantity().strip_annotations(keep_price, keep_date, keep_tag);
}
void print(std::ostream& out, const int first_width,
const int latter_width = -1) const {
quantity().print(out, first_width, latter_width);
}
balance_pair_t& add(const amount_t& amt,
const optional<amount_t>& a_cost = none) {
#if 0
if (a_cost && ! cost)
cost = quantity;
quantity += amt;
if (cost)
*cost += a_cost ? *a_cost : amt;
#endif
return *this;
}
bool valid() {
return quantity().valid() && (! cost || cost->valid());
}
void in_place_reduce() {
quantity().in_place_reduce();
if (cost) cost->in_place_reduce();
}
balance_pair_t reduce() const {
balance_pair_t temp(*this);
temp.in_place_reduce();
return temp;
}
friend std::ostream& operator<<(std::ostream& out,
const balance_pair_t& bal_pair);
}; };
inline std::ostream& operator<<(std::ostream& out,
const balance_pair_t& bal_pair) {
bal_pair.quantity().print(out, 12);
return out;
}
} // namespace ledger } // namespace ledger
#endif // _BALPAIR_H #endif // _BALPAIR_H