diff options
Diffstat (limited to 'src/commodity.cc')
-rw-r--r-- | src/commodity.cc | 152 |
1 files changed, 86 insertions, 66 deletions
diff --git a/src/commodity.cc b/src/commodity.cc index 11a53e96..f8ab523e 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -43,109 +43,75 @@ namespace ledger { -optional<commodity_t::history_t&> -commodity_t::history(const optional<const commodity_t&>& commodity) const +void commodity_t::base_t::history_t::add_price(const datetime_t& date, + const amount_t& price) { - if (base->varied_history) { - const commodity_t * comm = NULL; - if (! commodity) { - if (base->varied_history->size() > 1) - // jww (2008-09-20): Document which option switch to use here - throw_(commodity_error, "Cannot determine history for '" - << *this << "': prices known for multiple commodities (use -?)"); - comm = (*base->varied_history->begin()).first; - } else { - comm = &(*commodity); - } - - history_by_commodity_map::iterator i = base->varied_history->find(comm); - if (i != base->varied_history->end()) - return (*i).second; + history_map::iterator i = prices.find(date); + if (i != prices.end()) { + (*i).second = price; + } else { + std::pair<history_map::iterator, bool> result + = prices.insert(history_map::value_type(date, price)); + assert(result.second); } - return none; } -optional<commodity_t::history_t&> -commodity_t::history(const std::vector<const commodity_t *>& commodities) const +bool commodity_t::base_t::history_t::remove_price(const datetime_t& date) { - // This function differs from the single commodity case avoid in that - // 'commodities' represents a list of preferred valuation commodities. - // If no price can be located in terms of the first commodity, then - // the second is chosen, etc. - - foreach (const commodity_t * commodity, commodities) { - if (optional<commodity_t::history_t&> hist = - history(*commodity)) - return hist; - } - return none; + history_map::size_type n = prices.erase(date); + if (n > 0) + return true; + return false; } -void commodity_t::add_price(const datetime_t& date, const amount_t& price) +void commodity_t::base_t::varied_history_t::add_price(const datetime_t& date, + const amount_t& price) { - if (! base->varied_history) - base->varied_history = varied_history_t(); - optional<history_t&> hist = history(price.commodity()); if (! hist) { std::pair<history_by_commodity_map::iterator, bool> result - = base->varied_history->insert(history_by_commodity_map::value_type - (&price.commodity(), history_t())); + = histories.insert(history_by_commodity_map::value_type + (&price.commodity(), history_t())); assert(result.second); + hist = (*result.first).second; } assert(hist); - - history_map::iterator i = hist->prices.find(date); - if (i != hist->prices.end()) { - (*i).second = price; - } else { - std::pair<history_map::iterator, bool> result - = hist->prices.insert(history_map::value_type(date, price)); - assert(result.second); - } + + hist->add_price(date, price); } -bool commodity_t::remove_price(const datetime_t& date, const commodity_t& comm) +bool commodity_t::base_t::varied_history_t::remove_price(const datetime_t& date, + const commodity_t& comm) { - if (base->varied_history) { - optional<history_t&> hist = history(comm); - if (hist) { - history_map::size_type n = hist->prices.erase(date); - if (n > 0) { - if (hist->prices.empty()) - hist.reset(); - return true; - } - } - } + if (optional<history_t&> hist = history(comm)) + return hist->remove_price(date); return false; } optional<amount_t> -commodity_t::value(const history_t& history, - const optional<datetime_t>& moment) +commodity_t::base_t::history_t::find_price(const optional<datetime_t>& moment) { optional<datetime_t> age; optional<amount_t> price; - if (history.prices.size() == 0) + if (prices.size() == 0) return none; if (! moment) { - history_map::const_reverse_iterator r = history.prices.rbegin(); + history_map::const_reverse_iterator r = prices.rbegin(); age = (*r).first; price = (*r).second; } else { - history_map::const_iterator i = history.prices.lower_bound(*moment); - if (i == history.prices.end()) { - history_map::const_reverse_iterator r = history.prices.rbegin(); + history_map::const_iterator i = prices.lower_bound(*moment); + if (i == prices.end()) { + history_map::const_reverse_iterator r = prices.rbegin(); age = (*r).first; price = (*r).second; } else { age = (*i).first; if (*moment != *age) { - if (i != history.prices.begin()) { + if (i != prices.begin()) { --i; age = (*i).first; price = (*i).second; @@ -171,6 +137,60 @@ commodity_t::value(const history_t& history, return price; } +optional<amount_t> +commodity_t::base_t::varied_history_t::find_price + (const optional<const commodity_t&>& commodity, + const optional<datetime_t>& moment) +{ + return none; +} + +optional<amount_t> +commodity_t::base_t::varied_history_t::find_price + (const std::vector<const commodity_t *>& commodities, + const optional<datetime_t>& moment) +{ + return none; +} + +optional<commodity_t::base_t::history_t&> +commodity_t::base_t::varied_history_t::history + (const optional<const commodity_t&>& commodity) +{ + const commodity_t * comm = NULL; + if (! commodity) { + if (histories.size() > 1) + // jww (2008-09-20): Document which option switch to use here + throw_(commodity_error, + "Cannot determine price history: prices known for multiple commodities (use -?)"); + comm = (*histories.begin()).first; + } else { + comm = &(*commodity); + } + + history_by_commodity_map::iterator i = histories.find(comm); + if (i != histories.end()) + return (*i).second; + + return none; +} + +optional<commodity_t::history_t&> +commodity_t::base_t::varied_history_t::history + (const std::vector<const commodity_t *>& commodities) +{ + // This function differs from the single commodity case avoid in that + // 'commodities' represents a list of preferred valuation commodities. + // If no price can be located in terms of the first commodity, then + // the second is chosen, etc. + + foreach (const commodity_t * commodity, commodities) { + if (optional<history_t&> hist = history(*commodity)) + return hist; + } + return none; +} + void commodity_t::exchange(commodity_t& commodity, const amount_t& per_unit_cost, const datetime_t& moment) |