diff options
-rw-r--r-- | src/commodity.h | 9 | ||||
-rw-r--r-- | src/pool.cc | 161 | ||||
-rw-r--r-- | src/pool.h | 49 | ||||
-rw-r--r-- | src/py_commodity.cc | 11 | ||||
-rw-r--r-- | src/textual.cc | 11 |
5 files changed, 110 insertions, 131 deletions
diff --git a/src/commodity.h b/src/commodity.h index 524daaab..7934f1ad 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -164,7 +164,6 @@ protected: commodity_pool_t * parent_; optional<string> qualified_symbol; - optional<string> mapping_key_; bool annotated; explicit commodity_t(commodity_pool_t * _parent, @@ -218,13 +217,6 @@ public: return qualified_symbol ? *qualified_symbol : base_symbol(); } - string mapping_key() const { - if (mapping_key_) - return *mapping_key_; - else - return base_symbol(); - } - optional<std::size_t> graph_index() const {; return base->graph_index; } @@ -325,7 +317,6 @@ private: ar & base; ar & parent_; ar & qualified_symbol; - ar & mapping_key_; ar & annotated; } #endif // HAVE_BOOST_SERIALIZATION diff --git a/src/pool.cc b/src/pool.cc index 2c094d47..ca50db2c 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -56,7 +56,7 @@ commodity_t * commodity_pool_t::create(const string& symbol) { shared_ptr<commodity_t::base_t> base_commodity(new commodity_t::base_t(symbol)); - std::auto_ptr<commodity_t> commodity(new commodity_t(this, base_commodity)); + shared_ptr<commodity_t> commodity(new commodity_t(this, base_commodity)); DEBUG("pool.commodities", "Creating base commodity " << symbol); @@ -71,13 +71,23 @@ commodity_t * commodity_pool_t::create(const string& symbol) "Creating commodity '" << commodity->symbol() << "'"); std::pair<commodities_map::iterator, bool> result - = commodities.insert(commodities_map::value_type(commodity->mapping_key(), - commodity.get())); + = commodities.insert(commodities_map::value_type + (commodity->base_symbol(), commodity)); assert(result.second); commodity_price_history.add_commodity(*commodity.get()); - return commodity.release(); + return commodity.get(); +} + +commodity_t * commodity_pool_t::find(const string& symbol) +{ + DEBUG("pool.commodities", "Find commodity " << symbol); + + commodities_map::const_iterator i = commodities.find(symbol); + if (i != commodities.end()) + return (*i).second.get(); + return NULL; } commodity_t * commodity_pool_t::find_or_create(const string& symbol) @@ -88,97 +98,103 @@ commodity_t * commodity_pool_t::find_or_create(const string& symbol) return create(symbol); } -commodity_t * commodity_pool_t::find(const string& symbol) +commodity_t * commodity_pool_t::alias(const string& name, commodity_t& referent) { - DEBUG("pool.commodities", "Find commodity " << symbol); + commodities_map::const_iterator i = commodities.find(referent.symbol()); + assert(i != commodities.end()); - commodities_map::const_iterator i = commodities.find(symbol); - if (i != commodities.end()) - return (*i).second; - return NULL; + std::pair<commodities_map::iterator, bool> result + = commodities.insert(commodities_map::value_type(name, (*i).second)); + assert(result.second); + + return (*result.first).second.get(); } commodity_t * commodity_pool_t::create(const string& symbol, const annotation_t& details) { - commodity_t * new_comm = create(symbol); - if (! new_comm) - return NULL; + DEBUG("pool.commodities", "commodity_pool_t::create[ann] " + << "symbol " << symbol << std::endl << details); if (details) - return find_or_create(*new_comm, details); + return create(*find_or_create(symbol), details); else - return new_comm; + return create(symbol); } -string commodity_pool_t::make_qualified_name(const commodity_t& comm, - const annotation_t& details) +commodity_t * +commodity_pool_t::find(const string& symbol, const annotation_t& details) { - assert(details); - - if (details.price && details.price->sign() < 0) - throw_(amount_error, _("A commodity's price may not be negative")); + DEBUG("pool.commodities", "commodity_pool_t::find[ann] " + << "symbol " << symbol << std::endl << details); - std::ostringstream name; - comm.print(name); - details.print(name, comm.pool().keep_base); - -#if defined(DEBUG_ON) - if (comm.qualified_symbol) - DEBUG("pool.commodities", "make_qualified_name for " - << *comm.qualified_symbol << std::endl << details); -#endif - DEBUG("pool.commodities", "qualified_name is " << name.str()); - - return name.str(); + if (details) { + annotated_commodities_map::const_iterator i = + annotated_commodities.find + (annotated_commodities_map::key_type(symbol, details)); + if (i != annotated_commodities.end()) { + DEBUG("pool.commodities", "commodity_pool_t::find[ann] found " + << "symbol " << (*i).second->symbol() << std::endl + << as_annotated_commodity(*(*i).second.get()).details); + return (*i).second.get(); + } else { + return NULL; + } + } else { + return find(symbol); + } } commodity_t * -commodity_pool_t::find(const string& symbol, const annotation_t& details) +commodity_pool_t::find_or_create(const string& symbol, + const annotation_t& details) { - commodity_t * comm = find(symbol); - if (! comm) - return NULL; + DEBUG("pool.commodities", "commodity_pool_t::find_or_create[ann] " + << "symbol " << symbol << std::endl << details); if (details) { - string name = make_qualified_name(*comm, details); - - if (commodity_t * ann_comm = find(name)) { + if (commodity_t * ann_comm = find(symbol, details)) { assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details); return ann_comm; + } else { + return create(symbol, details); } - return NULL; } else { - return comm; + return find_or_create(symbol); } } commodity_t * -commodity_pool_t::find_or_create(const string& symbol, - const annotation_t& details) +commodity_pool_t::find_or_create(commodity_t& comm, const annotation_t& details) { - commodity_t * comm = find_or_create(symbol); - if (! comm) - return NULL; + DEBUG("pool.commodities", "commodity_pool_t::find_or_create[ann:comm] " + << "symbol " << comm.symbol() << std::endl << details); - if (details) - return find_or_create(*comm, details); - else - return comm; + if (details) { + if (commodity_t * ann_comm = find(comm.symbol(), details)) { + assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details); + return ann_comm; + } else { + return create(comm, details); + } + } else { + return &comm; + } } -commodity_t * +annotated_commodity_t * commodity_pool_t::create(commodity_t& comm, - const annotation_t& details, - const string& mapping_key) + const annotation_t& details) { + DEBUG("pool.commodities", "commodity_pool_t::create[ann:comm] " + << "symbol " << comm.symbol() << std::endl << details); + assert(comm); assert(! comm.has_annotation()); assert(details); - assert(! mapping_key.empty()); - unique_ptr<commodity_t> commodity - (new annotated_commodity_t(&comm, details)); + shared_ptr<annotated_commodity_t> + commodity(new annotated_commodity_t(&comm, details)); comm.add_flags(COMMODITY_SAW_ANNOTATED); if (details.price) { @@ -193,34 +209,15 @@ commodity_pool_t::create(commodity_t& comm, DEBUG("pool.commodities", "Creating annotated commodity " << "symbol " << commodity->symbol() - << " key " << mapping_key << std::endl << details); - - // Add the fully annotated name to the map, so that this symbol may - // quickly be found again. - commodity->mapping_key_ = mapping_key; + << std::endl << details); - std::pair<commodities_map::iterator, bool> result - = commodities.insert(commodities_map::value_type(mapping_key, - commodity.get())); + std::pair<annotated_commodities_map::iterator, bool> result + = annotated_commodities.insert(annotated_commodities_map::value_type + (annotated_commodities_map::key_type + (comm.symbol(), details), commodity)); assert(result.second); - return commodity.release(); -} - -commodity_t * commodity_pool_t::find_or_create(commodity_t& comm, - const annotation_t& details) -{ - assert(comm); - assert(details); - - string name = make_qualified_name(comm, details); - assert(! name.empty()); - - if (commodity_t * ann_comm = find(name)) { - assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details); - return ann_comm; - } - return create(comm, details, name); + return commodity.get(); } void commodity_pool_t::exchange(commodity_t& commodity, @@ -47,6 +47,7 @@ #define _POOL_H #include "history.h" +#include "annotate.h" namespace ledger { @@ -66,51 +67,48 @@ public: * explicitly by calling the create methods of commodity_pool_t, or * implicitly by parsing a commoditized amount. */ - typedef std::map<string, commodity_t *> commodities_map; + typedef std::map<string, shared_ptr<commodity_t> > commodities_map; + typedef std::map<std::pair<string, annotation_t>, + shared_ptr<annotated_commodity_t> > annotated_commodities_map; - commodities_map commodities; - commodity_history_t commodity_price_history; - commodity_t * null_commodity; - commodity_t * default_commodity; + commodities_map commodities; + annotated_commodities_map annotated_commodities; + commodity_history_t commodity_price_history; + commodity_t * null_commodity; + commodity_t * default_commodity; - bool keep_base; // --base - - optional<path> price_db; // --price-db= - long quote_leeway; // --leeway= - bool get_quotes; // --download - - static shared_ptr<commodity_pool_t> current_pool; + bool keep_base; // --base + optional<path> price_db; // --price-db= + long quote_leeway; // --leeway= + bool get_quotes; // --download function<optional<price_point_t> (commodity_t& commodity, const optional<commodity_t&>& in_terms_of)> get_commodity_quote; + static shared_ptr<commodity_pool_t> current_pool; + explicit commodity_pool_t(); virtual ~commodity_pool_t() { TRACE_DTOR(commodity_pool_t); - foreach (commodities_map::value_type& pair, commodities) - checked_delete(pair.second); } - string make_qualified_name(const commodity_t& comm, - const annotation_t& details); - commodity_t * create(const string& symbol); commodity_t * find(const string& name); commodity_t * find_or_create(const string& symbol); + commodity_t * alias(const string& name, commodity_t& referent); - commodity_t * create(const string& symbol, const annotation_t& details); - commodity_t * find(const string& symbol, const annotation_t& details); + commodity_t * create(const string& symbol, + const annotation_t& details); + commodity_t * find(const string& symbol, + const annotation_t& details); commodity_t * find_or_create(const string& symbol, const annotation_t& details); + commodity_t * find_or_create(commodity_t& comm, const annotation_t& details); - commodity_t * create(commodity_t& comm, - const annotation_t& details, - const string& mapping_key); - - commodity_t * find_or_create(commodity_t& comm, - const annotation_t& details); + annotated_commodity_t * create(commodity_t& comm, + const annotation_t& details); // Exchange one commodity for another, while recording the factored price. @@ -144,6 +142,7 @@ private: void serialize(Archive& ar, const unsigned int /* version */) { ar & current_pool; ar & commodities; + ar & annotated_commodities; ar & null_commodity; ar & default_commodity; ar & keep_base; diff --git a/src/py_commodity.cc b/src/py_commodity.cc index b5230850..25e5b918 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -115,7 +115,7 @@ namespace { (string("Could not find commodity ") + symbol).c_str()); throw_error_already_set(); } - return (*i).second; + return (*i).second.get(); } python::list py_pool_keys(commodity_pool_t& pool) { @@ -168,13 +168,15 @@ namespace { py_pool_commodities_values_begin(commodity_pool_t& pool) { return make_transform_iterator (pool.commodities.begin(), - bind(&commodity_pool_t::commodities_map::value_type::second, _1)); + bind(&shared_ptr<commodity_t>::get, + bind(&commodity_pool_t::commodities_map::value_type::second, _1))); } commodities_map_seconds_iterator py_pool_commodities_values_end(commodity_pool_t& pool) { return make_transform_iterator (pool.commodities.end(), - bind(&commodity_pool_t::commodities_map::value_type::second, _1)); + bind(&shared_ptr<commodity_t>::get, + bind(&commodity_pool_t::commodities_map::value_type::second, _1))); } void py_add_price_2(commodity_t& commodity, @@ -267,8 +269,6 @@ void export_commodity() make_getter(&commodity_pool_t::get_commodity_quote), make_setter(&commodity_pool_t::get_commodity_quote)) - .def("make_qualified_name", &commodity_pool_t::make_qualified_name) - .def("create", py_create_1, return_internal_reference<>()) .def("create", py_create_2, return_internal_reference<>()) @@ -359,7 +359,6 @@ void export_commodity() .add_property("base_symbol", &commodity_t::base_symbol) .add_property("symbol", &commodity_t::symbol) - .add_property("mapping_key", &commodity_t::mapping_key) .add_property("name", &commodity_t::name, &commodity_t::set_name) .add_property("note", &commodity_t::note, &commodity_t::set_note) diff --git a/src/textual.cc b/src/textual.cc index 2493dc0d..7bf67347 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1031,17 +1031,10 @@ void instance_t::commodity_directive(char * line) } } -void instance_t::commodity_alias_directive(commodity_t&, string) +void instance_t::commodity_alias_directive(commodity_t& comm, string alias) { -#if 0 trim(alias); - std::pair<commodity_pool_t::commodities_map::iterator, bool> result - = commodity_pool_t::current_pool->commodities.insert - (commodity_pool_t::commodities_map::value_type(alias, &comm)); - if (! result.second) - throw_(parse_error, - _("Cannot use existing commodity name as an alias: %1") << alias); -#endif + commodity_pool_t::current_pool->alias(alias, comm); } void instance_t::commodity_format_directive(commodity_t&, string format) |