diff options
Diffstat (limited to 'amount.h')
-rw-r--r-- | amount.h | 631 |
1 files changed, 0 insertions, 631 deletions
diff --git a/amount.h b/amount.h deleted file mode 100644 index ef1d2a3d..00000000 --- a/amount.h +++ /dev/null @@ -1,631 +0,0 @@ -#ifndef _AMOUNT_H -#define _AMOUNT_H - -#include <map> -#include <stack> -#include <string> -#include <memory> -#include <cctype> -#include <iostream> -#include <sstream> -#include <cassert> -#include <exception> - -#include "datetime.h" -#include "debug.h" -#include "error.h" - -namespace ledger { - -extern bool do_cleanup; - -class commodity_t; - -class amount_t -{ - public: - class bigint_t; - - static bool keep_price; - static bool keep_date; - static bool keep_tag; - static bool keep_base; - - protected: - void _init(); - void _copy(const amount_t& amt); - void _release(); - void _dup(); - void _resize(unsigned int prec); - - void _clear() { - if (quantity) { - assert(commodity_); - _release(); - quantity = NULL; - commodity_ = NULL; - } else { - assert(! commodity_); - } - } - - bigint_t * quantity; - commodity_t * commodity_; - - public: - // constructors - amount_t() : quantity(NULL), commodity_(NULL) {} - amount_t(const amount_t& amt) : quantity(NULL) { - if (amt.quantity) - _copy(amt); - else - commodity_ = NULL; - } - amount_t(const std::string& value) : quantity(NULL) { - parse(value); - } - amount_t(const char * value) : quantity(NULL) { - parse(value); - } - amount_t(const bool value); - amount_t(const long value); - amount_t(const unsigned long value); - amount_t(const double value); - - // destructor - ~amount_t() { - if (quantity) - _release(); - } - - commodity_t& commodity() const; - void set_commodity(commodity_t& comm) { - commodity_ = &comm; - } - void annotate_commodity(const amount_t& price, - const datetime_t& date = datetime_t(), - const std::string& tag = ""); - amount_t strip_annotations(const bool _keep_price = keep_price, - const bool _keep_date = keep_date, - const bool _keep_tag = keep_tag) const; - void clear_commodity() { - commodity_ = NULL; - } - amount_t price() const; - datetime_t date() const; - - bool null() const { - return ! quantity && ! commodity_; - } - - std::string quantity_string() const; - - // assignment operator - amount_t& operator=(const amount_t& amt); - amount_t& operator=(const std::string& value); - amount_t& operator=(const char * value); - amount_t& operator=(const bool value); - amount_t& operator=(const long value); - amount_t& operator=(const unsigned long value); - amount_t& operator=(const double value); - - // general methods - amount_t round(unsigned int prec) const; - amount_t round() const; - amount_t unround() const; - - // in-place arithmetic - amount_t& operator+=(const amount_t& amt); - amount_t& operator-=(const amount_t& amt); - amount_t& operator*=(const amount_t& amt); - amount_t& operator/=(const amount_t& amt); - - template <typename T> - amount_t& operator+=(T value) { - return *this += amount_t(value); - } - template <typename T> - amount_t& operator-=(T value) { - return *this -= amount_t(value); - } - template <typename T> - amount_t& operator*=(T value) { - return *this *= amount_t(value); - } - template <typename T> - amount_t& operator/=(T value) { - return *this /= amount_t(value); - } - - // 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 value) const { - amount_t temp = *this; - temp += value; - return temp; - } - template <typename T> - amount_t operator-(T value) const { - amount_t temp = *this; - temp -= value; - return temp; - } - template <typename T> - amount_t operator*(T value) const { - amount_t temp = *this; - temp *= value; - return temp; - } - template <typename T> - amount_t operator/(T value) const { - amount_t temp = *this; - temp /= value; - return temp; - } - - // unary negation - void negate(); - amount_t negated() const { - amount_t temp = *this; - temp.negate(); - return temp; - } - amount_t operator-() const { - return negated(); - } - - // test for non-zero (use ! for zero) - operator bool() const; - operator long() const; - operator double() const; - - bool realzero() const; - - // 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 operator>(const amount_t& amt) const { - return compare(amt) > 0; - } - bool operator>=(const amount_t& amt) const { - return compare(amt) >= 0; - } - 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); - } - - int sign() const; - - // 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; \ - } \ - } - - AMOUNT_CMP_INT(<) - AMOUNT_CMP_INT(<=) - AMOUNT_CMP_INT(>) - AMOUNT_CMP_INT(>=) - AMOUNT_CMP_INT(==) - - template <typename T> - bool operator!=(T num) const { - return ! (*this == num); - } - - amount_t value(const datetime_t& moment) const; - - void abs() { - if (*this < 0) - negate(); - } - -#define AMOUNT_PARSE_NO_MIGRATE 0x01 -#define AMOUNT_PARSE_NO_REDUCE 0x02 -#define AMOUNT_PARSE_SOFT_FAIL 0x04 - - bool parse(std::istream& in, unsigned char flags = 0); - bool parse(const std::string& str, unsigned char flags = 0); - void reduce(); - - amount_t reduced() const { - amount_t temp(*this); - temp.reduce(); - return temp; - } - - void read_quantity(char *& data); - void read_quantity(std::istream& in); - void write_quantity(std::ostream& out) const; - - bool valid() const; - - // Classes that are friends, and help to implement this class - - friend std::ostream& operator<<(std::ostream& out, const amount_t& amt); - friend std::istream& operator>>(std::istream& in, amount_t& amt); - - friend unsigned int sizeof_bigint_t(); - - friend void read_binary_amount(char *& data, amount_t& amt); - friend void write_binary_amount(std::ostream& out, const amount_t& amt); - - // This function is special, and exists only to support a custom - // optimization in binary.cc (which offers a significant enough gain - // to be worth the trouble). - - friend void clean_commodity_history(char * item_pool, - char * item_pool_end); - - friend void parse_annotations(std::istream& in, amount_t& price, - datetime_t& date, std::string& tag); -}; - -unsigned int sizeof_bigint_t(); - -void parse_quantity(std::istream& in, std::string& value); -void parse_commodity(std::istream& in, std::string& symbol); -void parse_annotations(std::istream& in, const std::string& symbol, - std::string& name, std::string& price, - std::string& date, std::string& tag); -void parse_conversion(const std::string& larger, - const std::string& smaller); - -inline bool is_quote_or_paren(char * p) { - return *p == '"' || *p == '{' || *p == '[' || *p == '('; -} - -inline char * scan_past_quotes_and_parens(char * expr) -{ - std::stack<char> paren_stack; - - char * p; - for (p = expr; *p; p++) { - if (*p == '"' || - ((*p == '(' || ((*p == '{' || *p == '[') && - paren_stack.top() != '(')) && - paren_stack.top() != '"')) { - paren_stack.push(*p); - } - else if ((*p == ')' && paren_stack.top() == '(') || - (*p == '}' && paren_stack.top() == '{') || - (*p == ']' && paren_stack.top() == '[') || - (*p == '"' && paren_stack.top() == '"')) { - paren_stack.pop(); - if (paren_stack.size() == 0) - break; - } - } - return p; -} - -inline amount_t abs(const amount_t& amt) { - return amt < 0 ? amt.negated() : amt; -} - -std::ostream& operator<<(std::ostream& out, const amount_t& amt); - -inline std::istream& operator>>(std::istream& in, amount_t& amt) { - amt.parse(in); - return in; -} - - -#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 datetime_t, amount_t> history_map; -typedef std::pair<const datetime_t, amount_t> history_pair; - -class commodity_base_t; - -typedef std::map<const std::string, commodity_base_t *> base_commodities_map; -typedef std::pair<const std::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; - std::string name; - std::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) {} - - commodity_base_t(const std::string& _symbol, - unsigned int _precision = 0, - unsigned int _flags = COMMODITY_STYLE_DEFAULTS) - : precision(_precision), flags(_flags), - smaller(NULL), larger(NULL), symbol(_symbol), history(NULL) {} - - ~commodity_base_t() { - if (history) delete history; - if (smaller) delete smaller; - if (larger) delete larger; - } - - static base_commodities_map commodities; - static commodity_base_t * create(const std::string& symbol); - - std::string symbol; - - struct history_t { - history_map prices; - datetime_t last_lookup; - datetime_t bogus_time; - history_t() : last_lookup(0), bogus_time(0) {} - }; - history_t * history; - - void add_price(const datetime_t& date, const amount_t& price); - bool remove_price(const datetime_t& date); - amount_t value(const datetime_t& moment = datetime_t::now); - - class updater_t { - public: - virtual ~updater_t() {} - virtual void operator()(commodity_base_t& commodity, - const datetime_t& moment, - const datetime_t& date, - const datetime_t& last, - amount_t& price) = 0; - }; - friend class updater_t; - - static updater_t * updater; -}; - -typedef std::map<const std::string, commodity_t *> commodities_map; -typedef std::pair<const std::string, commodity_t *> commodities_pair; - -class commodity_t -{ - friend class annotated_commodity_t; - - public: - // This map remembers all commodities that have been defined. - - static commodities_map commodities; - static bool commodities_sorted; - static commodity_t * null_commodity; - static commodity_t * default_commodity; - - static commodity_t * create(const std::string& symbol); - static commodity_t * find(const std::string& name); - static commodity_t * find_or_create(const std::string& symbol); - - static bool needs_quotes(const std::string& symbol); - - static void make_alias(const std::string& symbol, - commodity_t * commodity); - - // These are specific to each commodity reference - - typedef unsigned long ident_t; - - ident_t ident; - commodity_base_t * base; - std::string qualified_symbol; - bool annotated; - - public: - explicit commodity_t() : base(NULL), annotated(false) {} - virtual ~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); - } - - std::string base_symbol() const { - return base->symbol; - } - std::string symbol() const { - return qualified_symbol; - } - - void write(std::ostream& out) const { - out << symbol(); - } - - std::string name() const { - return base->name; - } - void set_name(const std::string& arg) { - base->name = arg; - } - - std::string note() const { - return base->note; - } - void set_note(const std::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) - 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) - delete base->larger; - base->larger = new amount_t(arg); - } - - commodity_base_t::history_t * history() const { - return base->history; - } - - void add_price(const datetime_t& date, const amount_t& price) { - return base->add_price(date, price); - } - bool remove_price(const datetime_t& date) { - return base->remove_price(date); - } - amount_t value(const datetime_t& moment = datetime_t::now) const { - return base->value(moment); - } - - bool valid() const; -}; - -class annotated_commodity_t : public commodity_t -{ - public: - const commodity_t * ptr; - - amount_t price; - datetime_t date; - std::string tag; - - explicit annotated_commodity_t() { - annotated = true; - } - - 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 amount_t& price, - const datetime_t& date, - const std::string& tag); - - private: - static commodity_t * create(const commodity_t& comm, - const amount_t& price, - const datetime_t& date, - const std::string& tag, - const std::string& mapping_key); - - static commodity_t * find_or_create(const commodity_t& comm, - const amount_t& price, - const datetime_t& date, - const std::string& tag); - - friend class amount_t; -}; - -inline std::ostream& operator<<(std::ostream& out, - const commodity_t& comm) { - out << comm.symbol(); - return out; -} - -inline amount_t amount_t::round() const { - return round(commodity().precision()); -} - -inline commodity_t& amount_t::commodity() const { - if (! commodity_) - return *commodity_t::null_commodity; - else - return *commodity_; -} - -class amount_error : public error { - public: - amount_error(const std::string& reason) throw() : error(reason) {} - virtual ~amount_error() throw() {} -}; - -struct compare_amount_commodities { - bool operator()(const amount_t * left, const amount_t * right) const; -}; - -} // namespace ledger - -#endif // _AMOUNT_H |