summaryrefslogtreecommitdiff
path: root/src/amount.h
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2007-05-02 03:04:20 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:38:35 -0400
commit230e03166f061387e7e25591bd2df6acad4195ee (patch)
tree34d80727f5efa12714f592e1010b51efbc9ba587 /src/amount.h
parente70b80d6fe1ed6da6812eb3f4c77570a18eb2bf3 (diff)
downloadfork-ledger-230e03166f061387e7e25591bd2df6acad4195ee.tar.gz
fork-ledger-230e03166f061387e7e25591bd2df6acad4195ee.tar.bz2
fork-ledger-230e03166f061387e7e25591bd2df6acad4195ee.zip
In the middle of switching to using boost/operators.hpp
Diffstat (limited to 'src/amount.h')
-rw-r--r--src/amount.h560
1 files changed, 71 insertions, 489 deletions
diff --git a/src/amount.h b/src/amount.h
index e1f7d6ef..b4b5df54 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -55,6 +55,8 @@ extern bool do_cleanup;
class commodity_t;
+DECLARE_EXCEPTION(amount_error);
+
/**
* @class amount_t
*
@@ -67,8 +69,7 @@ class commodity_t;
* uncommoditized numbers, no display truncation is ever done.
* Internally, precision is always kept to an excessive degree.
*/
-
-class amount_t
+class amount_t : public ordered_field_operators<amount_t>
{
public:
class bigint_t;
@@ -105,6 +106,10 @@ class amount_t
else
commodity_ = NULL;
}
+ amount_t(const long val);
+ amount_t(const unsigned long val);
+ amount_t(const double val);
+
amount_t(const string& val) : quantity(NULL) {
TRACE_CTOR(amount_t, "const string&");
parse(val);
@@ -113,63 +118,29 @@ class amount_t
TRACE_CTOR(amount_t, "const char *");
parse(val);
}
- amount_t(const long val);
- amount_t(const unsigned long val);
- amount_t(const double val);
- // destructor
~amount_t() {
TRACE_DTOR(amount_t);
if (quantity)
_release();
}
- amount_t number() const {
- if (! has_commodity())
- return *this;
- amount_t temp(*this);
- temp.clear_commodity();
- return temp;
- }
-
- bool has_commodity() const;
- void set_commodity(commodity_t& comm) {
- commodity_ = &comm;
- }
- void clear_commodity() {
- commodity_ = NULL;
- }
-
- commodity_t& commodity() const;
-
- void annotate_commodity(const optional<amount_t>& tprice,
- const optional<moment_t>& tdate = optional<moment_t>(),
- const optional<string>& ttag = optional<string>());
-
- amount_t strip_annotations(const bool _keep_price = keep_price,
- const bool _keep_date = keep_date,
- const bool _keep_tag = keep_tag) const;
-
- optional<amount_t> price() const;
- optional<moment_t> date() const;
- optional<string> tag() const;
-
- bool null() const {
- return ! quantity && ! has_commodity();
- }
-
// assignment operator
amount_t& operator=(const amount_t& amt);
+#if 0
+ amount_t& operator=(const double val);
+ amount_t& operator=(const unsigned long val);
+ amount_t& operator=(const long val);
amount_t& operator=(const string& val);
amount_t& operator=(const char * val);
- amount_t& operator=(const long val);
- amount_t& operator=(const unsigned long val);
- amount_t& operator=(const double val);
+#endif
- // general methods
- amount_t round(unsigned int prec) const;
- amount_t round() const;
- amount_t unround() const;
+ // comparisons between amounts
+ int compare(const amount_t& amt) const;
+ bool operator==(const amount_t& amt) const;
+ bool operator<(const amount_t& amt) const {
+ return compare(amt) < 0;
+ }
// in-place arithmetic
amount_t& operator+=(const amount_t& amt);
@@ -177,70 +148,6 @@ class amount_t
amount_t& operator*=(const amount_t& amt);
amount_t& operator/=(const amount_t& amt);
- template <typename T>
- amount_t& operator+=(T val) {
- return *this += amount_t(val);
- }
- template <typename T>
- amount_t& operator-=(T val) {
- return *this -= amount_t(val);
- }
- template <typename T>
- amount_t& operator*=(T val) {
- return *this *= amount_t(val);
- }
- template <typename T>
- amount_t& operator/=(T val) {
- return *this /= amount_t(val);
- }
-
- // simple arithmetic
- amount_t operator+(const amount_t& amt) const {
- amount_t temp = *this;
- temp += amt;
- return temp;
- }
- amount_t operator-(const amount_t& amt) const {
- amount_t temp = *this;
- temp -= amt;
- return temp;
- }
- amount_t operator*(const amount_t& amt) const {
- amount_t temp = *this;
- temp *= amt;
- return temp;
- }
- amount_t operator/(const amount_t& amt) const {
- amount_t temp = *this;
- temp /= amt;
- return temp;
- }
-
- template <typename T>
- amount_t operator+(T val) const {
- amount_t temp = *this;
- temp += val;
- return temp;
- }
- template <typename T>
- amount_t operator-(T val) const {
- amount_t temp = *this;
- temp -= val;
- return temp;
- }
- template <typename T>
- amount_t operator*(T val) const {
- amount_t temp = *this;
- temp *= val;
- return temp;
- }
- template <typename T>
- amount_t operator/(T val) const {
- amount_t temp = *this;
- temp /= val;
- return temp;
- }
-
// unary negation
void in_place_negate();
amount_t negate() const {
@@ -261,76 +168,66 @@ class amount_t
operator bool() const {
return ! zero();
}
- operator string() const {
- return to_string();
- }
- operator long() const;
- operator double() const;
-
- string to_string() const;
- string to_fullstring() const;
- string quantity_string() const;
+ // Methods relating to this amount's commodity
- // comparisons between amounts
- int compare(const amount_t& amt) const;
-
- bool operator<(const amount_t& amt) const {
- return compare(amt) < 0;
- }
- bool operator<=(const amount_t& amt) const {
- return compare(amt) <= 0;
+ bool is_null() const {
+ return ! quantity && ! has_commodity();
}
- bool operator>(const amount_t& amt) const {
- return compare(amt) > 0;
+
+ amount_t number() const {
+ if (! has_commodity())
+ return *this;
+ amount_t temp(*this);
+ temp.clear_commodity();
+ return temp;
}
- bool operator>=(const amount_t& amt) const {
- return compare(amt) >= 0;
+
+ bool has_commodity() const;
+ void set_commodity(commodity_t& comm) {
+ commodity_ = &comm;
}
- bool operator==(const amount_t& amt) const;
- bool operator!=(const amount_t& amt) const;
-
- template <typename T>
- void parse_num(T num) {
- std::ostringstream temp;
- temp << num;
- std::istringstream in(temp.str());
- parse(in);
+ void clear_commodity() {
+ commodity_ = NULL;
}
- // POD comparisons
-#define AMOUNT_CMP_INT(OP) \
- template <typename T> \
- bool operator OP (T num) const { \
- if (num == 0) { \
- return sign() OP 0; \
- } else { \
- amount_t amt; \
- amt.parse_num(num); \
- return *this OP amt; \
- } \
- }
+ commodity_t& commodity() const;
+
+ void annotate_commodity(const optional<amount_t>& tprice,
+ const optional<moment_t>& tdate = optional<moment_t>(),
+ const optional<string>& ttag = optional<string>());
+
+ amount_t strip_annotations(const bool _keep_price = keep_price,
+ const bool _keep_date = keep_date,
+ const bool _keep_tag = keep_tag) const;
- AMOUNT_CMP_INT(<)
- AMOUNT_CMP_INT(<=)
- AMOUNT_CMP_INT(>)
- AMOUNT_CMP_INT(>=)
- AMOUNT_CMP_INT(==)
+ optional<amount_t> price() const;
+ optional<moment_t> date() const;
+ optional<string> tag() const;
- template <typename T>
- bool operator!=(T num) const {
- return ! (*this == num);
+#if 0
+ // string and numeric conversions
+ operator string() const {
+ return to_string();
}
+ operator long() const;
+ operator double() const;
+#endif
- amount_t value(const moment_t& moment) const;
+ string to_string() const;
+ string to_fullstring() const;
+ string quantity_string() const;
+ // general methods
+ amount_t round(unsigned int prec) const;
+ amount_t round() const;
+ amount_t unround() const;
+ amount_t value(const moment_t& moment) const;
amount_t abs() const {
- if (*this < 0)
+ if (sign() < 0)
return negate();
return *this;
}
-
- void in_place_reduce();
amount_t reduce() const {
amount_t temp(*this);
temp.in_place_reduce();
@@ -339,6 +236,8 @@ class amount_t
bool valid() const;
+ void in_place_reduce();
+
static amount_t exact(const string& value);
// This function is special, and exists only to support a custom
@@ -407,51 +306,6 @@ inline string amount_t::quantity_string() const {
return bufstream.str();
}
-#define DEFINE_AMOUNT_OPERATORS(T) \
-inline amount_t operator+(const T val, const amount_t& amt) { \
- amount_t temp(val); \
- temp += amt; \
- return temp; \
-} \
-inline amount_t operator-(const T val, const amount_t& amt) { \
- amount_t temp(val); \
- temp -= amt; \
- return temp; \
-} \
-inline amount_t operator*(const T val, const amount_t& amt) { \
- amount_t temp(val); \
- temp *= amt; \
- return temp; \
-} \
-inline amount_t operator/(const T val, const amount_t& amt) { \
- amount_t temp(val); \
- temp /= amt; \
- return temp; \
-} \
- \
-inline bool operator<(const T val, const amount_t& amt) { \
- return amount_t(val) < amt; \
-} \
-inline bool operator<=(const T val, const amount_t& amt) { \
- return amount_t(val) <= amt; \
-} \
-inline bool operator>(const T val, const amount_t& amt) { \
- return amount_t(val) > amt; \
-} \
-inline bool operator>=(const T val, const amount_t& amt) { \
- return amount_t(val) >= amt; \
-} \
-inline bool operator==(const T val, const amount_t& amt) { \
- return amount_t(val) == amt; \
-} \
-inline bool operator!=(const T val, const amount_t& amt) { \
- return amount_t(val) != amt; \
-}
-
-DEFINE_AMOUNT_OPERATORS(long)
-DEFINE_AMOUNT_OPERATORS(unsigned long)
-DEFINE_AMOUNT_OPERATORS(double)
-
inline std::ostream& operator<<(std::ostream& out, const amount_t& amt) {
amt.print(out, false, amount_t::full_strings);
return out;
@@ -461,282 +315,16 @@ inline std::istream& operator>>(std::istream& in, amount_t& amt) {
return in;
}
+} // namespace ledger
-#define COMMODITY_STYLE_DEFAULTS 0x0000
-#define COMMODITY_STYLE_SUFFIXED 0x0001
-#define COMMODITY_STYLE_SEPARATED 0x0002
-#define COMMODITY_STYLE_EUROPEAN 0x0004
-#define COMMODITY_STYLE_THOUSANDS 0x0008
-#define COMMODITY_STYLE_NOMARKET 0x0010
-#define COMMODITY_STYLE_BUILTIN 0x0020
-
-typedef std::map<const moment_t, amount_t> history_map;
-typedef std::pair<const moment_t, amount_t> history_pair;
-
-class commodity_base_t;
-
-typedef std::map<const string, commodity_base_t *> base_commodities_map;
-typedef std::pair<const string, commodity_base_t *> base_commodities_pair;
-
-class commodity_base_t
-{
- public:
- friend class commodity_t;
- friend class annotated_commodity_t;
-
- typedef unsigned long ident_t;
-
- ident_t ident;
- string name;
- string note;
- unsigned char precision;
- unsigned char flags;
- amount_t * smaller;
- amount_t * larger;
-
- commodity_base_t()
- : precision(0), flags(COMMODITY_STYLE_DEFAULTS),
- smaller(NULL), larger(NULL), history(NULL) {
- TRACE_CTOR(commodity_base_t, "");
- }
-
- commodity_base_t(const commodity_base_t&) {
- TRACE_CTOR(commodity_base_t, "copy");
- assert(0);
- }
-
- commodity_base_t(const string& _symbol,
- unsigned int _precision = 0,
- unsigned int _flags = COMMODITY_STYLE_DEFAULTS)
- : precision(_precision), flags(_flags),
- smaller(NULL), larger(NULL), symbol(_symbol), history(NULL) {
- TRACE_CTOR(commodity_base_t, "const string&, unsigned int, unsigned int");
- }
-
- ~commodity_base_t() {
- TRACE_DTOR(commodity_base_t);
- if (history) checked_delete(history);
- if (smaller) checked_delete(smaller);
- if (larger) checked_delete(larger);
- }
-
- static base_commodities_map commodities;
- static commodity_base_t * create(const string& symbol);
-
- string symbol;
-
- struct history_t {
- history_map prices;
- ptime last_lookup;
- history_t() : last_lookup() {}
- };
- history_t * history;
-
- void add_price(const moment_t& date, const amount_t& price);
- bool remove_price(const moment_t& date);
- amount_t value(const moment_t& moment = now);
-
- class updater_t {
- public:
- virtual ~updater_t() {}
- virtual void operator()(commodity_base_t& commodity,
- const moment_t& moment,
- const moment_t& date,
- const moment_t& last,
- amount_t& price) = 0;
- };
- friend class updater_t;
-
- static updater_t * updater;
-};
-
-typedef std::map<const string, commodity_t *> commodities_map;
-typedef std::pair<const string, commodity_t *> commodities_pair;
-
-typedef std::vector<commodity_t *> commodities_array;
-
-class commodity_t
-{
- friend class annotated_commodity_t;
-
- public:
- // This map remembers all commodities that have been defined.
-
- static commodities_map commodities;
- static commodities_array * commodities_by_ident;
- static bool commodities_sorted;
- static commodity_t * null_commodity;
- static commodity_t * default_commodity;
-
- static commodity_t * create(const string& symbol);
- static commodity_t * find(const string& name);
- static commodity_t * find_or_create(const string& symbol);
-
- static bool needs_quotes(const string& symbol);
-
- static void make_alias(const string& symbol,
- commodity_t * commodity);
-
- // These are specific to each commodity reference
-
- typedef unsigned long ident_t;
-
- ident_t ident;
- commodity_base_t * base;
- string qualified_symbol;
- bool annotated;
-
- public:
- explicit commodity_t() : base(NULL), annotated(false) {
- TRACE_CTOR(commodity_t, "");
- }
- commodity_t(const commodity_t& o)
- : ident(o.ident), base(o.base),
- qualified_symbol(o.qualified_symbol), annotated(o.annotated) {
- TRACE_CTOR(commodity_t, "copy");
- }
- virtual ~commodity_t() {
- TRACE_DTOR(commodity_t);
- }
-
- operator bool() const {
- return this != null_commodity;
- }
- virtual bool operator==(const commodity_t& comm) const {
- if (comm.annotated)
- return comm == *this;
- return base == comm.base;
- }
- bool operator!=(const commodity_t& comm) const {
- return ! (*this == comm);
- }
-
- string base_symbol() const {
- return base->symbol;
- }
- string symbol() const {
- return qualified_symbol;
- }
-
- void write(std::ostream& out) const {
- out << symbol();
- }
-
- string name() const {
- return base->name;
- }
- void set_name(const string& arg) {
- base->name = arg;
- }
-
- string note() const {
- return base->note;
- }
- void set_note(const string& arg) {
- base->note = arg;
- }
-
- unsigned char precision() const {
- return base->precision;
- }
- void set_precision(unsigned char arg) {
- base->precision = arg;
- }
-
- unsigned char flags() const {
- return base->flags;
- }
- void set_flags(unsigned char arg) {
- base->flags = arg;
- }
- void add_flags(unsigned char arg) {
- base->flags |= arg;
- }
- void drop_flags(unsigned char arg) {
- base->flags &= ~arg;
- }
-
- amount_t * smaller() const {
- return base->smaller;
- }
- void set_smaller(const amount_t& arg) {
- if (base->smaller)
- checked_delete(base->smaller);
- base->smaller = new amount_t(arg);
- }
-
- amount_t * larger() const {
- return base->larger;
- }
- void set_larger(const amount_t& arg) {
- if (base->larger)
- checked_delete(base->larger);
- base->larger = new amount_t(arg);
- }
-
- commodity_base_t::history_t * history() const {
- return base->history;
- }
-
- void add_price(const moment_t& date, const amount_t& price) {
- return base->add_price(date, price);
- }
- bool remove_price(const moment_t& date) {
- return base->remove_price(date);
- }
- amount_t value(const moment_t& moment = now) const {
- return base->value(moment);
- }
-
- bool valid() const;
-};
-
-class annotated_commodity_t : public commodity_t
-{
- public:
- const commodity_t * ptr;
-
- optional<amount_t> price;
- optional<moment_t> date;
- optional<string> tag;
-
- explicit annotated_commodity_t() {
- TRACE_CTOR(annotated_commodity_t, "");
- annotated = true;
- }
- virtual ~annotated_commodity_t() {
- TRACE_DTOR(annotated_commodity_t);
- }
-
- virtual bool operator==(const commodity_t& comm) const;
-
- void write_annotations(std::ostream& out) const {
- annotated_commodity_t::write_annotations(out, price, date, tag);
- }
-
- static void write_annotations(std::ostream& out,
- const optional<amount_t>& price,
- const optional<moment_t>& date,
- const optional<string>& tag);
-
- private:
- static commodity_t * create(const commodity_t& comm,
- const optional<amount_t>& price,
- const optional<moment_t>& date,
- const optional<string>& tag,
- const string& mapping_key);
-
- static commodity_t * find_or_create(const commodity_t& comm,
- const optional<amount_t>& price,
- const optional<moment_t>& date,
- const optional<string>& tag);
+#include "commodity.h"
- friend class amount_t;
-};
+namespace ledger {
-inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) {
- out << comm.symbol();
- return out;
+inline bool amount_t::operator==(const amount_t& amt) const {
+ if (commodity() != amt.commodity())
+ return false;
+ return compare(amt) == 0;
}
inline amount_t amount_t::round() const {
@@ -756,12 +344,6 @@ inline commodity_t& amount_t::commodity() const {
void parse_conversion(const string& larger_str,
const string& smaller_str);
-DECLARE_EXCEPTION(amount_error);
-
-struct compare_amount_commodities {
- bool operator()(const amount_t * left, const amount_t * right) const;
-};
-
} // namespace ledger
#endif // _AMOUNT_H