From e2afc783db0dff1927b00dc506390353d9e3bbd2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Feb 2012 22:32:23 -0600 Subject: Increased file copyrights to 2012 --- src/pool.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pool.cc') diff --git a/src/pool.cc b/src/pool.cc index 65edbd6a..ba408fc5 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are -- cgit v1.2.3 From 48ab6ad1dbab100bb8abd87029a0ca5bc501a3db Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 4 Mar 2012 03:35:06 -0600 Subject: Switched to using Boost.Graph for commodity pricing --- src/commodity.cc | 442 +++++------------------------------------------------- src/commodity.h | 114 +------------- src/filters.cc | 3 + src/history.cc | 196 ++++++++++++++++++++++++ src/history.h | 184 +++++++++++++++++++++++ src/iterators.cc | 3 + src/pool.cc | 88 ++--------- src/pool.h | 23 ++- src/report.cc | 10 +- src/system.hh.in | 15 ++ tools/Makefile.am | 2 + 11 files changed, 476 insertions(+), 604 deletions(-) create mode 100644 src/history.cc create mode 100644 src/history.h (limited to 'src/pool.cc') diff --git a/src/commodity.cc b/src/commodity.cc index 643d0d1e..c0ccae11 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -40,410 +40,68 @@ namespace ledger { bool commodity_t::decimal_comma_by_default = false; -void commodity_t::history_t::add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive) +void commodity_t::add_price(const datetime_t& date, const amount_t& price, + const bool reflexive) { - DEBUG("commodity.prices.add", "add_price to " << source - << (reflexive ? " (secondary)" : " (primary)") - << " : " << date << ", " << price); + if (! reflexive) + add_flags(COMMODITY_PRIMARY); + pool().commodity_price_history.add_price(*this, date, price); - history_map::iterator i = prices.find(date); - if (i != prices.end()) { - (*i).second = price; - } else { - std::pair result - = prices.insert(history_map::value_type(date, price)); - assert(result.second); - } - - if (reflexive) { - amount_t inverse = price.inverted(); - inverse.set_commodity(const_cast(source)); - price.commodity().add_price(date, inverse, false); - } else { - DEBUG("commodity.prices.add", - "marking commodity " << source.symbol() << " as primary"); - source.add_flags(COMMODITY_PRIMARY); - } -} - -bool commodity_t::history_t::remove_price(const datetime_t& date) -{ - DEBUG("commodity.prices.add", "remove_price: " << date); - - history_map::size_type n = prices.erase(date); - if (n > 0) - return true; - return false; -} - -void commodity_t::varied_history_t:: - add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive) -{ - optional hist = history(price.commodity()); - if (! hist) { - std::pair result - = histories.insert(history_by_commodity_map::value_type - (&price.commodity(), history_t())); - assert(result.second); - - hist = (*result.first).second; - } - assert(hist); - - hist->add_price(source, date, price, reflexive); + DEBUG("commodity.prices.find", "Price added, clearing price_map"); + base->price_map.clear(); // a price was added, invalid the map } -bool commodity_t::varied_history_t::remove_price(const datetime_t& date, - commodity_t& comm) +void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) { - DEBUG("commodity.prices.add", "varied_remove_price: " << date << ", " << comm); + pool().commodity_price_history.remove_price(*this, commodity, date); - if (optional hist = history(comm)) - return hist->remove_price(date); - return false; + DEBUG("commodity.prices.find", "Price removed, clearing price_map"); + base->price_map.clear(); // a price was added, invalid the map } optional -commodity_t::history_t::find_price(const optional& moment, - const optional& oldest -#if defined(DEBUG_ON) - , const int indent -#endif - ) const +commodity_t::find_price(const optional& target = none, + const optional& moment = none, + const optional& oldest = none) const { - price_point_t point; - bool found = false; - -#if defined(DEBUG_ON) -#define DEBUG_INDENT(cat, indent) \ - do { \ - if (SHOW_DEBUG(cat)) \ - for (int _i = 0; _i < indent; _i++) \ - ledger::_log_buffer << " "; \ - } while (false) -#else -#define DEBUG_INDENT(cat, indent) -#endif - -#if defined(DEBUG_ON) + pair = base_t::time_and_commodity_t + (base_t::optional_time_pair_t(moment, oldest), + commodity ? &(*commodity) : NULL); DEBUG_INDENT("commodity.prices.find", indent); - if (moment) - DEBUG("commodity.prices.find", "find price nearest before or on: " << *moment); - else - DEBUG("commodity.prices.find", "find any price"); + DEBUG("commodity.prices.find", "looking for memoized args: " + << (moment ? format_datetime(*moment) : "NONE") << ", " + << (oldest ? format_datetime(*oldest) : "NONE") << ", " + << (commodity ? commodity->symbol() : "NONE")); - if (oldest) { + base_t::memoized_price_map::iterator i = base->price_map.find(*pair); + if (i != base->price_map.end()) { DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "but no older than: " << *oldest); - } -#endif - - if (prices.size() == 0) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "there are no prices in this history"); - return none; + DEBUG("commodity.prices.find", "found! returning: " + << ((*i).second ? (*i).second->price : amount_t(0L))); + return (*i).second; } - if (! moment) { - history_map::const_reverse_iterator r = prices.rbegin(); - point.when = (*r).first; - point.price = (*r).second; - found = true; - - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "using most recent price"); - } else { - history_map::const_iterator i = prices.upper_bound(*moment); - if (i == prices.end()) { - history_map::const_reverse_iterator r = prices.rbegin(); - point.when = (*r).first; - point.price = (*r).second; - found = true; + optional point = + pool().commodity_price_history.find_price + (*this, commodity, moment ? *moment : epoch, oldest); + if (pair) { + if (base->price_map.size() > base_t::max_price_map_size) { DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "using last price"); - } else { - point.when = (*i).first; - if (*moment < point.when) { - if (i != prices.begin()) { - --i; - point.when = (*i).first; - point.price = (*i).second; - found = true; - } - } else { - point.price = (*i).second; - found = true; - } - - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "using found price"); - } - } - - if (! found) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "could not find a price"); - return none; - } - else if (moment && point.when > *moment) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "price is too young "); - return none; - } - else if (oldest && point.when < *oldest) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "price is too old "); - return none; - } - else { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", - "returning price: " << point.when << ", " << point.price); - return point; - } -} - -optional -commodity_t::varied_history_t::find_price(const commodity_t& source, - const optional& commodity, - const optional& moment, - const optional& oldest -#if defined(DEBUG_ON) - , const int indent -#endif - ) const -{ - optional point; - optional limit = oldest; - -#if defined(VERIFY_ON) - if (commodity) { - VERIFY(source != *commodity); - VERIFY(! commodity->has_annotation()); - VERIFY(source.referent() != commodity->referent()); - } -#endif - -#if defined(DEBUG_ON) - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "varied_find_price for: " << source); - - DEBUG_INDENT("commodity.prices.find", indent); - if (commodity) - DEBUG("commodity.prices.find", "looking for: commodity '" << *commodity << "'"); - else - DEBUG("commodity.prices.find", "looking for: any commodity"); - - if (moment) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "time index: " << *moment); - } - - if (oldest) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "only consider prices younger than: " << *oldest); - } -#endif - - // Either we couldn't find a history for the target commodity, or we - // couldn't find a price. In either case, search all histories known - // to this commodity for a price which we can calculate in terms of - // the goal commodity. - price_point_t best; - bool found = false; - - foreach (const history_by_commodity_map::value_type& hist, histories) { - commodity_t& comm(*hist.first); - if (comm == source) - continue; - - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", - "searching for price via commodity '" << comm << "'"); - - point = hist.second.find_price(moment, limit -#if defined(DEBUG_ON) - , indent + 2 -#endif - ); - assert(! point || point->price.commodity() == comm); - - if (point) { - optional xlat; - - if (commodity && comm != *commodity) { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "looking for translation price"); - - xlat = comm.find_price(commodity, moment, limit, true -#if defined(DEBUG_ON) - , indent + 2 -#endif - ); - if (xlat) { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "found translated price " - << xlat->price << " from " << xlat->when); - - point->price = xlat->price * point->price; - if (xlat->when < point->when) { - point->when = xlat->when; - - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", - "adjusting date of result back to " << point->when); - } - } else { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "saw no translated price there"); - continue; - } - } - - assert(! commodity || point->price.commodity() == *commodity); - - DEBUG_INDENT("commodity.prices.find", indent + 1); DEBUG("commodity.prices.find", - "saw a price there: " << point->price << " from " << point->when); - - if (! limit || point->when > *limit) { - limit = point->when; - best = *point; - found = true; + "price map has grown too large, clearing it by half"); - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", - "search limit adjusted to " << *limit); - } - } else { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "saw no price there"); + for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) + base->price_map.erase(base->price_map.begin()); } - } - if (found) { DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.download", - "found price " << best.price << " from " << best.when); - return best; - } - return none; -} - -optional -commodity_t::varied_history_t::history(const optional& commodity) -{ - commodity_t * comm = NULL; - if (! commodity) { - if (histories.size() > 1) - return none; - 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::find_price(const optional& commodity, - const optional& moment, - const optional& oldest, - const bool nested -#if defined(DEBUG_ON) - , const int indent -#endif - ) const -{ - if (! has_flags(COMMODITY_WALKED) && base->varied_history) { - optional pair; -#if defined(VERIFY_ON) - optional checkpoint; - bool found = false; -#endif - - if (! nested) { - pair = base_t::time_and_commodity_t - (base_t::optional_time_pair_t(moment, oldest), - commodity ? &(*commodity) : NULL); - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "looking for memoized args: " - << (moment ? format_datetime(*moment) : "NONE") << ", " - << (oldest ? format_datetime(*oldest) : "NONE") << ", " - << (commodity ? commodity->symbol() : "NONE")); - - base_t::memoized_price_map::iterator i = base->price_map.find(*pair); - if (i != base->price_map.end()) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "found! returning: " - << ((*i).second ? (*i).second->price : amount_t(0L))); -#if defined(VERIFY_ON) - IF_VERIFY() { - found = true; - checkpoint = (*i).second; - } else -#endif // defined(VERIFY_ON) - return (*i).second; - } - } - - optional point; - - const_cast(*this).add_flags(COMMODITY_WALKED); - try { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "manually finding price..."); - - point = base->varied_history->find_price(*this, commodity, - moment, oldest -#if defined(DEBUG_ON) - , indent -#endif - ); - } - catch (...) { - const_cast(*this).drop_flags(COMMODITY_WALKED); - throw; - } - const_cast(*this).drop_flags(COMMODITY_WALKED); - -#if defined(VERIFY_ON) - if (DO_VERIFY() && found) { - VERIFY(checkpoint == point); - return checkpoint; - } -#endif // defined(VERIFY_ON) - - if (! nested && pair) { - if (base->price_map.size() > base_t::max_price_map_size) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", - "price map has grown too large, clearing it by half"); - - for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) - base->price_map.erase(base->price_map.begin()); - } - - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", - "remembered: " << (point ? point->price : amount_t(0L))); - base->price_map.insert - (base_t::memoized_price_map::value_type(*pair, point)); - } - return point; + DEBUG("commodity.prices.find", + "remembered: " << (point ? point->price : amount_t(0L))); + base->price_map.insert + (base_t::memoized_price_map::value_type(*pair, point)); } - return none; + return point; } optional @@ -767,28 +425,6 @@ void to_xml(std::ostream& out, const commodity_t& comm, if (commodity_details) { if (comm.has_annotation()) to_xml(out, as_annotated_commodity(comm).details); - - if (comm.varied_history()) { - push_xml y(out, "varied-history"); - - foreach (const commodity_t::history_by_commodity_map::value_type& pair, - comm.varied_history()->histories) { - { - push_xml z(out, "symbol"); - out << y.guard(pair.first->symbol()); - } - { - push_xml z(out, "history"); - - foreach (const commodity_t::history_map::value_type& inner_pair, - pair.second.prices) { - push_xml w(out, "price-point"); - to_xml(out, inner_pair.first); - to_xml(out, inner_pair.second); - } - } - } - } } } diff --git a/src/commodity.h b/src/commodity.h index 68f788e3..1505fe24 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -85,78 +85,6 @@ class commodity_t : public delegates_flags, public equality_comparable1 { -public: - typedef std::map history_map; - - struct history_t - { - history_map prices; - - void add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive = true); - bool remove_price(const datetime_t& date); - - optional - find_price(const optional& moment = none, - const optional& oldest = none -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const; - -#if defined(HAVE_BOOST_SERIALIZATION) - private: - /** Serialization. */ - - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int /* version */) { - ar & prices; - } -#endif // HAVE_BOOST_SERIALIZATION - }; - - typedef std::map history_by_commodity_map; - - struct varied_history_t - { - history_by_commodity_map histories; - - void add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive = true); - bool remove_price(const datetime_t& date, commodity_t& commodity); - - optional - find_price(const commodity_t& source, - const optional& commodity = none, - const optional& moment = none, - const optional& oldest = none -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const; - - optional - history(const optional& commodity = none); - -#if defined(HAVE_BOOST_SERIALIZATION) - private: - /** Serialization. */ - - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int /* version */) { - ar & histories; - } -#endif // HAVE_BOOST_SERIALIZATION - }; - protected: friend class commodity_pool_t; friend class annotated_commodity_t; @@ -182,7 +110,6 @@ protected: amount_t::precision_t precision; optional name; optional note; - optional varied_history; optional smaller; optional larger; @@ -228,7 +155,6 @@ protected: ar & precision; ar & name; ar & note; - ar & varied_history; ar & smaller; ar & larger; } @@ -335,48 +261,14 @@ public: base->larger = arg; } - optional varied_history() { - if (base->varied_history) - return *base->varied_history; - return none; - } - optional varied_history() const { - if (base->varied_history) - return *base->varied_history; - return none; - } - - optional history(const optional& commodity); - - // These methods provide a transparent pass-through to the underlying - // base->varied_history object. - void add_price(const datetime_t& date, const amount_t& price, - const bool reflexive = true) { - if (! base->varied_history) - base->varied_history = varied_history_t(); - base->varied_history->add_price(*this, date, price, reflexive); - DEBUG("commodity.prices.find", "Price added, clearing price_map"); - base->price_map.clear(); // a price was added, invalid the map - } - bool remove_price(const datetime_t& date, commodity_t& commodity) { - if (base->varied_history) { - base->varied_history->remove_price(date, commodity); - DEBUG("commodity.prices.find", "Price removed, clearing price_map"); - base->price_map.clear(); // a price was added, invalid the map - } - return false; - } + const bool reflexive = true); + void remove_price(const datetime_t& date, commodity_t& commodity); optional find_price(const optional& commodity = none, const optional& moment = none, - const optional& oldest = none, - const bool nested = false -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const; + const optional& oldest = none) const; optional check_for_updated_price(const optional& point, diff --git a/src/filters.cc b/src/filters.cc index 72ce9c32..0c6222d7 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -754,6 +754,8 @@ void changed_value_posts::output_intermediate_prices(post_t& post, // fall through... case value_t::BALANCE: { +#if 0 + // jww (2012-03-04): TODO commodity_t::history_map all_prices; foreach (const balance_t::amounts_map::value_type& amt_comm, @@ -797,6 +799,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post, output_revaluation(post, price.first); last_total = repriced_total; } +#endif break; } default: diff --git a/src/history.cc b/src/history.cc new file mode 100644 index 00000000..44d19f5a --- /dev/null +++ b/src/history.cc @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "history.h" + +template +struct f_max : public std::binary_function { + T operator()(const T& x, const T& y) const { + return std::max(x, y); + } +}; + +namespace ledger { + +void commodity_history_t::add_commodity(const commodity_t& comm) +{ + const vertex_descriptor vert = add_vertex(&comm, price_graph); + put(indexmap, vert, reinterpret_cast(&comm)); +} + +void commodity_history_t::add_price(const commodity_t& source, + const datetime_t& when, + const amount_t& price) +{ + vertex_descriptor sv = + vertex(reinterpret_cast(&source), price_graph); + vertex_descriptor tv = + vertex(reinterpret_cast(&price.commodity()), price_graph); + + std::pair e1 = add_edge(sv, tv, 0, price_graph); + price_map_t& prices(get(ratiomap, e1.first)); + + std::pair result = + prices.insert(price_map_t::value_type(when, price)); + if (! result.second) { + // There is already an entry for this moment, so update it + (*result.first).second = price; + } +} + +void commodity_history_t::remove_price(const commodity_t& source, + const commodity_t& target, + const datetime_t& date) +{ + vertex_descriptor sv = + vertex(reinterpret_cast(&source), price_graph); + vertex_descriptor tv = + vertex(reinterpret_cast(&target), price_graph); + + std::pair e1 = add_edge(sv, tv, 0, price_graph); + price_map_t& prices(get(ratiomap, e1.first)); + + // jww (2012-03-04): If it fails, should we give a warning? + prices.erase(date); +} + +optional +commodity_history_t::find_price(const commodity_t& source, + const datetime_t& moment, + const optional& oldest, + const optional& target) +{ + vertex_descriptor sv = + vertex(reinterpret_cast(&source), price_graph); + vertex_descriptor tv = + vertex(reinterpret_cast(&*target), price_graph); + + // Filter out edges which came into being after the reference time + + FGraph fg(price_graph, + recent_edge_weight + (get(edge_weight, price_graph), pricemap, ratiomap, + moment, oldest)); + + std::vector predecessors(num_vertices(fg)); + std::vector distances(num_vertices(fg)); + + PredecessorMap predecessorMap(&predecessors[0]); + DistanceMap distanceMap(&distances[0]); + + dijkstra_shortest_paths(fg, /* start= */ sv, + predecessor_map(predecessorMap) + .distance_map(distanceMap) + .distance_combine(f_max())); + + // Extract the shortest path and performance the calculations + datetime_t least_recent = moment; + amount_t price; + + vertex_descriptor v = tv; + for (vertex_descriptor u = predecessorMap[v]; + u != v; + v = u, u = predecessorMap[v]) + { + std::pair edgePair = edge(u, v, fg); + Graph::edge_descriptor edge = edgePair.first; + + const price_point_t& point(get(pricemap, edge)); + + if (price.is_null()) { + least_recent = point.when; + price = point.price; + } + else if (point.when < least_recent) + least_recent = point.when; + + // jww (2012-03-04): TODO + //price *= point.price; + } + + return price_point_t(least_recent, price); +} + +#if 0 + print_vertices(fg, f_commmap); + print_edges(fg, f_commmap); + print_graph(fg, f_commmap); + + graph_traits::vertex_iterator f_vi, f_vend; + for(tie(f_vi, f_vend) = vertices(fg); f_vi != f_vend; ++f_vi) + std::cerr << get(f_commmap, *f_vi) << " is in the filtered graph" + << std::endl; + + for (tie(f_vi, f_vend) = vertices(fg); f_vi != f_vend; ++f_vi) { + std::cerr << "distance(" << get(f_commmap, *f_vi) << ") = " + << distanceMap[*f_vi] << ", "; + std::cerr << "parent(" << get(f_commmap, *f_vi) << ") = " + << get(f_commmap, predecessorMap[*f_vi]) + << std::endl; + } + + // Write shortest path + FCommMap f_commmap = get(vertex_comm, fg); + + std::cerr << "Shortest path from CAD to EUR:" << std::endl; + for (PathType::reverse_iterator pathIterator = path.rbegin(); + pathIterator != path.rend(); + ++pathIterator) + { + std::cerr << get(f_commmap, source(*pathIterator, fg)) + << " -> " << get(f_commmap, target(*pathIterator, fg)) + << " = " << get(edge_weight, fg, *pathIterator) + << std::endl; + } + std::cerr << std::endl; + + std::cerr << "Distance: " << distanceMap[vd4] << std::endl; +#endif + +#if 0 + #include + + // Writing graph to file + { + std::ofstream f("test.dot"); + + dynamic_properties p; + p.property("label", get(edge_weight, g)); + p.property("weight", get(edge_weight, g)); + p.property("node_id", get(vertex_comm, g)); + write_graphviz(f,g,p); + f.close(); + } +#endif + +} // namespace ledger diff --git a/src/history.h b/src/history.h new file mode 100644 index 00000000..486602dd --- /dev/null +++ b/src/history.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @addtogroup math + */ + +/** + * @file history.h + * @author John Wiegley + * + * @ingroup math + * + * @brief Types for managing commodity historys + * + * Long. + */ +#ifndef _HISTORY_H +#define _HISTORY_H + +#include "amount.h" +#include "commodity.h" + +namespace boost { + enum edge_price_point_t { edge_price_point }; + enum edge_price_ratio_t { edge_price_ratio }; + BOOST_INSTALL_PROPERTY(edge, price_point); + BOOST_INSTALL_PROPERTY(edge, price_ratio); +} + +namespace ledger { + +typedef std::map price_map_t; + +template +class recent_edge_weight +{ +public: + EdgeWeightMap weight; + PricePointMap price_point; + PriceRatioMap ratios; + + datetime_t reftime; + optional oldest; + + recent_edge_weight() { } + recent_edge_weight(EdgeWeightMap _weight, + PricePointMap _price_point, + PriceRatioMap _ratios, + datetime_t _reftime, + const optional& _oldest = none) + : weight(_weight), price_point(_price_point), ratios(_ratios), + reftime(_reftime), oldest(_oldest) { } + + template + bool operator()(const Edge& e) const { + const price_map_t& prices(get(ratios, e)); + price_map_t::const_iterator low = prices.upper_bound(reftime); + if (prices.empty() || + (low != prices.end() && low == prices.begin())) { + return false; + } else { + if (low == prices.end()) + --low; + assert(((*low).first <= reftime)); + + if (oldest && (*low).first <= *oldest) + return false; + + long secs = (reftime - (*low).first).total_seconds(); + assert(secs >= 0); + + put(weight, e, secs); + put(price_point, e, price_point_t((*low).first, (*low).second)); + + return true; + } + } +}; + +class commodity_history_t : public noncopyable +{ +public: + typedef adjacency_list + >, + + // All edges are weights computed as the absolute difference between + // the reference time of a search and a known price point. A + // filtered_graph is used to select the recent price point to the + // reference time before performing the search. + property > >, + + // Graph itself has a std::string name + property + > Graph; + + Graph price_graph; + + typedef graph_traits::vertex_descriptor vertex_descriptor; + typedef graph_traits::edge_descriptor edge_descriptor; + + typedef property_map::type IndexMap; + typedef property_map::type NameMap; + + typedef iterator_property_map PredecessorMap; + typedef iterator_property_map DistanceMap; + + typedef property_map::type EdgeWeightMap; + typedef property_map::type PricePointMap; + typedef property_map::type PriceRatioMap; + + IndexMap indexmap; + PricePointMap pricemap; + PriceRatioMap ratiomap; + + typedef filtered_graph > FGraph; + typedef property_map::type FNameMap; + + commodity_history_t() + : indexmap(get(vertex_index, price_graph)), + pricemap(get(edge_price_point, price_graph)), + ratiomap(get(edge_price_ratio, price_graph)) {} + + void add_commodity(const commodity_t& comm); + + void add_price(const commodity_t& source, + const datetime_t& when, + const amount_t& price); + void remove_price(const commodity_t& source, + const commodity_t& target, + const datetime_t& date); + + optional + find_price(const commodity_t& source, + const datetime_t& moment, + const optional& oldest = none, + const optional& commodity = none); +}; + +} // namespace ledger + +#endif // _HISTORY_H diff --git a/src/iterators.cc b/src/iterators.cc index 72e0481c..b7ed011e 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -90,6 +90,8 @@ void posts_commodities_iterator::reset(journal_t& journal) std::map xacts_by_commodity; +#if 0 + // jww (2012-03-04): TODO foreach (commodity_t * comm, commodities) { if (optional history = comm->varied_history()) { @@ -136,6 +138,7 @@ void posts_commodities_iterator::reset(journal_t& journal) } } } +#endif xacts.reset(xact_temps.begin(), xact_temps.end()); diff --git a/src/pool.cc b/src/pool.cc index ba408fc5..67cfe3d1 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -35,6 +35,7 @@ #include "commodity.h" #include "annotate.h" #include "pool.h" +#include "history.h" #include "quotes.h" namespace ledger { @@ -74,15 +75,15 @@ commodity_t * commodity_pool_t::create(const string& symbol) commodity.get())); assert(result.second); + commodity_price_history.add_commodity(*commodity.get()); + return commodity.release(); } commodity_t * commodity_pool_t::find_or_create(const string& symbol) { DEBUG("pool.commodities", "Find-or-create commodity " << symbol); - - commodity_t * commodity = find(symbol); - if (commodity) + if (commodity_t * commodity = find(symbol)) return commodity; return create(symbol); } @@ -222,6 +223,15 @@ commodity_t * commodity_pool_t::find_or_create(commodity_t& comm, return create(comm, details, name); } +optional +commodity_pool_t::find_price(const commodity_t& source, + const optional& commodity, + const optional& moment, + const optional& oldest) const +{ + return commodity_price_history.find_price(source, commodity, moment, oldest); +} + void commodity_pool_t::exchange(commodity_t& commodity, const amount_t& per_unit_cost, const datetime_t& moment) @@ -382,76 +392,4 @@ commodity_pool_t::parse_price_expression(const std::string& str, return NULL; } -void commodity_pool_t::print_pricemap(std::ostream& out, - const keep_details_t& keep, - const optional& moment) -{ - typedef std::map comm_map_t; - - comm_map_t comm_map; - - foreach (const commodities_map::value_type& comm_pair, commodities) { - commodity_t * comm(&comm_pair.second->strip_annotations(keep)); - comm_map.insert(comm_map_t::value_type(comm, NULL)); - } - - out << "digraph commodities {\n"; - - foreach (const comm_map_t::value_type& comm_pair, comm_map) { - commodity_t * comm(comm_pair.first); - if (comm->has_flags(COMMODITY_BUILTIN)) - continue; - - out << " "; - if (commodity_t::symbol_needs_quotes(comm->symbol())) - out << comm->symbol() << ";\n"; - else - out << "\"" << comm->symbol() << "\";\n"; - - if (! comm->has_flags(COMMODITY_NOMARKET) && - (! commodity_pool_t::current_pool->default_commodity || - comm != commodity_pool_t::current_pool->default_commodity)) { - if (optional vhist = - comm->varied_history()) { - foreach (const commodity_t::history_by_commodity_map::value_type& pair, - vhist->histories) { - datetime_t most_recent; - amount_t most_recent_amt; - foreach (const commodity_t::history_map::value_type& inner_pair, - pair.second.prices) { - if ((most_recent.is_not_a_date_time() || - inner_pair.first > most_recent) && - (! moment || inner_pair.first <= moment)) { - most_recent = inner_pair.first; - most_recent_amt = inner_pair.second; - } - } - - if (! most_recent.is_not_a_date_time()) { - out << " "; - if (commodity_t::symbol_needs_quotes(comm->symbol())) - out << comm->symbol(); - else - out << "\"" << comm->symbol() << "\""; - - out << " -> "; - - if (commodity_t::symbol_needs_quotes(pair.first->symbol())) - out << pair.first->symbol(); - else - out << "\"" << pair.first->symbol() << "\""; - - out << " [label=\"" - << most_recent_amt.number() << "\\n" - << format_date(most_recent.date(), FMT_WRITTEN) - << "\" fontcolor=\"#008e28\"];\n"; - } - } - } - } - } - - out << "}\n"; -} - } // namespace ledger diff --git a/src/pool.h b/src/pool.h index 87b315f9..709f5c71 100644 --- a/src/pool.h +++ b/src/pool.h @@ -46,6 +46,8 @@ #ifndef _POOL_H #define _POOL_H +#include "history.h" + namespace ledger { struct cost_breakdown_t @@ -66,15 +68,16 @@ public: */ typedef std::map commodities_map; - commodities_map commodities; - commodity_t * null_commodity; - commodity_t * default_commodity; + commodities_map commodities; + commodity_history_t commodity_price_history; + commodity_t * null_commodity; + commodity_t * default_commodity; - bool keep_base; // --base + bool keep_base; // --base - optional price_db; // --price-db= - long quote_leeway; // --leeway= - bool get_quotes; // --download + optional price_db; // --price-db= + long quote_leeway; // --leeway= + bool get_quotes; // --download static shared_ptr current_pool; @@ -131,12 +134,6 @@ public: const bool add_prices = true, const optional& moment = none); - // Output the commodity price map for a given date as a DOT file - - void print_pricemap(std::ostream& out, - const keep_details_t& keep, - const optional& moment = none); - #if defined(HAVE_BOOST_SERIALIZATION) private: /** Serialization. */ diff --git a/src/report.cc b/src/report.cc index 647df3d2..689028d0 100644 --- a/src/report.cc +++ b/src/report.cc @@ -878,11 +878,12 @@ value_t report_t::echo_command(call_scope_t& args) value_t report_t::pricemap_command(call_scope_t& args) { std::ostream& out(output_stream); - +#if 0 + // jww (2012-03-04): TODO commodity_pool_t::current_pool->print_pricemap (out, what_to_keep(), args.has(0) ? optional(datetime_t(parse_date(args.get(0)))) : none); - +#endif return true; } @@ -913,6 +914,11 @@ option_t * report_t::lookup_option(const char * p) case 'G': OPT_CH(gain); break; +#if 0 + case 'H': + OPT_CH(historical); + break; +#endif case 'I': OPT_CH(price); break; diff --git a/src/system.hh.in b/src/system.hh.in index 3aa60f71..8f684486 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -138,37 +138,52 @@ typedef std::ostream::pos_type ostream_pos_type; #include #include #include + #include #include #include + #include #include #include #include #include + #if !(defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__) #include #endif #include + +#include +#include +#include +#include + #include + #include #include #define BOOST_IOSTREAMS_USE_DEPRECATED 1 #include + #include #include + #include #include #include #include + #include #include #include #include + #if defined(HAVE_BOOST_REGEX_UNICODE) #include #else #include + #endif // HAVE_BOOST_REGEX_UNICODE #include #include diff --git a/tools/Makefile.am b/tools/Makefile.am index 09021b1f..671db294 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -30,6 +30,7 @@ libledger_util_la_LDFLAGS = -release $(LIBVERSION) libledger_math_la_SOURCES = \ src/balance.cc \ src/quotes.cc \ + src/history.cc \ src/pool.cc \ src/annotate.cc \ src/commodity.cc \ @@ -104,6 +105,7 @@ pkginclude_HEADERS = \ src/amount.h \ src/commodity.h \ src/annotate.h \ + src/history.h \ src/pool.h \ src/quotes.h \ src/balance.h \ -- cgit v1.2.3 From e9108783122ae4d775046ced646b14552f1e184d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 4 Mar 2012 04:03:32 -0600 Subject: Changes to get all the code to compile --- src/commodity.cc | 54 ++++++++++++++++++++++++++++++++---------------------- src/commodity.h | 24 +++++++++++++++--------- src/history.cc | 31 ++++++++++++++++--------------- src/history.h | 2 +- src/pool.cc | 9 --------- 5 files changed, 64 insertions(+), 56 deletions(-) (limited to 'src/pool.cc') diff --git a/src/commodity.cc b/src/commodity.cc index c0ccae11..a01847c5 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -60,42 +60,52 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) } optional -commodity_t::find_price(const optional& target = none, - const optional& moment = none, - const optional& oldest = none) const +commodity_t::find_price(const optional& commodity, + const optional& moment, + const optional& oldest) const { - pair = base_t::time_and_commodity_t - (base_t::optional_time_pair_t(moment, oldest), - commodity ? &(*commodity) : NULL); - DEBUG_INDENT("commodity.prices.find", indent); + optional pair = + base_t::time_and_commodity_t(base_t::optional_time_pair_t(moment, oldest), + commodity ? &(*commodity) : NULL); + DEBUG("commodity.prices.find", "looking for memoized args: " - << (moment ? format_datetime(*moment) : "NONE") << ", " - << (oldest ? format_datetime(*oldest) : "NONE") << ", " - << (commodity ? commodity->symbol() : "NONE")); - - base_t::memoized_price_map::iterator i = base->price_map.find(*pair); - if (i != base->price_map.end()) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "found! returning: " - << ((*i).second ? (*i).second->price : amount_t(0L))); - return (*i).second; + << (moment ? format_datetime(*moment) : "NONE") << ", " + << (oldest ? format_datetime(*oldest) : "NONE") << ", " + << (commodity ? commodity->symbol() : "NONE")); + { + base_t::memoized_price_map::iterator i = base->price_map.find(*pair); + if (i != base->price_map.end()) { + DEBUG("commodity.prices.find", "found! returning: " + << ((*i).second ? (*i).second->price : amount_t(0L))); + return (*i).second; + } } + datetime_t when; + if (moment) + when = *moment; + else if (epoch) + when = *epoch; + else + when = CURRENT_TIME(); + + optional target; + if (commodity) + target = commodity; + else if (pool().default_commodity) + target = *pool().default_commodity; + optional point = - pool().commodity_price_history.find_price - (*this, commodity, moment ? *moment : epoch, oldest); + pool().commodity_price_history.find_price(*this, when, oldest, target); if (pair) { if (base->price_map.size() > base_t::max_price_map_size) { - DEBUG_INDENT("commodity.prices.find", indent); DEBUG("commodity.prices.find", "price map has grown too large, clearing it by half"); - for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) base->price_map.erase(base->price_map.begin()); } - DEBUG_INDENT("commodity.prices.find", indent); DEBUG("commodity.prices.find", "remembered: " << (point ? point->price : amount_t(0L))); base->price_map.insert diff --git a/src/commodity.h b/src/commodity.h index 1505fe24..a1ad0147 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -106,12 +106,13 @@ protected: #define COMMODITY_SAW_ANN_PRICE_FLOAT 0x400 #define COMMODITY_SAW_ANN_PRICE_FIXATED 0x800 - string symbol; - amount_t::precision_t precision; - optional name; - optional note; - optional smaller; - optional larger; + string symbol; + optional graph_index; + amount_t::precision_t precision; + optional name; + optional note; + optional smaller; + optional larger; typedef std::pair, optional > optional_time_pair_t; @@ -123,15 +124,13 @@ protected: static const std::size_t max_price_map_size = 16; mutable memoized_price_map price_map; - mutable bool searched; - public: explicit base_t(const string& _symbol) : supports_flags (commodity_t::decimal_comma_by_default ? static_cast(COMMODITY_STYLE_DECIMAL_COMMA) : static_cast(COMMODITY_STYLE_DEFAULTS)), - symbol(_symbol), precision(0), searched(false) { + symbol(_symbol), precision(0) { TRACE_CTOR(base_t, "const string&"); } virtual ~base_t() { @@ -226,6 +225,13 @@ public: return base_symbol(); } + optional graph_index() const {; + return base->graph_index; + } + void set_graph_index(const optional& arg = none) { + base->graph_index = arg; + } + optional name() const { return base->name; } diff --git a/src/history.cc b/src/history.cc index 44d19f5a..c92a0102 100644 --- a/src/history.cc +++ b/src/history.cc @@ -42,20 +42,22 @@ struct f_max : public std::binary_function { namespace ledger { -void commodity_history_t::add_commodity(const commodity_t& comm) +void commodity_history_t::add_commodity(commodity_t& comm) { - const vertex_descriptor vert = add_vertex(&comm, price_graph); - put(indexmap, vert, reinterpret_cast(&comm)); + if (! comm.graph_index()) { + std::size_t index = num_vertices(price_graph); + comm.set_graph_index(index); + const vertex_descriptor vert = add_vertex(&comm, price_graph); + put(indexmap, vert, index); + } } void commodity_history_t::add_price(const commodity_t& source, const datetime_t& when, const amount_t& price) { - vertex_descriptor sv = - vertex(reinterpret_cast(&source), price_graph); - vertex_descriptor tv = - vertex(reinterpret_cast(&price.commodity()), price_graph); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); + vertex_descriptor tv = vertex(*price.commodity().graph_index(), price_graph); std::pair e1 = add_edge(sv, tv, 0, price_graph); price_map_t& prices(get(ratiomap, e1.first)); @@ -72,10 +74,8 @@ void commodity_history_t::remove_price(const commodity_t& source, const commodity_t& target, const datetime_t& date) { - vertex_descriptor sv = - vertex(reinterpret_cast(&source), price_graph); - vertex_descriptor tv = - vertex(reinterpret_cast(&target), price_graph); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); + vertex_descriptor tv = vertex(*target.graph_index(), price_graph); std::pair e1 = add_edge(sv, tv, 0, price_graph); price_map_t& prices(get(ratiomap, e1.first)); @@ -90,10 +90,11 @@ commodity_history_t::find_price(const commodity_t& source, const optional& oldest, const optional& target) { - vertex_descriptor sv = - vertex(reinterpret_cast(&source), price_graph); - vertex_descriptor tv = - vertex(reinterpret_cast(&*target), price_graph); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); + // jww (2012-03-04): What to do when target is null? In that case, + // should we just return whatever is the most recent price for that + // commodity? + vertex_descriptor tv = vertex(*target->graph_index(), price_graph); // Filter out edges which came into being after the reference time diff --git a/src/history.h b/src/history.h index 486602dd..f94d12c3 100644 --- a/src/history.h +++ b/src/history.h @@ -163,7 +163,7 @@ public: pricemap(get(edge_price_point, price_graph)), ratiomap(get(edge_price_ratio, price_graph)) {} - void add_commodity(const commodity_t& comm); + void add_commodity(commodity_t& comm); void add_price(const commodity_t& source, const datetime_t& when, diff --git a/src/pool.cc b/src/pool.cc index 67cfe3d1..2c094d47 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -223,15 +223,6 @@ commodity_t * commodity_pool_t::find_or_create(commodity_t& comm, return create(comm, details, name); } -optional -commodity_pool_t::find_price(const commodity_t& source, - const optional& commodity, - const optional& moment, - const optional& oldest) const -{ - return commodity_price_history.find_price(source, commodity, moment, oldest); -} - void commodity_pool_t::exchange(commodity_t& commodity, const amount_t& per_unit_cost, const datetime_t& moment) -- cgit v1.2.3 From 97dbf379d5e44c80c748483a688502b1cec8f075 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 5 Mar 2012 17:50:17 -0600 Subject: Rewrote the way annotated commodities are managed The new scheme should be much more efficient, and allows for future growth of what annotations may appear on a commodity. --- src/commodity.h | 9 --- src/pool.cc | 161 ++++++++++++++++++++++++++-------------------------- src/pool.h | 49 ++++++++-------- src/py_commodity.cc | 11 ++-- src/textual.cc | 11 +--- 5 files changed, 110 insertions(+), 131 deletions(-) (limited to 'src/pool.cc') 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 qualified_symbol; - optional 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 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 base_commodity(new commodity_t::base_t(symbol)); - std::auto_ptr commodity(new commodity_t(this, base_commodity)); + shared_ptr 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 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 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 - (new annotated_commodity_t(&comm, details)); + shared_ptr + 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 result - = commodities.insert(commodities_map::value_type(mapping_key, - commodity.get())); + std::pair 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, diff --git a/src/pool.h b/src/pool.h index 709f5c71..7203bc20 100644 --- a/src/pool.h +++ b/src/pool.h @@ -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 commodities_map; + typedef std::map > commodities_map; + typedef std::map, + shared_ptr > 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 price_db; // --price-db= - long quote_leeway; // --leeway= - bool get_quotes; // --download - - static shared_ptr current_pool; + bool keep_base; // --base + optional price_db; // --price-db= + long quote_leeway; // --leeway= + bool get_quotes; // --download function (commodity_t& commodity, const optional& in_terms_of)> get_commodity_quote; + static shared_ptr 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::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::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 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) -- cgit v1.2.3 From 71d0033b6f65260698cf0bf367002a9b6429a3fd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 6 Mar 2012 23:04:27 -0600 Subject: Corrected several compile and link problems --- src/account.cc | 6 ++++-- src/amount.cc | 2 ++ src/draft.cc | 7 +++++++ src/filters.cc | 13 +++++++++++-- src/format.cc | 2 ++ src/op.cc | 10 ++++++++++ src/op.h | 8 ++------ src/pool.cc | 18 +++++++++++------- src/pyinterp.cc | 1 + src/query.h | 1 + src/textual.cc | 10 +++++++--- src/times.h | 2 ++ src/xact.cc | 2 ++ 13 files changed, 62 insertions(+), 20 deletions(-) (limited to 'src/pool.cc') diff --git a/src/account.cc b/src/account.cc index e1874839..29c05719 100644 --- a/src/account.cc +++ b/src/account.cc @@ -89,8 +89,10 @@ account_t * account_t::find_account(const string& acct_name, if (has_flags(ACCOUNT_GENERATED)) account->add_flags(ACCOUNT_GENERATED); - std::pair result - = accounts.insert(accounts_map::value_type(first, account)); +#if defined(DEBUG_ON) + std::pair result = +#endif + accounts.insert(accounts_map::value_type(first, account)); assert(result.second); } else { account = (*i).second; diff --git a/src/amount.cc b/src/amount.cc index f9e2309b..313f8d27 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -120,11 +120,13 @@ namespace { { char * buf = NULL; try { +#if defined(DEBUG_ON) IF_DEBUG("amount.convert") { char * tbuf = mpq_get_str(NULL, 10, quant); DEBUG("amount.convert", "Rational to convert = " << tbuf); std::free(tbuf); } +#endif // Convert the rational number to a floating-point, extending the // floating-point to a large enough size to get a precise answer. diff --git a/src/draft.cc b/src/draft.cc index 017c637d..9abc769e 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -109,7 +109,14 @@ void draft_t::parse_args(const value_t& args) } else if (check_for_date && bool(weekday = string_to_day_of_week(what[0]))) { +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif short dow = static_cast(*weekday); +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic pop +#endif date_t date = CURRENT_DATE() - date_duration(1); while (date.day_of_week() != dow) date -= date_duration(1); diff --git a/src/filters.cc b/src/filters.cc index 8543cddb..34df2056 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -833,10 +833,17 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, foreach (post_t * post, component_posts) { date_t date = post->date(); date_t value_date = post->value_date(); +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif if (! range_start || date < *range_start) range_start = date; if (! range_finish || value_date > *range_finish) range_finish = value_date; +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic pop +#endif } } component_posts.clear(); @@ -880,8 +887,10 @@ void subtotal_posts::operator()(post_t& post) if (i == values.end()) { value_t temp; post.add_to_value(temp, amount_expr); - std::pair result - = values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); +#if defined(DEBUG_ON) + std::pair result = +#endif + values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); assert(result.second); } else { post.add_to_value((*i).second.value, amount_expr); diff --git a/src/format.cc b/src/format.cc index d8c03e6a..79f94869 100644 --- a/src/format.cc +++ b/src/format.cc @@ -221,8 +221,10 @@ format_t::element_t * format_t::parse_elements(const string& fmt, static_cast(current->max_width) : -1); else if (keyword == "left") expr << (current->has_flags(ELEMENT_ALIGN_LEFT) ? "false" : "true"); +#if defined(DEBUG_ON) else assert("Unrecognized format substitution keyword" == NULL); +#endif } else { expr << *ptr++; } diff --git a/src/op.cc b/src/op.cc index 56d3710e..1889f2aa 100644 --- a/src/op.cc +++ b/src/op.cc @@ -38,6 +38,16 @@ namespace ledger { +void intrusive_ptr_add_ref(const expr_t::op_t * op) +{ + op->acquire(); +} + +void intrusive_ptr_release(const expr_t::op_t * op) +{ + op->release(); +} + namespace { value_t split_cons_expr(expr_t::ptr_op_t op) { diff --git a/src/op.h b/src/op.h index 192c1f5e..1807cdd7 100644 --- a/src/op.h +++ b/src/op.h @@ -260,12 +260,8 @@ private: checked_delete(this); } - friend inline void intrusive_ptr_add_ref(const op_t * op) { - op->acquire(); - } - friend inline void intrusive_ptr_release(const op_t * op) { - op->release(); - } + friend void intrusive_ptr_add_ref(const op_t * op); + friend void intrusive_ptr_release(const op_t * op); ptr_op_t copy(ptr_op_t _left = NULL, ptr_op_t _right = NULL) const { ptr_op_t node(new_node(kind, _left, _right)); diff --git a/src/pool.cc b/src/pool.cc index ca50db2c..a6ae0919 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -70,9 +70,11 @@ commodity_t * commodity_pool_t::create(const string& symbol) DEBUG("pool.commodities", "Creating commodity '" << commodity->symbol() << "'"); - std::pair result - = commodities.insert(commodities_map::value_type - (commodity->base_symbol(), commodity)); +#if defined(DEBUG_ON) + std::pair result = +#endif + commodities.insert(commodities_map::value_type + (commodity->base_symbol(), commodity)); assert(result.second); commodity_price_history.add_commodity(*commodity.get()); @@ -211,10 +213,12 @@ commodity_pool_t::create(commodity_t& comm, << "symbol " << commodity->symbol() << std::endl << details); - std::pair result - = annotated_commodities.insert(annotated_commodities_map::value_type - (annotated_commodities_map::key_type - (comm.symbol(), details), commodity)); +#if defined(DEBUG_ON) + std::pair result = +#endif + annotated_commodities.insert(annotated_commodities_map::value_type + (annotated_commodities_map::key_type + (comm.symbol(), details), commodity)); assert(result.second); return commodity.get(); diff --git a/src/pyinterp.cc b/src/pyinterp.cc index d733c40d..d1f46580 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -535,6 +535,7 @@ namespace { case value_t::ANY: // a pointer to an arbitrary object return object(val); } + return object(); } } diff --git a/src/query.h b/src/query.h index f95988a7..7286e89b 100644 --- a/src/query.h +++ b/src/query.h @@ -186,6 +186,7 @@ public: assert(false); return ""; } + return ""; } void unexpected(); diff --git a/src/textual.cc b/src/textual.cc index cf15f048..258a4d76 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -107,10 +107,12 @@ namespace { return (in.good() && ! in.eof() && (in.peek() == ' ' || in.peek() == '\t')); } +#if defined(HAVE_BOOST_PYTHON) bool peek_blank_line() { return (in.good() && ! in.eof() && (in.peek() == '\n' || in.peek() == '\r')); } +#endif void read_next_directive(); @@ -943,9 +945,11 @@ void instance_t::account_alias_directive(account_t * account, string alias) // (account), add a reference to the account in the `account_aliases' // map, which is used by the post parser to resolve alias references. trim(alias); - std::pair result - = context.journal - ->account_aliases.insert(accounts_map::value_type(alias, account)); +#if defined(DEBUG_ON) + std::pair result = +#endif + context.journal->account_aliases.insert + (accounts_map::value_type(alias, account)); assert(result.second); } diff --git a/src/times.h b/src/times.h index 6eadcad3..edc6d8b8 100644 --- a/src/times.h +++ b/src/times.h @@ -218,6 +218,7 @@ struct date_duration_t case YEARS: return date + gregorian::years(length); } + return date_t(); } date_t subtract(const date_t& date) const { @@ -233,6 +234,7 @@ struct date_duration_t case YEARS: return date - gregorian::years(length); } + return date_t(); } string to_string() const { diff --git a/src/xact.cc b/src/xact.cc index 5cec9ab0..5c43558d 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -336,7 +336,9 @@ bool xact_base_t::finalize() amount_t> sorted_amounts_map; sorted_amounts_map samp; foreach (const balance_t::amounts_map::value_type& pair, bal.amounts) { +#if defined(DEBUG_ON) std::pair result = +#endif samp.insert(sorted_amounts_map::value_type (sorted_amounts_map::key_type (pair.first->symbol(), -- cgit v1.2.3 From 7bb83173dae617b8e754fff8e52390ff9664873b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 7 Mar 2012 08:34:15 -0600 Subject: Added some missing DEBUG #if's --- src/account.cc | 2 ++ src/filters.cc | 2 ++ src/pool.cc | 4 ++++ src/textual.cc | 2 ++ src/xact.cc | 2 ++ 5 files changed, 12 insertions(+) (limited to 'src/pool.cc') diff --git a/src/account.cc b/src/account.cc index 29c05719..d772368c 100644 --- a/src/account.cc +++ b/src/account.cc @@ -93,7 +93,9 @@ account_t * account_t::find_account(const string& acct_name, std::pair result = #endif accounts.insert(accounts_map::value_type(first, account)); +#if defined(DEBUG_ON) assert(result.second); +#endif } else { account = (*i).second; } diff --git a/src/filters.cc b/src/filters.cc index 34df2056..3a975920 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -891,7 +891,9 @@ void subtotal_posts::operator()(post_t& post) std::pair result = #endif values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); +#if defined(DEBUG_ON) assert(result.second); +#endif } else { post.add_to_value((*i).second.value, amount_expr); } diff --git a/src/pool.cc b/src/pool.cc index a6ae0919..fd661fe1 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -75,7 +75,9 @@ commodity_t * commodity_pool_t::create(const string& symbol) #endif commodities.insert(commodities_map::value_type (commodity->base_symbol(), commodity)); +#if defined(DEBUG_ON) assert(result.second); +#endif commodity_price_history.add_commodity(*commodity.get()); @@ -219,7 +221,9 @@ commodity_pool_t::create(commodity_t& comm, annotated_commodities.insert(annotated_commodities_map::value_type (annotated_commodities_map::key_type (comm.symbol(), details), commodity)); +#if defined(DEBUG_ON) assert(result.second); +#endif return commodity.get(); } diff --git a/src/textual.cc b/src/textual.cc index 1d1835e3..66972fb3 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -950,7 +950,9 @@ void instance_t::account_alias_directive(account_t * account, string alias) #endif context.journal->account_aliases.insert (accounts_map::value_type(alias, account)); +#if defined(DEBUG_ON) assert(result.second); +#endif } void instance_t::alias_directive(char * line) diff --git a/src/xact.cc b/src/xact.cc index 4ec40f69..4e43e680 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -346,7 +346,9 @@ bool xact_base_t::finalize() as_annotated_commodity(*pair.first).details : annotation_t()), pair.second)); +#if defined(DEBUG_ON) assert(result.second); +#endif } bool first = true; -- cgit v1.2.3 From c9f7195936090ecbe2d5b4ec88c196660ae24f81 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 9 Mar 2012 01:28:20 -0600 Subject: Added the notion of "virtual costs" --- src/annotate.cc | 7 ++++++- src/pool.cc | 1 + src/pool.h | 1 + src/post.h | 3 ++- src/py_commodity.cc | 7 ++++--- src/textual.cc | 11 +++++++++-- src/xact.cc | 2 +- 7 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src/pool.cc') diff --git a/src/annotate.cc b/src/annotate.cc index d2e4976e..1140bf0a 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -122,7 +122,12 @@ void annotation_t::parse(std::istream& in) else if (c == '(') { in.get(c); c = static_cast(in.peek()); - if (c == '(') { + if (c == '@') { + in.clear(); + in.seekg(pos, std::ios::beg); + break; + } + else if (c == '(') { if (value_expr) throw_(amount_error, _("Commodity specifies more than one valuation expresion")); diff --git a/src/pool.cc b/src/pool.cc index fd661fe1..1dd91e99 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -246,6 +246,7 @@ cost_breakdown_t commodity_pool_t::exchange(const amount_t& amount, const amount_t& cost, const bool is_per_unit, + const bool add_price, const optional& moment, const optional& tag) { diff --git a/src/pool.h b/src/pool.h index 7203bc20..b7921f59 100644 --- a/src/pool.h +++ b/src/pool.h @@ -119,6 +119,7 @@ public: cost_breakdown_t exchange(const amount_t& amount, const amount_t& cost, const bool is_per_unit = false, + const bool add_price = true, const optional& moment = none, const optional& tag = none); diff --git a/src/post.h b/src/post.h index 217f5509..7d93b1cc 100644 --- a/src/post.h +++ b/src/post.h @@ -58,7 +58,8 @@ public: #define POST_COST_CALCULATED 0x0080 // posting's cost was calculated #define POST_COST_IN_FULL 0x0100 // cost specified using @@ #define POST_COST_FIXATED 0x0200 // cost is fixed using = indicator -#define POST_ANONYMIZED 0x0400 // a temporary, anonymous posting +#define POST_COST_VIRTUAL 0x0400 // cost is virtualized: (@) +#define POST_ANONYMIZED 0x0800 // a temporary, anonymous posting xact_t * xact; // only set for posts of regular xacts account_t * account; diff --git a/src/py_commodity.cc b/src/py_commodity.cc index 25e5b918..c75b5e64 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -96,14 +96,15 @@ namespace { pool.exchange(commodity, per_unit_cost, moment); } - cost_breakdown_t py_exchange_5(commodity_pool_t& pool, + cost_breakdown_t py_exchange_7(commodity_pool_t& pool, const amount_t& amount, const amount_t& cost, const bool is_per_unit, + const bool add_prices, const boost::optional& moment, const boost::optional& tag) { - return pool.exchange(amount, cost, is_per_unit, moment, tag); + return pool.exchange(amount, cost, is_per_unit, add_prices, moment, tag); } commodity_t * py_pool_getitem(commodity_pool_t& pool, const string& symbol) @@ -280,7 +281,7 @@ void export_commodity() .def("exchange", py_exchange_2, with_custodian_and_ward<1, 2>()) .def("exchange", py_exchange_3, with_custodian_and_ward<1, 2>()) - .def("exchange", py_exchange_5) + .def("exchange", py_exchange_7) .def("parse_price_directive", &commodity_pool_t::parse_price_directive) .def("parse_price_expression", &commodity_pool_t::parse_price_expression, diff --git a/src/textual.cc b/src/textual.cc index 66972fb3..a8cb844b 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1447,12 +1447,16 @@ post_t * instance_t::parse_post(char * line, // Parse the optional cost (@ PER-UNIT-COST, @@ TOTAL-COST) - if (*next == '@') { + if (*next == '@' || (*next == '(' && *(next + 1) == '@')) { DEBUG("textual.parse", "line " << context.linenum << ": " << "Found a price indicator"); - bool per_unit = true; + if (*next == '(') { + post->add_flags(POST_COST_VIRTUAL); + ++next; + } + bool per_unit = true; if (*++next == '@') { per_unit = false; post->add_flags(POST_COST_IN_FULL); @@ -1460,6 +1464,9 @@ post_t * instance_t::parse_post(char * line, << "And it's for a total price"); } + if (post->has_flags(POST_COST_VIRTUAL) && *(next + 1) == ')') + ++next; + beg = static_cast(++next - line); p = skip_ws(next); diff --git a/src/xact.cc b/src/xact.cc index 4e43e680..4e8e56fa 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -269,7 +269,7 @@ bool xact_base_t::finalize() cost_breakdown_t breakdown = commodity_pool_t::current_pool->exchange - (post->amount, *post->cost, false, + (post->amount, *post->cost, false, ! post->has_flags(POST_COST_VIRTUAL), datetime_t(date(), time_duration(0, 0, 0, 0))); if (post->amount.has_annotation() && post->amount.annotation().price) { -- cgit v1.2.3 From 9fd1fc1c228eeba8324972d0d034027ad9de6f41 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 9 Mar 2012 05:06:40 -0600 Subject: Simplified some code in commodity_pool_t --- src/pool.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/pool.cc') diff --git a/src/pool.cc b/src/pool.cc index 1dd91e99..0118a97d 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -67,14 +67,12 @@ commodity_t * commodity_pool_t::create(const string& symbol) *commodity->qualified_symbol += "\""; } - DEBUG("pool.commodities", - "Creating commodity '" << commodity->symbol() << "'"); + DEBUG("pool.commodities", "Creating commodity '" << symbol << "'"); #if defined(DEBUG_ON) std::pair result = #endif - commodities.insert(commodities_map::value_type - (commodity->base_symbol(), commodity)); + commodities.insert(commodities_map::value_type(symbol, commodity)); #if defined(DEBUG_ON) assert(result.second); #endif -- cgit v1.2.3 From 610a3e170994dc3cd3ae0dc989a49e4e7c7fdadf Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 15 Mar 2012 04:47:32 -0500 Subject: Don't map_prices if price commodity matches source Fixes #680 --- src/commodity.cc | 6 ++++-- src/commodity.h | 3 ++- src/filters.cc | 2 +- src/history.cc | 32 ++++++++++++++++++++++++-------- src/history.h | 3 ++- src/pool.cc | 3 +++ test/regress/786A3DD0.test | 17 +++++++++++++++++ 7 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 test/regress/786A3DD0.test (limited to 'src/pool.cc') diff --git a/src/commodity.cc b/src/commodity.cc index 8f0dc100..0dad9a1a 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -72,7 +72,8 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) void commodity_t::map_prices(function fn, const datetime_t& moment, - const datetime_t& _oldest) + const datetime_t& _oldest, + bool bidirectionally) { datetime_t when; if (! moment.is_not_a_date_time()) @@ -82,7 +83,8 @@ void commodity_t::map_prices(function fn, else when = CURRENT_TIME(); - pool().commodity_price_history.map_prices(fn, *this, when, _oldest); + pool().commodity_price_history.map_prices(fn, *this, when, _oldest, + bidirectionally); } optional diff --git a/src/commodity.h b/src/commodity.h index bd1aedb9..148a3636 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -273,7 +273,8 @@ public: void map_prices(function fn, const datetime_t& moment = datetime_t(), - const datetime_t& _oldest = datetime_t()); + const datetime_t& _oldest = datetime_t(), + bool bidirectionally = false); optional find_price_from_expr(expr_t& expr, const commodity_t * commodity, diff --git a/src/filters.cc b/src/filters.cc index 9501856e..d5cb8ebb 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -776,7 +776,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post, display_total.as_balance().amounts) amt_comm.first->map_prices(insert_prices_in_map(all_prices), datetime_t(current), - datetime_t(post.value_date())); + datetime_t(post.value_date()), true); // Choose the last price from each day as the price to use typedef std::map date_map; diff --git a/src/history.cc b/src/history.cc index fcb80d67..3767c1df 100644 --- a/src/history.cc +++ b/src/history.cc @@ -132,6 +132,8 @@ void commodity_history_t::add_price(const commodity_t& source, const datetime_t& when, const amount_t& price) { + assert(source != price.commodity()); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*price.commodity().graph_index(), price_graph); @@ -153,6 +155,8 @@ void commodity_history_t::remove_price(const commodity_t& source, const commodity_t& target, const datetime_t& date) { + assert(source != target); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*target.graph_index(), price_graph); @@ -172,8 +176,11 @@ void commodity_history_t::map_prices(function fn, const commodity_t& source, const datetime_t& moment, - const datetime_t& oldest) + const datetime_t& oldest, + bool bidirectionally) { + DEBUG("history.map", "Mapping prices for source commodity: " << source); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); FGraph fg(price_graph, @@ -193,16 +200,23 @@ void commodity_history_t::map_prices(function= oldest) && when <= moment) { if (pair.second.commodity() == source) { - amount_t price(pair.second); - price.in_place_invert(); - if (source == *get(namemap, sv)) - price.set_commodity(const_cast(*get(namemap, *f_vi))); - else - price.set_commodity(const_cast(*get(namemap, sv))); + if (bidirectionally) { + amount_t price(pair.second); + price.in_place_invert(); + if (source == *get(namemap, sv)) + price.set_commodity(const_cast(*get(namemap, *f_vi))); + else + price.set_commodity(const_cast(*get(namemap, sv))); + DEBUG("history.map", "Inverted price is " << price); + fn(when, price); + } + } else { + fn(when, pair.second); } - fn(when, pair.second); } } } @@ -275,6 +289,8 @@ commodity_history_t::find_price(const commodity_t& source, const datetime_t& moment, const datetime_t& oldest) { + assert(source != target); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*target.graph_index(), price_graph); diff --git a/src/history.h b/src/history.h index 71cbad0c..af0d90f9 100644 --- a/src/history.h +++ b/src/history.h @@ -113,7 +113,8 @@ public: void map_prices(function fn, const commodity_t& source, const datetime_t& moment, - const datetime_t& _oldest = datetime_t()); + const datetime_t& _oldest = datetime_t(), + bool bidirectionally = false); optional find_price(const commodity_t& source, diff --git a/src/pool.cc b/src/pool.cc index 0118a97d..d5494352 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -266,6 +266,9 @@ commodity_pool_t::exchange(const amount_t& amount, amount_t per_unit_cost = (is_per_unit || amount.is_realzero()) ? cost.abs() : (cost / amount).abs(); + if (! cost.has_commodity()) + per_unit_cost.clear_commodity(); + DEBUG("commodity.prices.add", "exchange: per-unit-cost = " << per_unit_cost); // Do not record commodity exchanges where amount's commodity has a diff --git a/test/regress/786A3DD0.test b/test/regress/786A3DD0.test new file mode 100644 index 00000000..051f6382 --- /dev/null +++ b/test/regress/786A3DD0.test @@ -0,0 +1,17 @@ +D 1000.00 EUR + +2011-02-27 * Australia + A -100.00 AUD @ 0.746 EUR + B + +2012-03-12 * Withdrawal + Assets:Cash USD 200.00 + Expenses:Banking:Fees USD 2.50 + Assets:Chequing CAD -203.42 + Epenses:Banking:Fees CAD 2.00 + Assets:Chqeuing CAD -2.00 + +test pricedb +P 2011/02/27 00:00:00 AUD 0.746 EUR +P 2012/03/12 00:00:00 USD CAD 1.00454320987654321 +end test -- cgit v1.2.3 From a49e33a8ce91e07ebcbbb99bd8f01108d578dcc0 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 16 Mar 2012 00:59:32 -0500 Subject: Don't add price exchanges for a commodity itself Fixes #703 --- 95350193.test | 6 ++++++ src/pool.cc | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 95350193.test (limited to 'src/pool.cc') diff --git a/95350193.test b/95350193.test new file mode 100644 index 00000000..dadb39cf --- /dev/null +++ b/95350193.test @@ -0,0 +1,6 @@ +2011-11-08 * Test + Assets:Voucher:Amazon 137.87 GBP (48H5) + Assets:Cash -137.87 GBP + +test pricedb +end test diff --git a/src/pool.cc b/src/pool.cc index d5494352..5813c0f6 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -277,8 +277,10 @@ commodity_pool_t::exchange(const amount_t& amount, if (! per_unit_cost.is_realzero() && (current_annotation == NULL || ! (current_annotation->price && - current_annotation->has_flags(ANNOTATION_PRICE_FIXATED)))) + current_annotation->has_flags(ANNOTATION_PRICE_FIXATED))) && + commodity.referent() != per_unit_cost.commodity().referent()) { exchange(commodity, per_unit_cost, moment ? *moment : CURRENT_TIME()); + } cost_breakdown_t breakdown; breakdown.final_cost = ! is_per_unit ? cost : cost * amount.abs(); -- cgit v1.2.3 From 47d7f5a43b286b3c736e21480d84caf75cea885f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 18 Mar 2012 02:16:41 -0500 Subject: Fix problem with -H and lack of pricing info Fixes #691 --- src/annotate.cc | 6 +++++- src/annotate.h | 9 +++++---- src/pool.cc | 37 +++++++++++++++---------------------- test/regress/96A8E4A1.test | 10 ++++++++++ 4 files changed, 35 insertions(+), 27 deletions(-) create mode 100644 test/regress/96A8E4A1.test (limited to 'src/pool.cc') diff --git a/src/annotate.cc b/src/annotate.cc index 2b118e76..25f0e582 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -56,6 +56,7 @@ bool annotation_t::operator<(const annotation_t& rhs) const return true; if (price->commodity().symbol() > rhs.price->commodity().symbol()) return false; + if (*price < *rhs.price) return true; if (*price > *rhs.price) return false; } @@ -68,9 +69,12 @@ bool annotation_t::operator<(const annotation_t& rhs) const if (*tag > *rhs.tag) return false; } if (value_expr) { + DEBUG("annotate.less", "Comparing (" << value_expr->text() + << ") < (" << rhs.value_expr->text()); if (value_expr->text() < rhs.value_expr->text()) return true; - if (value_expr->text() > rhs.value_expr->text()) return false; + //if (value_expr->text() > rhs.value_expr->text()) return false; } + return false; } diff --git a/src/annotate.h b/src/annotate.h index 044ebc4d..163ffac5 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -72,7 +72,7 @@ struct annotation_t : public supports_flags<>, : supports_flags<>(), price(_price), date(_date), tag(_tag), value_expr(_value_expr) { TRACE_CTOR(annotation_t, - "const optional& + date_t + string + expr_t"); + "optional + date_t + string + expr_t"); } annotation_t(const annotation_t& other) : supports_flags<>(other.flags()), @@ -91,9 +91,9 @@ struct annotation_t : public supports_flags<>, bool operator<(const annotation_t& rhs) const; bool operator==(const annotation_t& rhs) const { - return (price == rhs.price && - date == rhs.date && - tag == rhs.tag && + return (price == rhs.price && + date == rhs.date && + tag == rhs.tag && (value_expr && rhs.value_expr ? value_expr->text() == rhs.value_expr->text() : value_expr == rhs.value_expr)); @@ -228,6 +228,7 @@ protected: : commodity_t(_ptr->parent_, _ptr->base), ptr(_ptr), details(_details) { TRACE_CTOR(annotated_commodity_t, "commodity_t *, annotation_t"); annotated = true; + qualified_symbol = _ptr->qualified_symbol; } public: diff --git a/src/pool.cc b/src/pool.cc index 5813c0f6..be26de3b 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -102,7 +102,7 @@ commodity_t * commodity_pool_t::find_or_create(const string& symbol) commodity_t * commodity_pool_t::alias(const string& name, commodity_t& referent) { - commodities_map::const_iterator i = commodities.find(referent.symbol()); + commodities_map::const_iterator i = commodities.find(referent.base_symbol()); assert(i != commodities.end()); std::pair result @@ -130,20 +130,16 @@ commodity_pool_t::find(const string& symbol, const annotation_t& details) DEBUG("pool.commodities", "commodity_pool_t::find[ann] " << "symbol " << symbol << std::endl << details); - 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; - } + 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->base_symbol() << std::endl + << as_annotated_commodity(*(*i).second.get()).details); + return (*i).second.get(); } else { - return find(symbol); + return NULL; } } @@ -170,10 +166,10 @@ commodity_t * commodity_pool_t::find_or_create(commodity_t& comm, const annotation_t& details) { DEBUG("pool.commodities", "commodity_pool_t::find_or_create[ann:comm] " - << "symbol " << comm.symbol() << std::endl << details); + << "symbol " << comm.base_symbol() << std::endl << details); if (details) { - if (commodity_t * ann_comm = find(comm.symbol(), details)) { + if (commodity_t * ann_comm = find(comm.base_symbol(), details)) { assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details); return ann_comm; } else { @@ -189,7 +185,7 @@ commodity_pool_t::create(commodity_t& comm, const annotation_t& details) { DEBUG("pool.commodities", "commodity_pool_t::create[ann:comm] " - << "symbol " << comm.symbol() << std::endl << details); + << "symbol " << comm.base_symbol() << std::endl << details); assert(comm); assert(! comm.has_annotation()); @@ -206,11 +202,8 @@ commodity_pool_t::create(commodity_t& comm, comm.add_flags(COMMODITY_SAW_ANN_PRICE_FLOAT); } - commodity->qualified_symbol = comm.symbol(); - assert(! commodity->qualified_symbol->empty()); - DEBUG("pool.commodities", "Creating annotated commodity " - << "symbol " << commodity->symbol() + << "symbol " << commodity->base_symbol() << std::endl << details); #if defined(DEBUG_ON) @@ -218,7 +211,7 @@ commodity_pool_t::create(commodity_t& comm, #endif annotated_commodities.insert(annotated_commodities_map::value_type (annotated_commodities_map::key_type - (comm.symbol(), details), commodity)); + (comm.base_symbol(), details), commodity)); #if defined(DEBUG_ON) assert(result.second); #endif diff --git a/test/regress/96A8E4A1.test b/test/regress/96A8E4A1.test new file mode 100644 index 00000000..93fb55d2 --- /dev/null +++ b/test/regress/96A8E4A1.test @@ -0,0 +1,10 @@ +2011-01-31 * Test + Expenses:Travel 1 "Spr MegaBonus" + Assets:Voucher + +test -X EUR -H bal + -1 "Spr MegaBonus" Assets:Voucher + 1 "Spr MegaBonus" Expenses:Travel +-------------------- + 0 +end test -- cgit v1.2.3 From 22505d9527edce59cd3cf90c5241e4bd809eb8a2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 20 Mar 2012 02:10:40 -0500 Subject: Always call TRACE_CTOR at the end of constructors --- src/amount.cc | 10 +++++----- src/amount.h | 8 ++++---- src/annotate.h | 2 +- src/balance.cc | 6 +++--- src/balance.h | 6 +++--- src/csv.h | 2 +- src/draft.h | 2 +- src/expr.cc | 4 ++-- src/filters.cc | 12 ++++++------ src/filters.h | 15 +++++++-------- src/format.h | 2 +- src/generate.cc | 3 +-- src/global.cc | 4 ++-- src/item.h | 4 ++-- src/iterators.h | 14 +++++++------- src/journal.cc | 6 +++--- src/journal.h | 2 +- src/mask.cc | 2 +- src/option.h | 2 +- src/org.cc | 4 ++-- src/output.cc | 8 ++++---- src/pool.cc | 2 +- src/post.h | 2 +- src/pstream.h | 8 ++++---- src/pyfstream.h | 8 ++++---- src/query.h | 8 +++++--- src/scope.h | 2 +- src/session.cc | 4 ++-- src/times.h | 5 +++-- src/unistring.h | 4 ++-- src/utils.cc | 12 +++++++----- src/value.h | 34 ++++++++++++++++++---------------- 32 files changed, 106 insertions(+), 101 deletions(-) (limited to 'src/pool.cc') diff --git a/src/amount.cc b/src/amount.cc index 5fa58528..8c5ae574 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -63,16 +63,16 @@ struct amount_t::bigint_t : public supports_flags<> #define MP(bigint) ((bigint)->val) bigint_t() : prec(0), refc(1) { - TRACE_CTOR(bigint_t, ""); mpq_init(val); + TRACE_CTOR(bigint_t, ""); } bigint_t(const bigint_t& other) : supports_flags<>(static_cast (other.flags() & ~BIGINT_BULK_ALLOC)), prec(other.prec), refc(1) { - TRACE_CTOR(bigint_t, "copy"); mpq_init(val); mpq_set(val, other.val); + TRACE_CTOR(bigint_t, "copy"); } ~bigint_t() { TRACE_DTOR(bigint_t); @@ -349,24 +349,24 @@ void amount_t::_release() amount_t::amount_t(const double val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const double"); quantity = new bigint_t; mpq_set_d(MP(quantity), val); quantity->prec = extend_by_digits; // an approximation + TRACE_CTOR(amount_t, "const double"); } amount_t::amount_t(const unsigned long val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const unsigned long"); quantity = new bigint_t; mpq_set_ui(MP(quantity), val, 1); + TRACE_CTOR(amount_t, "const unsigned long"); } amount_t::amount_t(const long val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const long"); quantity = new bigint_t; mpq_set_si(MP(quantity), val, 1); + TRACE_CTOR(amount_t, "const long"); } diff --git a/src/amount.h b/src/amount.h index 903a01cd..10e83552 100644 --- a/src/amount.h +++ b/src/amount.h @@ -155,17 +155,17 @@ public: commodity_t::null_commodity. The number may be of infinite precision. */ explicit amount_t(const string& val) : quantity(NULL) { - TRACE_CTOR(amount_t, "const string&"); parse(val); + TRACE_CTOR(amount_t, "const string&"); } /** Parse a pointer to a C string as an (optionally commoditized) amount. If no commodity is present, the resulting commodity is \c commodity_t::null_commodity. The number may be of infinite precision. */ explicit amount_t(const char * val) : quantity(NULL) { - TRACE_CTOR(amount_t, "const char *"); assert(val); parse(val); + TRACE_CTOR(amount_t, "const char *"); } /*@}*/ @@ -195,21 +195,21 @@ public: same memory used by the original via reference counting. The \c amount_t::bigint_t class in amount.cc maintains the reference. */ amount_t(const amount_t& amt) : quantity(NULL) { - TRACE_CTOR(amount_t, "copy"); if (amt.quantity) _copy(amt); else commodity_ = NULL; + TRACE_CTOR(amount_t, "copy"); } /** Copy an amount object, applying the given commodity annotation details afterward. This is equivalent to doing a normal copy (@see amount_t(const amount_t&)) and then calling amount_t::annotate(). */ amount_t(const amount_t& amt, const annotation_t& details) : quantity(NULL) { - TRACE_CTOR(amount_t, "const amount_t&, const annotation_t&"); assert(amt.quantity); _copy(amt); annotate(details); + TRACE_CTOR(amount_t, "const amount_t&, const annotation_t&"); } /** Assign an amount object. This is like copying if the amount was null beforehand, otherwise the previous value's reference is must diff --git a/src/annotate.h b/src/annotate.h index 163ffac5..85a34662 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -226,9 +226,9 @@ protected: explicit annotated_commodity_t(commodity_t * _ptr, const annotation_t& _details) : commodity_t(_ptr->parent_, _ptr->base), ptr(_ptr), details(_details) { - TRACE_CTOR(annotated_commodity_t, "commodity_t *, annotation_t"); annotated = true; qualified_symbol = _ptr->qualified_symbol; + TRACE_CTOR(annotated_commodity_t, "commodity_t *, annotation_t"); } public: diff --git a/src/balance.cc b/src/balance.cc index f87e8bbd..5c57cd99 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -41,23 +41,23 @@ namespace ledger { balance_t::balance_t(const double val) { - TRACE_CTOR(balance_t, "const double"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const double"); } balance_t::balance_t(const unsigned long val) { - TRACE_CTOR(balance_t, "const unsigned long"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const unsigned long"); } balance_t::balance_t(const long val) { - TRACE_CTOR(balance_t, "const long"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const long"); } balance_t& balance_t::operator+=(const balance_t& bal) diff --git a/src/balance.h b/src/balance.h index 5f0d52ed..11c370bb 100644 --- a/src/balance.h +++ b/src/balance.h @@ -108,26 +108,26 @@ public: TRACE_CTOR(balance_t, ""); } balance_t(const amount_t& amt) { - TRACE_CTOR(balance_t, "const amount_t&"); if (amt.is_null()) throw_(balance_error, _("Cannot initialize a balance from an uninitialized amount")); if (! amt.is_realzero()) amounts.insert(amounts_map::value_type(&amt.commodity(), amt)); + TRACE_CTOR(balance_t, "const amount_t&"); } balance_t(const double val); balance_t(const unsigned long val); balance_t(const long val); explicit balance_t(const string& val) { - TRACE_CTOR(balance_t, "const string&"); amount_t temp(val); amounts.insert(amounts_map::value_type(&temp.commodity(), temp)); + TRACE_CTOR(balance_t, "const string&"); } explicit balance_t(const char * val) { - TRACE_CTOR(balance_t, "const char *"); amount_t temp(val); amounts.insert(amounts_map::value_type(&temp.commodity(), temp)); + TRACE_CTOR(balance_t, "const char *"); } /** diff --git a/src/csv.h b/src/csv.h index d98c0567..7d5098d2 100644 --- a/src/csv.h +++ b/src/csv.h @@ -91,8 +91,8 @@ public: cost_mask("cost"), total_mask("total"), note_mask("note") { - TRACE_CTOR(csv_reader, "parse_context_t&"); read_index(*context.stream.get()); + TRACE_CTOR(csv_reader, "parse_context_t&"); } ~csv_reader() { TRACE_DTOR(csv_reader); diff --git a/src/draft.h b/src/draft.h index e5d29134..46aa26e1 100644 --- a/src/draft.h +++ b/src/draft.h @@ -92,9 +92,9 @@ class draft_t : public expr_base_t public: draft_t(const value_t& args) : base_type() { - TRACE_CTOR(draft_t, "value_t"); if (! args.empty()) parse_args(args); + TRACE_CTOR(draft_t, "value_t"); } virtual ~draft_t() throw() { TRACE_DTOR(draft_t); diff --git a/src/expr.cc b/src/expr.cc index b22572f8..25967207 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -55,16 +55,16 @@ expr_t::expr_t(ptr_op_t _ptr, scope_t * _context) expr_t::expr_t(const string& _str, const parse_flags_t& flags) : base_type() { - TRACE_CTOR(expr_t, "string, parse_flags_t"); if (! _str.empty()) parse(_str, flags); + TRACE_CTOR(expr_t, "string, parse_flags_t"); } expr_t::expr_t(std::istream& in, const parse_flags_t& flags) : base_type() { - TRACE_CTOR(expr_t, "std::istream&, parse_flags_t"); parse(in, flags); + TRACE_CTOR(expr_t, "std::istream&, parse_flags_t"); } expr_t::~expr_t() { diff --git a/src/filters.cc b/src/filters.cc index 73ee200d..5915ad3c 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -512,8 +512,8 @@ display_filter_posts::display_filter_posts(post_handler_ptr handler, display_total_expr(report.HANDLER(display_total_).expr), show_rounding(_show_rounding) { - TRACE_CTOR(display_filter_posts, "post_handler_ptr, report_t&, bool"); create_accounts(); + TRACE_CTOR(display_filter_posts, "post_handler_ptr, report_t&, bool"); } bool display_filter_posts::output_rounding(post_t& post) @@ -598,9 +598,6 @@ changed_value_posts::changed_value_posts show_unrealized(_show_unrealized), last_post(NULL), display_filter(_display_filter) { - TRACE_CTOR(changed_value_posts, - "post_handler_ptr, report_t&, bool, bool, display_filter_posts *"); - string gains_equity_account_name; if (report.HANDLED(unrealized_gains_)) gains_equity_account_name = report.HANDLER(unrealized_gains_).str(); @@ -620,6 +617,9 @@ changed_value_posts::changed_value_posts losses_equity_account->add_flags(ACCOUNT_GENERATED); create_accounts(); + + TRACE_CTOR(changed_value_posts, + "post_handler_ptr, report_t&, bool, bool, display_filter_posts *"); } void changed_value_posts::flush() @@ -1417,8 +1417,6 @@ inject_posts::inject_posts(post_handler_ptr handler, account_t * master) : item_handler(handler) { - TRACE_CTOR(inject_posts, "post_handler_ptr, string, account_t *"); - scoped_array buf(new char[tag_list.length() + 1]); std::strcpy(buf.get(), tag_list.c_str()); @@ -1435,6 +1433,8 @@ inject_posts::inject_posts(post_handler_ptr handler, tags_list.push_back (tags_list_pair(q, tag_mapping_pair(account, tag_injected_set()))); } + + TRACE_CTOR(inject_posts, "post_handler_ptr, string, account_t *"); } void inject_posts::operator()(post_t& post) diff --git a/src/filters.h b/src/filters.h index 3e766863..ab226429 100644 --- a/src/filters.h +++ b/src/filters.h @@ -75,8 +75,8 @@ public: expr_t& _group_by_expr) : post_chain(_post_chain), report(_report), group_by_expr(_group_by_expr) { + preflush_func = bind(&post_splitter::print_title, this, _1); TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t"); - preflush_func = bind(&post_splitter::print_title, this, _1); } virtual ~post_splitter() { TRACE_DTOR(post_splitter); @@ -154,8 +154,6 @@ class pass_down_posts : public item_handler public: pass_down_posts(post_handler_ptr handler, Iterator& iter) : item_handler(handler) { - TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); - while (post_t * post = *iter) { try { item_handler::operator()(*post); @@ -168,6 +166,8 @@ public: } item_handler::flush(); + + TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); } virtual ~pass_down_posts() { @@ -448,8 +448,8 @@ public: only_predicate(_only_predicate), count(0), last_xact(NULL), last_post(NULL), only_collapse_if_zero(_only_collapse_if_zero), report(_report) { - TRACE_CTOR(collapse_posts, "post_handler_ptr, ..."); create_accounts(); + TRACE_CTOR(collapse_posts, "post_handler_ptr, ..."); } virtual ~collapse_posts() { TRACE_DTOR(collapse_posts); @@ -499,8 +499,7 @@ public: const bool _also_matching = false) : item_handler(handler), also_matching(_also_matching) { - TRACE_CTOR(related_posts, - "post_handler_ptr, const bool"); + TRACE_CTOR(related_posts, "post_handler_ptr, const bool"); } virtual ~related_posts() throw() { TRACE_DTOR(related_posts); @@ -722,9 +721,9 @@ public: : subtotal_posts(_handler, amount_expr), start_interval(_interval), interval(start_interval), exact_periods(_exact_periods), generate_empty_posts(_generate_empty_posts) { + create_accounts(); TRACE_CTOR(interval_posts, "post_handler_ptr, expr_t&, date_interval_t, bool, bool"); - create_accounts(); } virtual ~interval_posts() throw() { TRACE_DTOR(interval_posts); @@ -774,8 +773,8 @@ public: posts_as_equity(post_handler_ptr _handler, report_t& _report, expr_t& amount_expr) : subtotal_posts(_handler, amount_expr), report(_report) { - TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); create_accounts(); + TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); } virtual ~posts_as_equity() throw() { TRACE_DTOR(posts_as_equity); diff --git a/src/format.h b/src/format.h index 60ae2abe..cc48bdda 100644 --- a/src/format.h +++ b/src/format.h @@ -125,9 +125,9 @@ public: } format_t(const string& _str, scope_t * context = NULL) : base_type(context) { - TRACE_CTOR(format_t, "const string&"); if (! _str.empty()) parse_format(_str); + TRACE_CTOR(format_t, "const string&"); } virtual ~format_t() { TRACE_DTOR(format_t); diff --git a/src/generate.cc b/src/generate.cc index edd58632..8769c99c 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -63,8 +63,6 @@ generate_posts_iterator::generate_posts_iterator neg_number_range(-10000, -1), neg_number_gen(rnd_gen, neg_number_range), pos_number_range(1, 10000), pos_number_gen(rnd_gen, pos_number_range) { - TRACE_CTOR(generate_posts_iterator, "bool"); - std::ostringstream next_date_buf; generate_date(next_date_buf); next_date = parse_date(next_date_buf.str()); @@ -73,6 +71,7 @@ generate_posts_iterator::generate_posts_iterator generate_date(next_aux_date_buf); next_aux_date = parse_date(next_aux_date_buf.str()); + TRACE_CTOR(generate_posts_iterator, "bool"); } void generate_posts_iterator::generate_string(std::ostream& out, int len, diff --git a/src/global.cc b/src/global.cc index b5ceb614..6dc8d150 100644 --- a/src/global.cc +++ b/src/global.cc @@ -47,8 +47,6 @@ static bool args_only = false; global_scope_t::global_scope_t(char ** envp) { - TRACE_CTOR(global_scope_t, ""); - epoch = CURRENT_TIME(); #if defined(HAVE_BOOST_PYTHON) @@ -89,6 +87,8 @@ global_scope_t::global_scope_t(char ** envp) } else { session().HANDLER(price_db_).off(); } + + TRACE_CTOR(global_scope_t, ""); } global_scope_t::~global_scope_t() diff --git a/src/item.h b/src/item.h index e7415918..a1160329 100644 --- a/src/item.h +++ b/src/item.h @@ -60,8 +60,8 @@ struct position_t TRACE_CTOR(position_t, ""); } position_t(const position_t& pos) { - TRACE_CTOR(position_t, "copy"); *this = pos; + TRACE_CTOR(position_t, "copy"); } ~position_t() throw() { TRACE_DTOR(position_t); @@ -125,8 +125,8 @@ public: } item_t(const item_t& item) : supports_flags(), scope_t() { - TRACE_CTOR(item_t, "copy"); copy_details(item); + TRACE_CTOR(item_t, "copy"); } virtual ~item_t() { TRACE_DTOR(item_t); diff --git a/src/iterators.h b/src/iterators.h index 922ebccd..53814666 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -100,8 +100,8 @@ public: } xact_posts_iterator(xact_t& xact) : posts_uninitialized(true) { - TRACE_CTOR(xact_posts_iterator, "xact_t&"); reset(xact); + TRACE_CTOR(xact_posts_iterator, "xact_t&"); } xact_posts_iterator(const xact_posts_iterator& i) : iterator_facade_base& _prepend_format) : report(_report), last_xact(NULL), last_post(NULL) { - TRACE_CTOR(posts_to_org_table, "report&, optional"); - first_line_format.parse_format ("|%(format_date(date))" "|%(code)" @@ -79,6 +77,8 @@ posts_to_org_table::posts_to_org_table(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(posts_to_org_table, "report&, optional"); } void posts_to_org_table::flush() diff --git a/src/output.cc b/src/output.cc index aaf81f60..742000bd 100644 --- a/src/output.cc +++ b/src/output.cc @@ -47,8 +47,6 @@ format_posts::format_posts(report_t& _report, : report(_report), prepend_width(_prepend_width), last_xact(NULL), last_post(NULL), first_report_title(true) { - TRACE_CTOR(format_posts, "report&, const string&, bool"); - const char * f = format.c_str(); if (const char * p = std::strstr(f, "%/")) { @@ -70,6 +68,8 @@ format_posts::format_posts(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(format_posts, "report&, const string&, bool"); } void format_posts::flush() @@ -131,8 +131,6 @@ format_accounts::format_accounts(report_t& _report, : report(_report), prepend_width(_prepend_width), disp_pred(), first_report_title(true) { - TRACE_CTOR(format_accounts, "report&, const string&"); - const char * f = format.c_str(); if (const char * p = std::strstr(f, "%/")) { @@ -154,6 +152,8 @@ format_accounts::format_accounts(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(format_accounts, "report&, const string&"); } std::size_t format_accounts::post_account(account_t& account, const bool flat) diff --git a/src/pool.cc b/src/pool.cc index be26de3b..61b5bef2 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -47,9 +47,9 @@ commodity_pool_t::commodity_pool_t() quote_leeway(86400), get_quotes(false), get_commodity_quote(commodity_quote_from_script) { - TRACE_CTOR(commodity_pool_t, ""); null_commodity = create(""); null_commodity->add_flags(COMMODITY_BUILTIN | COMMODITY_NOMARKET); + TRACE_CTOR(commodity_pool_t, ""); } commodity_t * commodity_pool_t::create(const string& symbol) diff --git a/src/post.h b/src/post.h index d6004c9f..76a89a33 100644 --- a/src/post.h +++ b/src/post.h @@ -96,8 +96,8 @@ public: assigned_amount(post.assigned_amount), xdata_(post.xdata_) { - TRACE_CTOR(post_t, "copy"); copy_details(post); + TRACE_CTOR(post_t, "copy"); } virtual ~post_t() { TRACE_DTOR(post_t); diff --git a/src/pstream.h b/src/pstream.h index dfb27056..6e38158a 100644 --- a/src/pstream.h +++ b/src/pstream.h @@ -58,14 +58,14 @@ class ptristream : public std::istream public: ptrinbuf(char * _ptr, std::size_t _len) : ptr(_ptr), len(_len) { - TRACE_CTOR(ptrinbuf, "char *, std::size_t"); - if (*ptr && len == 0) len = std::strlen(ptr); - setg(ptr, // beginning of putback area - ptr, // read position + setg(ptr, // beginning of putback area + ptr, // read position ptr+len); // end position + + TRACE_CTOR(ptrinbuf, "char *, std::size_t"); } ~ptrinbuf() throw() { TRACE_DTOR(ptrinbuf); diff --git a/src/pyfstream.h b/src/pyfstream.h index 972f976f..18f28bc4 100644 --- a/src/pyfstream.h +++ b/src/pyfstream.h @@ -86,8 +86,8 @@ protected: public: pyofstream (PyFileObject * fo) : std::ostream(0), buf(fo) { - TRACE_CTOR(pyofstream, "PyFileObject *"); rdbuf(&buf); + TRACE_CTOR(pyofstream, "PyFileObject *"); } ~pyofstream() throw() { TRACE_DTOR(pyofstream); @@ -121,11 +121,11 @@ public: * => force underflow() */ pyinbuf (PyFileObject * _fo) : fo(_fo) { - TRACE_CTOR(pyinbuf, "PyFileObject *"); - setg (buffer+pbSize, // beginning of putback area buffer+pbSize, // read position buffer+pbSize); // end position + + TRACE_CTOR(pyinbuf, "PyFileObject *"); } ~pyinbuf() throw() { TRACE_DTOR(pyinbuf); @@ -191,8 +191,8 @@ protected: public: pyifstream (PyFileObject * fo) : std::istream(0), buf(fo) { - TRACE_CTOR(pyifstream, "PyFileObject *"); rdbuf(&buf); + TRACE_CTOR(pyifstream, "PyFileObject *"); } ~pyifstream() throw() { TRACE_DTOR(pyifstream); diff --git a/src/query.h b/src/query.h index c694d099..fe52eb35 100644 --- a/src/query.h +++ b/src/query.h @@ -204,10 +204,11 @@ public: consume_whitespace(false), consume_next_arg(false), multiple_args(_multiple_args) { - TRACE_CTOR(query_t::lexer_t, ""); assert(begin != end); arg_i = (*begin).as_string().begin(); arg_end = (*begin).as_string().end(); + + TRACE_CTOR(query_t::lexer_t, ""); } lexer_t(const lexer_t& lexer) : begin(lexer.begin), end(lexer.end), @@ -302,18 +303,19 @@ public: query_t(const string& arg, const keep_details_t& what_to_keep = keep_details_t(), bool multiple_args = true) { - TRACE_CTOR(query_t, "string, keep_details_t, bool"); if (! arg.empty()) { value_t temp(string_value(arg)); parse_args(temp.to_sequence(), what_to_keep, multiple_args); } + TRACE_CTOR(query_t, "string, keep_details_t, bool"); } query_t(const value_t& args, const keep_details_t& what_to_keep = keep_details_t(), bool multiple_args = true) { - TRACE_CTOR(query_t, "value_t, keep_details_t, bool"); if (! args.empty()) parse_args(args, what_to_keep, multiple_args); + + TRACE_CTOR(query_t, "value_t, keep_details_t, bool"); } virtual ~query_t() { TRACE_DTOR(query_t); diff --git a/src/scope.h b/src/scope.h index 9318fc5c..acaf7194 100644 --- a/src/scope.h +++ b/src/scope.h @@ -209,9 +209,9 @@ public: explicit bind_scope_t(scope_t& _parent, scope_t& _grandchild) : child_scope_t(_parent), grandchild(_grandchild) { - TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&"); DEBUG("scope.symbols", "Binding scope " << &_parent << " with " << &_grandchild); + TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&"); } virtual ~bind_scope_t() { TRACE_DTOR(bind_scope_t); diff --git a/src/session.cc b/src/session.cc index 5c9e4fd4..9a77d341 100644 --- a/src/session.cc +++ b/src/session.cc @@ -62,14 +62,14 @@ void set_session_context(session_t * session) session_t::session_t() : flush_on_next_data_file(false), journal(new journal_t) { - TRACE_CTOR(session_t, ""); - if (const char * home_var = std::getenv("HOME")) HANDLER(price_db_).on(none, (path(home_var) / ".pricedb").string()); else HANDLER(price_db_).on(none, path("./.pricedb").string()); parsing_context.push(); + + TRACE_CTOR(session_t, ""); } std::size_t session_t::read_data(const string& master_account) diff --git a/src/times.h b/src/times.h index e3134665..3bb95903 100644 --- a/src/times.h +++ b/src/times.h @@ -307,13 +307,14 @@ public: } date_specifier_t(const date_t& date, const optional& traits = none) { - TRACE_CTOR(date_specifier_t, "date_t, date_traits_t"); if (! traits || traits->has_year) year = date.year(); if (! traits || traits->has_month) month = date.month(); if (! traits || traits->has_day) day = date.day(); + + TRACE_CTOR(date_specifier_t, "date_t, date_traits_t"); } date_specifier_t(const date_specifier_t& other) : year(other.year), month(other.month), @@ -538,8 +539,8 @@ public: TRACE_CTOR(date_interval_t, ""); } date_interval_t(const string& str) : aligned(false) { - TRACE_CTOR(date_interval_t, "const string&"); parse(str); + TRACE_CTOR(date_interval_t, "const string&"); } date_interval_t(const date_interval_t& other) : range(other.range), diff --git a/src/unistring.h b/src/unistring.h index a33c6e3f..b2278796 100644 --- a/src/unistring.h +++ b/src/unistring.h @@ -64,14 +64,14 @@ public: } unistring(const std::string& input) { - TRACE_CTOR(unistring, "std::string"); - const char * p = input.c_str(); std::size_t len = input.length(); assert(len < 1024); VERIFY(utf8::is_valid(p, p + len)); utf8::unchecked::utf8to32(p, p + len, std::back_inserter(utf32chars)); + + TRACE_CTOR(unistring, "std::string"); } ~unistring() { TRACE_DTOR(unistring); diff --git a/src/utils.cc b/src/utils.cc index 5a364008..17118904 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -278,16 +278,18 @@ namespace { buf << num; + string number(buf.str()); + int integer_digits = 0; // Count the number of integer digits - for (const char * p = buf.str().c_str(); *p; p++) { + for (const char * p = number.c_str(); *p; p++) { if (*p == '.') break; else if (*p != '-') integer_digits++; } - for (const char * p = buf.str().c_str(); *p; p++) { + for (const char * p = number.c_str(); *p; p++) { if (*p == '.') { obuf << *p; assert(integer_digits <= 3); @@ -335,7 +337,7 @@ namespace { void report_count_map(std::ostream& out, object_count_map& the_map) { foreach (object_count_map::value_type& pair, the_map) { - out << " " << std::right << std::setw(12); + out << " " << std::right << std::setw(18); stream_commified_number(out, pair.second.first); out << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); @@ -433,7 +435,7 @@ void report_memory(std::ostream& out, bool report_all) out << "Live memory:" << std::endl; foreach (const memory_map::value_type& pair, *live_memory) { - out << " " << std::right << std::setw(12) << pair.first + out << " " << std::right << std::setw(18) << pair.first << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); out << " " << std::left << pair.second.first @@ -455,7 +457,7 @@ void report_memory(std::ostream& out, bool report_all) out << "Live objects:" << std::endl; foreach (const objects_map::value_type& pair, *live_objects) { - out << " " << std::right << std::setw(12) << pair.first + out << " " << std::right << std::setw(18) << pair.first << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); out << " " << std::left << pair.second.first diff --git a/src/value.h b/src/value.h index a95968c2..d128bb89 100644 --- a/src/value.h +++ b/src/value.h @@ -179,8 +179,8 @@ public: */ explicit storage_t(const storage_t& rhs) : type(rhs.type), refc(0) { - TRACE_CTOR(value_t::storage_t, "copy"); *this = rhs; + TRACE_CTOR(value_t::storage_t, "copy"); } storage_t& operator=(const storage_t& rhs); @@ -290,73 +290,75 @@ public: } value_t(const bool val) { - TRACE_CTOR(value_t, "const bool"); set_boolean(val); + TRACE_CTOR(value_t, "const bool"); } value_t(const datetime_t& val) { - TRACE_CTOR(value_t, "const datetime_t&"); set_datetime(val); + TRACE_CTOR(value_t, "const datetime_t&"); } value_t(const date_t& val) { - TRACE_CTOR(value_t, "const date_t&"); set_date(val); + TRACE_CTOR(value_t, "const date_t&"); } value_t(const long val) { - TRACE_CTOR(value_t, "const long"); set_long(val); + TRACE_CTOR(value_t, "const long"); } value_t(const unsigned long val) { - TRACE_CTOR(value_t, "const unsigned long"); set_amount(val); + TRACE_CTOR(value_t, "const unsigned long"); } value_t(const double val) { - TRACE_CTOR(value_t, "const double"); set_amount(val); + TRACE_CTOR(value_t, "const double"); } value_t(const amount_t& val) { - TRACE_CTOR(value_t, "const amount_t&"); set_amount(val); + TRACE_CTOR(value_t, "const amount_t&"); } value_t(const balance_t& val) { - TRACE_CTOR(value_t, "const balance_t&"); set_balance(val); + TRACE_CTOR(value_t, "const balance_t&"); } value_t(const mask_t& val) { - TRACE_CTOR(value_t, "const mask_t&"); set_mask(val); + TRACE_CTOR(value_t, "const mask_t&"); } explicit value_t(const string& val, bool literal = false) { - TRACE_CTOR(value_t, "const string&, bool"); if (literal) set_string(val); else set_amount(amount_t(val)); + + TRACE_CTOR(value_t, "const string&, bool"); } explicit value_t(const char * val, bool literal = false) { - TRACE_CTOR(value_t, "const char *"); if (literal) set_string(val); else set_amount(amount_t(val)); + + TRACE_CTOR(value_t, "const char *"); } value_t(const sequence_t& val) { - TRACE_CTOR(value_t, "const sequence_t&"); set_sequence(val); + TRACE_CTOR(value_t, "const sequence_t&"); } explicit value_t(scope_t * item) { - TRACE_CTOR(value_t, "scope_t *"); set_scope(item); + TRACE_CTOR(value_t, "scope_t *"); } #if 0 template explicit value_t(T& item) { - TRACE_CTOR(value_t, "T&"); set_any(item); + TRACE_CTOR(value_t, "T&"); } #endif @@ -375,8 +377,8 @@ public: * object. A true copy is only ever made prior to modification. */ value_t(const value_t& val) { - TRACE_CTOR(value_t, "copy"); *this = val; + TRACE_CTOR(value_t, "copy"); } value_t& operator=(const value_t& val) { if (! (this == &val || storage == val.storage)) -- cgit v1.2.3