Added use of boost::optional<> to amount.h

This commit is contained in:
John Wiegley 2007-04-30 12:20:58 +00:00
parent 21af83013f
commit 18aaf588ab
17 changed files with 251 additions and 126 deletions

View file

@ -27,7 +27,8 @@ AM_LFLAGS = -o $(LEX_OUTPUT_ROOT).c
#WARNFLAGS += -Wconversion -Wshorten-64-to-32 -Wsign-compare #WARNFLAGS += -Wconversion -Wshorten-64-to-32 -Wsign-compare
#WARNFLAGS += -Wmissing-field-initializers -pedantic-errors #WARNFLAGS += -Wmissing-field-initializers -pedantic-errors
libledger_la_CPPFLAGS = -I$(top_builddir)/gdtoa -I$(srcdir) -I$(srcdir)/src libledger_la_CPPFLAGS = -I$(top_builddir)/gdtoa -I$(srcdir)/gdtoa \
-I$(srcdir)/src
libledger_la_LDFLAGS = -release 3.0 libledger_la_LDFLAGS = -release 3.0
libledger_la_SOURCES = \ libledger_la_SOURCES = \

View file

@ -355,7 +355,7 @@ AM_LFLAGS = -o $(LEX_OUTPUT_ROOT).c
#WARNFLAGS += -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion #WARNFLAGS += -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion
#WARNFLAGS += -Wconversion -Wshorten-64-to-32 -Wsign-compare #WARNFLAGS += -Wconversion -Wshorten-64-to-32 -Wsign-compare
#WARNFLAGS += -Wmissing-field-initializers -pedantic-errors #WARNFLAGS += -Wmissing-field-initializers -pedantic-errors
libledger_la_CPPFLAGS = -I$(top_builddir)/gdtoa -I$(srcdir) \ libledger_la_CPPFLAGS = -I$(top_builddir)/gdtoa -I$(srcdir)/gdtoa \
-I$(srcdir)/src $(am__append_2) $(am__append_4) \ -I$(srcdir)/src $(am__append_2) $(am__append_4) \
$(am__append_6) $(am__append_8) $(am__append_9) $(am__append_6) $(am__append_8) $(am__append_9)
libledger_la_LDFLAGS = -release 3.0 libledger_la_LDFLAGS = -release 3.0

View file

@ -1,5 +1,6 @@
lib_LTLIBRARIES = libgdtoa.la lib_LTLIBRARIES = libgdtoa.la
libgdtoa_la_LDFLAGS = -release 1.0
libgdtoa_la_CPPFLAGS = -I$(top_builddir) libgdtoa_la_CPPFLAGS = -I$(top_builddir)
libgdtoa_la_SOURCES = \ libgdtoa_la_SOURCES = \
dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c g_ffmt.c \ dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c g_ffmt.c \
@ -11,7 +12,8 @@ libgdtoa_la_SOURCES = \
EXTRA_libgdtoa_la_SOURCES = arithchk.c qnan.c EXTRA_libgdtoa_la_SOURCES = arithchk.c qnan.c
$(libgdtoa_la_SOURCES): arith.h gd_qnan.h BUILT_SOURCES = arith.h gd_qnan.h
CLEANFILES = arith.h gd_qnan.h arithchk qnan
arith.h: arithchk.c arith.h: arithchk.c
$(CC) $(CFLAGS) -o $(top_builddir)/arithchk $< || \ $(CC) $(CFLAGS) -o $(top_builddir)/arithchk $< || \
@ -24,9 +26,4 @@ gd_qnan.h: qnan.c arith.h
$(top_builddir)/qnan > $(top_builddir)/$@ $(top_builddir)/qnan > $(top_builddir)/$@
rm -f $(top_builddir)/qnan rm -f $(top_builddir)/qnan
libgdtoa_la_LDFLAGS = -release 1.0 pkginclude_HEADERS = gdtoa.h gdtoaimp.h arith.h gd_qnan.h
pkginclude_HEADERS = gdtoa.h gdtoaimp.h
CLEANFILES = arithchk qnan
DISTCLEANFILES = arithchk arith.h qnan gd_qnan.h

View file

