summaryrefslogtreecommitdiff
path: root/src/balance.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/balance.cc')
-rw-r--r--src/balance.cc262
1 files changed, 131 insertions, 131 deletions
diff --git a/src/balance.cc b/src/balance.cc
index e2e7df43..1baad2bf 100644
--- a/src/balance.cc
+++ b/src/balance.cc
@@ -2,6 +2,137 @@
namespace ledger {
+balance_t& balance_t::operator*=(const balance_t& bal)
+{
+ if (realzero() || bal.realzero()) {
+ return *this = amount_t();
+ }
+ else if (bal.amounts.size() == 1) {
+ return *this *= (*bal.amounts.begin()).second;
+ }
+ else if (amounts.size() == 1) {
+ return *this = bal * *this;
+ }
+ else {
+ // Since we would fail with an error at this point otherwise, try
+ // stripping annotations to see if we can come up with a
+ // reasonable result. The user will not notice any annotations
+ // missing (since they are viewing a stripped report anyway), only
+ // that some of their value expression may not see any pricing or
+ // date data because of this operation.
+
+ balance_t temp(bal.strip_annotations());
+ if (temp.amounts.size() == 1)
+ return *this *= temp;
+ temp = strip_annotations();
+ if (temp.amounts.size() == 1)
+ return *this = bal * temp;
+
+ throw_(amount_error, "Cannot multiply two balances: " << temp << " * " << bal);
+ }
+}
+
+balance_t& balance_t::operator*=(const amount_t& amt)
+{
+ if (realzero() || amt.realzero()) {
+ return *this = amount_t();
+ }
+ else if (! amt.commodity()) {
+ // Multiplying by the null commodity causes all amounts to be
+ // increased by the same factor.
+ for (amounts_map::iterator i = amounts.begin();
+ i != amounts.end();
+ i++)
+ (*i).second *= amt;
+ }
+ else if (amounts.size() == 1) {
+ *this = (*amounts.begin()).second * amt;
+ }
+ else {
+ amounts_map::iterator i = amounts.find(&amt.commodity());
+ if (i != amounts.end()) {
+ (*i).second *= amt;
+ } else {
+ // Try stripping annotations before giving an error.
+ balance_t temp(strip_annotations());
+ if (temp.amounts.size() == 1) {
+ return *this = (*temp.amounts.begin()).second * amt;
+ } else {
+ i = temp.amounts.find(&amt.commodity());
+ if (i != temp.amounts.end())
+ return *this = temp * amt;
+ }
+
+ throw_(amount_error, "Attempt to multiply balance by a commodity" <<
+ " not found in that balance: " << temp << " * " << amt);
+ }
+ }
+ return *this;
+}
+
+balance_t& balance_t::operator/=(const balance_t& bal)
+{
+ if (bal.realzero()) {
+ throw_(amount_error, "Divide by zero: " << *this << " / " << bal);
+ }
+ else if (realzero()) {
+ return *this = amount_t();
+ }
+ else if (bal.amounts.size() == 1) {
+ return *this /= (*bal.amounts.begin()).second;
+ }
+ else if (*this == bal) {
+ return *this = amount_t(1L);
+ }
+ else {
+ // Try stripping annotations before giving an error.
+ balance_t temp(bal.strip_annotations());
+ if (temp.amounts.size() == 1)
+ return *this /= temp;
+
+ throw_(amount_error,
+ "Cannot divide two balances: " << temp << " / " << bal);
+ }
+}
+
+balance_t& balance_t::operator/=(const amount_t& amt)
+{
+ if (amt.realzero()) {
+ throw_(amount_error, "Divide by zero: " << *this << " / " << amt);
+ }
+ else if (realzero()) {
+ return *this = amount_t();
+ }
+ else if (! amt.commodity()) {
+ // Dividing by the null commodity causes all amounts to be
+ // decreased by the same factor.
+ for (amounts_map::iterator i = amounts.begin();
+ i != amounts.end();
+ i++)
+ (*i).second /= amt;
+ }
+ else if (amounts.size() == 1 &&
+ (*amounts.begin()).first == &amt.commodity()) {
+ (*amounts.begin()).second /= amt;
+ }
+ else {
+ amounts_map::iterator i = amounts.find(&amt.commodity());
+ if (i != amounts.end()) {
+ (*i).second /= amt;
+ } else {
+ // Try stripping annotations before giving an error.
+ balance_t temp(strip_annotations());
+ if (temp.amounts.size() == 1 &&
+ (*temp.amounts.begin()).first == &amt.commodity())
+ return *this = temp / amt;
+
+ throw_(amount_error, "Attempt to divide balance by a commodity" <<
+ " not found in that balance: " << temp << " * " << amt);
+ }
+ }
+ return *this;
+}
+
amount_t balance_t::amount(const commodity_t& commodity) const
{
if (! commodity) {
@@ -167,137 +298,6 @@ void balance_t::write(std::ostream& out,
}
}
-balance_t& balance_t::operator*=(const balance_t& bal)
-{
- if (realzero() || bal.realzero()) {
- return *this = 0L;
- }
- else if (bal.amounts.size() == 1) {
- return *this *= (*bal.amounts.begin()).second;
- }
- else if (amounts.size() == 1) {
- return *this = bal * *this;
- }
- else {
- // Since we would fail with an error at this point otherwise, try
- // stripping annotations to see if we can come up with a
- // reasonable result. The user will not notice any annotations
- // missing (since they are viewing a stripped report anyway), only
- // that some of their value expression may not see any pricing or
- // date data because of this operation.
-
- balance_t temp(bal.strip_annotations());
- if (temp.amounts.size() == 1)
- return *this *= temp;
- temp = strip_annotations();
- if (temp.amounts.size() == 1)
- return *this = bal * temp;
-
- throw_(amount_error, "Cannot multiply two balances: " << temp << " * " << bal);
- }
-}
-
-balance_t& balance_t::operator*=(const amount_t& amt)
-{
- if (realzero() || amt.realzero()) {
- return *this = 0L;
- }
- else if (! amt.commodity()) {
- // Multiplying by the null commodity causes all amounts to be
- // increased by the same factor.
- for (amounts_map::iterator i = amounts.begin();
- i != amounts.end();
- i++)
- (*i).second *= amt;
- }
- else if (amounts.size() == 1) {
- *this = (*amounts.begin()).second * amt;
- }
- else {
- amounts_map::iterator i = amounts.find(&amt.commodity());
- if (i != amounts.end()) {
- (*i).second *= amt;
- } else {
- // Try stripping annotations before giving an error.
- balance_t temp(strip_annotations());
- if (temp.amounts.size() == 1) {
- return *this = (*temp.amounts.begin()).second * amt;
- } else {
- i = temp.amounts.find(&amt.commodity());
- if (i != temp.amounts.end())
- return *this = temp * amt;
- }
-
- throw_(amount_error, "Attempt to multiply balance by a commodity" <<
- " not found in that balance: " << temp << " * " << amt);
- }
- }
- return *this;
-}
-
-balance_t& balance_t::operator/=(const balance_t& bal)
-{
- if (bal.realzero()) {
- throw_(amount_error, "Divide by zero: " << *this << " / " << bal);
- }
- else if (realzero()) {
- return *this = 0L;
- }
- else if (bal.amounts.size() == 1) {
- return *this /= (*bal.amounts.begin()).second;
- }
- else if (*this == bal) {
- return *this = 1L;
- }
- else {
- // Try stripping annotations before giving an error.
- balance_t temp(bal.strip_annotations());
- if (temp.amounts.size() == 1)
- return *this /= temp;
-
- throw_(amount_error,
- "Cannot divide two balances: " << temp << " / " << bal);
- }
-}
-
-balance_t& balance_t::operator/=(const amount_t& amt)
-{
- if (amt.realzero()) {
- throw_(amount_error, "Divide by zero: " << *this << " / " << amt);
- }
- else if (realzero()) {
- return *this = 0L;
- }
- else if (! amt.commodity()) {
- // Dividing by the null commodity causes all amounts to be
- // decreased by the same factor.
- for (amounts_map::iterator i = amounts.begin();
- i != amounts.end();
- i++)
- (*i).second /= amt;
- }
- else if (amounts.size() == 1 &&
- (*amounts.begin()).first == &amt.commodity()) {
- (*amounts.begin()).second /= amt;
- }
- else {
- amounts_map::iterator i = amounts.find(&amt.commodity());
- if (i != amounts.end()) {
- (*i).second /= amt;
- } else {
- // Try stripping annotations before giving an error.
- balance_t temp(strip_annotations());
- if (temp.amounts.size() == 1 &&
- (*temp.amounts.begin()).first == &amt.commodity())
- return *this = temp / amt;
-
- throw_(amount_error, "Attempt to divide balance by a commodity" <<
- " not found in that balance: " << temp << " * " << amt);
- }
- }
- return *this;
-}
-
#if 0
balance_t::operator amount_t() const
{