@ -219,6 +219,7 @@ target_alias = @target_alias@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libgdtoa.la lib_LTLIBRARIES = libgdtoa.la
libgdtoa_la_LDFLAGS = -release 1.0
libgdtoa_la_CPPFLAGS = -I$(top_builddir) libgdtoa_la_CPPFLAGS = -I$(top_builddir)
libgdtoa_la_SOURCES = \ libgdtoa_la_SOURCES = \
dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c g_ffmt.c \ dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c g_ffmt.c \
@ -229,11 +230,10 @@ libgdtoa_la_SOURCES = \
strtord.c strtordd.c strtorf.c strtorx.c strtorxL.c sum.c ulp.c strtord.c strtordd.c strtorf.c strtorx.c strtorxL.c sum.c ulp.c
EXTRA_libgdtoa_la_SOURCES = arithchk.c qnan.c EXTRA_libgdtoa_la_SOURCES = arithchk.c qnan.c
libgdtoa_la_LDFLAGS = -release 1.0 BUILT_SOURCES = arith.h gd_qnan.h
pkginclude_HEADERS = gdtoa.h gdtoaimp.h CLEANFILES = arith.h gd_qnan.h arithchk qnan
CLEANFILES = arithchk qnan pkginclude_HEADERS = gdtoa.h gdtoaimp.h arith.h gd_qnan.h
DISTCLEANFILES = arithchk arith.h qnan gd_qnan.h all: $(BUILT_SOURCES) acconf.h
all: acconf.h
$(MAKE) $(AM_MAKEFLAGS) all-am $(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES: .SUFFIXES:
@ -890,13 +890,15 @@ distcleancheck: distclean
$(distcleancheck_listfiles) ; \ $(distcleancheck_listfiles) ; \
exit 1; } >&2 exit 1; } >&2
check-am: all-am check-am: all-am
check: check-am check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS) acconf.h all-am: Makefile $(LTLIBRARIES) $(HEADERS) acconf.h
installdirs: installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgincludedir)"; do \ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done done
install: install-am install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am install-exec: install-exec-am
install-data: install-data-am install-data: install-data-am
uninstall: uninstall-am uninstall: uninstall-am
@ -917,11 +919,11 @@ clean-generic:
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
@ -1004,8 +1006,6 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS
uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS
$(libgdtoa_la_SOURCES): arith.h gd_qnan.h
arith.h: arithchk.c arith.h: arithchk.c
$(CC) $(CFLAGS) -o $(top_builddir)/arithchk $< || \ $(CC) $(CFLAGS) -o $(top_builddir)/arithchk $< || \
$(CC) -DNO_LONG_LONG $(CFLAGS) -o $(top_builddir)/arithchk $< $(CC) -DNO_LONG_LONG $(CFLAGS) -o $(top_builddir)/arithchk $<

View file

@ -59,11 +59,13 @@ bool amount_t::full_strings = false;
class amount_t::bigint_t class amount_t::bigint_t
{ {
public: public:
typedef uint8_t precision_t;
mpz_t val; mpz_t val;
unsigned char prec; precision_t prec;
unsigned char flags; uint8_t flags;
unsigned int ref; uint_least16_t ref;
unsigned int index; uint_fast32_t index;
bigint_t() : prec(0), flags(0), ref(1), index(0) { bigint_t() : prec(0), flags(0), ref(1), index(0) {
TRACE_CTOR(bigint_t, ""); TRACE_CTOR(bigint_t, "");
@ -245,7 +247,7 @@ amount_t::amount_t(const unsigned long val)
} }
namespace { namespace {
unsigned char convert_double(mpz_t dest, double val) amount_t::bigint_t::precision_t convert_double(mpz_t dest, double val)
{ {
#ifndef HAVE_GDTOA #ifndef HAVE_GDTOA
// This code is far too imprecise to be worthwhile. // This code is far too imprecise to be worthwhile.
@ -285,7 +287,7 @@ namespace {
mpz_set_str(dest, buf, 10); mpz_set_str(dest, buf, 10);
free(buf); free(buf);
return (unsigned char)exp; return amount_t::bigint_t::precision_t(exp);
#else #else
int decpt, sign; int decpt, sign;
char * buf = dtoa(val, 0, 0, &decpt, &sign, NULL); char * buf = dtoa(val, 0, 0, &decpt, &sign, NULL);
@ -830,7 +832,7 @@ void amount_t::print_quantity(std::ostream& out) const
// outputting it. NOTE: `rquotient' is used here as a temp variable! // outputting it. NOTE: `rquotient' is used here as a temp variable!
commodity_t& comm(commodity()); commodity_t& comm(commodity());
unsigned char precision; bigint_t::precision_t precision;
if (! comm || quantity->flags & BIGINT_KEEP_PREC) { if (! comm || quantity->flags & BIGINT_KEEP_PREC) {
mpz_ui_pow_ui(divisor, 10, quantity->prec); mpz_ui_pow_ui(divisor, 10, quantity->prec);
@ -932,7 +934,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
// outputting it. NOTE: `rquotient' is used here as a temp variable! // outputting it. NOTE: `rquotient' is used here as a temp variable!
commodity_t& comm(base.commodity()); commodity_t& comm(base.commodity());
unsigned char precision = 0; bigint_t::precision_t precision = 0;
if (quantity) { if (quantity) {
if (! comm || full_precision || base.quantity->flags & BIGINT_KEEP_PREC) { if (! comm || full_precision || base.quantity->flags & BIGINT_KEEP_PREC) {
@ -1213,7 +1215,7 @@ bool parse_annotations(std::istream& in, amount_t& price,
return has_date; return has_date;
} }
void amount_t::parse(std::istream& in, unsigned char flags) void amount_t::parse(std::istream& in, uint8_t flags)
{ {
// The possible syntax for an amount is: // The possible syntax for an amount is:
// //
@ -1427,8 +1429,8 @@ void amount_t::write(std::ostream& out) const
#ifndef THREADSAFE #ifndef THREADSAFE
static char * bigints; static char * bigints;
static char * bigints_next; static char * bigints_next;
static unsigned int bigints_index; static uint_fast32_t bigints_index;
static unsigned int bigints_count; static uint_fast32_t bigints_count;
#endif #endif
void amount_t::read_quantity(char *& data) void amount_t::read_quantity(char *& data)
@ -1452,14 +1454,14 @@ void amount_t::read_quantity(char *& data)
if (negative) if (negative)
mpz_neg(MPZ(quantity), MPZ(quantity)); mpz_neg(MPZ(quantity), MPZ(quantity));
quantity->prec = *((unsigned char *) data); quantity->prec = *((bigint_t::precision_t *) data);
data += sizeof(unsigned char); data += sizeof(bigint_t::precision_t);
quantity->flags = *((unsigned char *) data); quantity->flags = *((uint8_t *) data);
data += sizeof(unsigned char); data += sizeof(uint8_t);
quantity->flags |= BIGINT_BULK_ALLOC; quantity->flags |= BIGINT_BULK_ALLOC;
} else { } else {
unsigned int index = *((unsigned int *) data); uint_fast32_t index = *((uint_fast32_t *) data);
data += sizeof(unsigned int); data += sizeof(uint_fast32_t);
quantity = (bigint_t *) (bigints + (index - 1) * sizeof(bigint_t)); quantity = (bigint_t *) (bigints + (index - 1) * sizeof(bigint_t));
DEBUG("amounts.refs", DEBUG("amounts.refs",
@ -1533,7 +1535,7 @@ void amount_t::write_quantity(std::ostream& out) const
out.write(&byte, sizeof(byte)); out.write(&byte, sizeof(byte));
out.write((char *)&quantity->prec, sizeof(quantity->prec)); out.write((char *)&quantity->prec, sizeof(quantity->prec));
unsigned char flags = quantity->flags & ~BIGINT_BULK_ALLOC; uint8_t flags = quantity->flags & ~BIGINT_BULK_ALLOC;
assert(sizeof(flags) == sizeof(quantity->flags)); assert(sizeof(flags) == sizeof(quantity->flags));
out.write((char *)&flags, sizeof(flags)); out.write((char *)&flags, sizeof(flags));
} else { } else {
@ -1634,7 +1636,7 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
return t; return t;
} }
amount_t amount_t::price() const optional<amount_t> amount_t::price() const
{ {
if (commodity_ && commodity_->annotated) { if (commodity_ && commodity_->annotated) {
amount_t t(((annotated_commodity_t *)commodity_)->price); amount_t t(((annotated_commodity_t *)commodity_)->price);
@ -1643,10 +1645,10 @@ amount_t amount_t::price() const
"Returning price of " << *this << " = " << t); "Returning price of " << *this << " = " << t);
return t; return t;
} }
return *this; return optional<amount_t>();
} }
moment_t amount_t::date() const optional<moment_t> amount_t::date() const
{ {
if (commodity_ && commodity_->annotated) { if (commodity_ && commodity_->annotated) {
DEBUG("amounts.commodities", DEBUG("amounts.commodities",
@ -1654,7 +1656,18 @@ moment_t amount_t::date() const
<< ((annotated_commodity_t *)commodity_)->date); << ((annotated_commodity_t *)commodity_)->date);
return ((annotated_commodity_t *)commodity_)->date; return ((annotated_commodity_t *)commodity_)->date;
} }
return moment_t(); return optional<moment_t>();
}
optional<string> amount_t::tag() const
{
if (commodity_ && commodity_->annotated) {
DEBUG("amounts.commodities",
"Returning tag of " << *this << " = "
<< ((annotated_commodity_t *)commodity_)->tag);
return ((annotated_commodity_t *)commodity_)->tag;
}
return optional<string>();
} }

View file

@ -48,7 +48,6 @@
#define _AMOUNT_H #define _AMOUNT_H
#include "utils.h" #include "utils.h"
#include "times.h"
namespace ledger { namespace ledger {
@ -126,27 +125,34 @@ class amount_t
} }
amount_t number() const { amount_t number() const {
if (! has_commodity())
return *this;
amount_t temp(*this); amount_t temp(*this);
temp.clear_commodity(); temp.clear_commodity();
return temp; return temp;
} }
bool has_commodity() const; bool has_commodity() const;
commodity_t& commodity() const;
void set_commodity(commodity_t& comm) { void set_commodity(commodity_t& comm) {
commodity_ = &comm; commodity_ = &comm;
} }
void annotate_commodity(const amount_t& price,
const moment_t& date = moment_t(),
const 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() { void clear_commodity() {
commodity_ = NULL; commodity_ = NULL;
} }
amount_t price() const;
moment_t date() const; commodity_t& commodity() const;
void annotate_commodity(const amount_t& price,
const moment_t& date = moment_t(),
const 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;
optional<amount_t> price() const;
optional<moment_t> date() const;
optional<string> tag() const;
bool null() const { bool null() const {
return ! quantity && ! has_commodity(); return ! quantity && ! has_commodity();
@ -732,6 +738,8 @@ inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) {
} }
inline amount_t amount_t::round() const { inline amount_t amount_t::round() const {
if (! has_commodity())
return *this;
return round(commodity().precision()); return round(commodity().precision());
} }
@ -740,10 +748,7 @@ inline bool amount_t::has_commodity() const {
} }
inline commodity_t& amount_t::commodity() const { inline commodity_t& amount_t::commodity() const {
if (! commodity_) return has_commodity() ? *commodity_ : *commodity_t::null_commodity;
return *commodity_t::null_commodity;
else
return *commodity_;
} }
void parse_conversion(const string& larger_str, void parse_conversion(const string& larger_str,

View file

@ -39,30 +39,51 @@ balance_t balance_t::value(const moment_t& moment) const
return temp; return temp;
} }
balance_t balance_t::price() const optional<balance_t> balance_t::price() const
{ {
balance_t temp; optional<balance_t> temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++)
temp += (*i).second.price();
return temp;
}
moment_t balance_t::date() const
{
moment_t temp;
for (amounts_map::const_iterator i = amounts.begin(); for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end(); i != amounts.end();
i++) { i++) {
moment_t tdate = (*i).second.date(); optional<amount_t> i_price = (*i).second.price();
if (! is_valid_moment(temp) && is_valid_moment(tdate)) if (i_price) {
temp = tdate; if (! temp)
else if (temp != tdate) temp = balance_t();
return moment_t(); *temp += *i_price;
}
}
return temp;
}
optional<moment_t> balance_t::date() const
{
optional<moment_t> temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++) {
optional<moment_t> tdate = (*i).second.date();
if (! temp && tdate)
temp = *tdate;
else if (temp && tdate && temp != tdate)
return optional<moment_t>();
}
return temp;
}
optional<string> balance_t::tag() const
{
optional<string> temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++) {
optional<string> ttag = (*i).second.tag();
if (! temp && ttag)
temp = *ttag;
else if (temp && ttag && temp != ttag)
return optional<string>();
} }
return temp; return temp;
} }

View file

@ -435,8 +435,10 @@ class balance_t
amount_t amount(const commodity_t& commodity = amount_t amount(const commodity_t& commodity =
*commodity_t::null_commodity) const; *commodity_t::null_commodity) const;
balance_t value(const moment_t& moment = now) const; balance_t value(const moment_t& moment = now) const;
balance_t price() const;
moment_t date() const; optional<balance_t> price() const;
optional<moment_t> date() const;
optional<string> tag() const;
balance_t balance_t
strip_annotations(const bool keep_price = amount_t::keep_price, strip_annotations(const bool keep_price = amount_t::keep_price,
@ -896,12 +898,16 @@ class balance_pair_t
balance_t value(const moment_t& moment = now) const { balance_t value(const moment_t& moment = now) const {
return quantity.value(moment); return quantity.value(moment);
} }
balance_t price() const {
optional<balance_t> price() const {
return quantity.price(); return quantity.price();
} }
moment_t date() const { optional<moment_t> date() const {
return quantity.date(); return quantity.date();
} }
optional<string> tag() const {
return quantity.tag();
}
balance_t balance_t
strip_annotations(const bool keep_price = amount_t::keep_price, strip_annotations(const bool keep_price = amount_t::keep_price,

View file

@ -23,9 +23,6 @@
#include <parser.h> #include <parser.h>
#include <textual.h> #include <textual.h>
#include <binary.h> #include <binary.h>
#include <gnucash.h>
#include <qif.h>
#include <ofx.h>
#include <report.h> #include <report.h>
#include <transform.h> #include <transform.h>

View file

@ -3,9 +3,12 @@
#else #else
#include <ledger.h> #include <ledger.h>
#endif #endif
#include <option.h>
#include "acconf.h" #include "acconf.h"
#include "option.h"
#include "gnucash.h"
#include "qif.h"
#include "ofx.h"
#ifdef HAVE_UNIX_PIPES #ifdef HAVE_UNIX_PIPES
#include <sys/types.h> #include <sys/types.h>

View file

@ -82,7 +82,7 @@ namespace std {
#define HAVE_GDTOA 1 #define HAVE_GDTOA 1
#ifdef HAVE_GDTOA #ifdef HAVE_GDTOA
#include <gdtoa/gdtoa.h> #include "gdtoa.h"
#endif #endif
extern "C" { extern "C" {

View file

@ -1,4 +1,4 @@
#include "times.h" #include "utils.h"
namespace ledger { namespace ledger {

View file

@ -1,8 +1,6 @@
#ifndef _TIMES_H #ifndef _TIMES_H
#define _TIMES_H #define _TIMES_H
#include "utils.h"
namespace ledger { namespace ledger {
#define SUPPORT_DATE_AND_TIME 1 #define SUPPORT_DATE_AND_TIME 1

View file

@ -1,5 +1,4 @@
#include "utils.h" #include "utils.h"
#include "times.h"
/********************************************************************** /**********************************************************************
* *

View file

@ -3,6 +3,26 @@
#include <system.hh> #include <system.hh>
/**********************************************************************
*
* Default values
*/
#if defined(FULL_DEBUG)
#define VERIFY_ON 1
#define TRACING_ON 1
#define DEBUG_ON 1
#define TIMERS_ON 1
#define FREE_MEMORY 1
#elif defined(NO_DEBUG)
#define NO_ASSERTS 1
#define NO_LOGGING 1
#else
#define VERIFY_ON 1 // compiled in, use --verify to enable
#define TRACING_ON 1 // use --trace X to enable
#define TIMERS_ON 1
#endif
/********************************************************************** /**********************************************************************
* *
* Forward declarations * Forward declarations
@ -29,26 +49,6 @@ namespace ledger {
typedef boost::filesystem::filesystem_error filesystem_error; typedef boost::filesystem::filesystem_error filesystem_error;
} }
/**********************************************************************
*
* Default values
*/
#if defined(FULL_DEBUG)
#define VERIFY_ON 1
#define TRACING_ON 1
#define DEBUG_ON 1
#define TIMERS_ON 1
#define FREE_MEMORY 1
#elif defined(NO_DEBUG)
#define NO_ASSERTS 1
#define NO_LOGGING 1
#else
#define VERIFY_ON 1 // compiled in, use --verify to enable
#define TRACING_ON 1 // use --trace X to enable
#define TIMERS_ON 1 // jww (2007-04-25): is this correct?
#endif
/********************************************************************** /**********************************************************************
* *
* Assertions * Assertions
@ -72,6 +72,10 @@ namespace ledger {
((x) ? ((void)0) : debug_assert(#x, BOOST_CURRENT_FUNCTION, \ ((x) ? ((void)0) : debug_assert(#x, BOOST_CURRENT_FUNCTION, \
__FILE__, __LINE__)) __FILE__, __LINE__))
#else // ! ASSERTS_ON
#define assert(x)
#endif // ASSERTS_ON #endif // ASSERTS_ON
/********************************************************************** /**********************************************************************
@ -429,6 +433,13 @@ inline void throw_unexpected_error(char c, char wanted) {
} // namespace ledger } // namespace ledger
/**********************************************************************
*
* Date/time support classes
*/
#include "times.h"
/********************************************************************** /**********************************************************************
* *
* General utility functions * General utility functions

View file

@ -1981,12 +1981,24 @@ value_t value_t::price() const
case DATETIME: case DATETIME:
throw_(value_error, "Cannot find the price of a date/time"); throw_(value_error, "Cannot find the price of a date/time");
case AMOUNT: case AMOUNT: {
return ((amount_t *) data)->price(); optional<amount_t> temp = ((amount_t *) data)->price();
case BALANCE: if (! temp)
return ((balance_t *) data)->price(); return false;
case BALANCE_PAIR: return *temp;
return ((balance_pair_t *) data)->quantity.price(); }
case BALANCE: {
optional<balance_t> temp = ((balance_t *) data)->price();
if (! temp)
return false;
return *temp;
}
case BALANCE_PAIR: {
optional<balance_t> temp = ((balance_pair_t *) data)->price();
if (! temp)
return false;
return *temp;
}
case STRING: case STRING:
throw_(value_error, "Cannot find the price of a string"); throw_(value_error, "Cannot find the price of a string");
@ -2018,12 +2030,73 @@ value_t value_t::date() const
case DATETIME: case DATETIME:
return *this; return *this;
case AMOUNT: case AMOUNT: {
return ((amount_t *) data)->date(); optional<moment_t> temp = ((amount_t *) data)->date();
case BALANCE: if (! temp)
return ((balance_t *) data)->date(); return false;
case BALANCE_PAIR: return *temp;
return ((balance_pair_t *) data)->quantity.date(); }
case BALANCE: {
optional<moment_t> temp = ((balance_t *) data)->date();
if (! temp)
return false;
return *temp;
}
case BALANCE_PAIR: {
optional<moment_t> temp = ((balance_pair_t *) data)->date();
if (! temp)
return false;
return *temp;
}
case STRING:
throw_(value_error, "Cannot find the date of a string");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().date();
case POINTER:
throw_(value_error, "Cannot find the date of a pointer");
case SEQUENCE:
throw_(value_error, "Cannot find the date of a sequence");
default:
assert(0);
break;
}
assert(0);
return value_t();
}
value_t value_t::tag() const
{
switch (type) {
case BOOLEAN:
throw_(value_error, "Cannot find the date of a boolean");
case INTEGER:
throw_(value_error, "Cannot find the date of an integer");
case DATETIME:
return *this;
case AMOUNT: {
optional<string> temp = ((amount_t *) data)->tag();
if (! temp)
return false;
return *temp;
}
case BALANCE: {
optional<string> temp = ((balance_t *) data)->tag();
if (! temp)
return false;
return *temp;
}
case BALANCE_PAIR: {
optional<string> temp = ((balance_pair_t *) data)->tag();
if (! temp)
return false;
return *temp;
}
case STRING: case STRING:
throw_(value_error, "Cannot find the date of a string"); throw_(value_error, "Cannot find the date of a string");

View file

@ -441,6 +441,7 @@ class value_t
value_t cost() const; value_t cost() const;
value_t price() const; value_t price() const;
value_t date() const; value_t date() const;
value_t tag() const;
value_t cast(type_t cast_type) const { value_t cast(type_t cast_type) const {
value_t temp(*this); value_t temp(*this);