Cleaned up some method names and documentation relating to values.

This commit is contained in:
John Wiegley 2008-07-31 05:05:24 -04:00
parent 8276b51f56
commit 8afd926a27
7 changed files with 129 additions and 103 deletions

View file

@ -778,7 +778,7 @@ bool amount_t::fits_in_long() const
} }
void amount_t::annotate_commodity(const annotation_t& details) void amount_t::annotate(const annotation_t& details)
{ {
commodity_t * this_base; commodity_t * this_base;
annotated_commodity_t * this_ann = NULL; annotated_commodity_t * this_ann = NULL;
@ -810,7 +810,7 @@ void amount_t::annotate_commodity(const annotation_t& details)
DEBUG("amounts.commodities", " Annotated amount is " << *this); DEBUG("amounts.commodities", " Annotated amount is " << *this);
} }
bool amount_t::commodity_annotated() const bool amount_t::annotated() const
{ {
if (! quantity) if (! quantity)
throw_(amount_error, throw_(amount_error,
@ -820,7 +820,7 @@ bool amount_t::commodity_annotated() const
return commodity().annotated; return commodity().annotated;
} }
annotation_t& amount_t::annotation_details() annotation_t& amount_t::annotation()
{ {
if (! quantity) if (! quantity)
throw_(amount_error, throw_(amount_error,

View file

@ -551,12 +551,12 @@ public:
* amount_t::keep_price, amount_t::keep_date and amount_t::keep_tag * amount_t::keep_price, amount_t::keep_date and amount_t::keep_tag
* have been set to (which all default to false). * have been set to (which all default to false).
*/ */
void annotate_commodity(const annotation_t& details); void annotate(const annotation_t& details);
bool commodity_annotated() const; bool annotated() const;
annotation_t& annotation_details(); annotation_t& annotation();
const annotation_t& annotation_details() const { const annotation_t& annotation() const {
return const_cast<amount_t&>(*this).annotation_details(); return const_cast<amount_t&>(*this).annotation();
} }
amount_t strip_annotations(const bool _keep_price = keep_price, amount_t strip_annotations(const bool _keep_price = keep_price,

View file

@ -182,7 +182,7 @@ amount_t commodity_t::exchange(const amount_t& amount,
basis_cost = final_cost; basis_cost = final_cost;
amount_t ann_amount(amount); amount_t ann_amount(amount);
ann_amount.annotate_commodity(annotation_t(per_unit_cost, moment, tag)); ann_amount.annotate(annotation_t(per_unit_cost, moment, tag));
return ann_amount; return ann_amount;
} }

View file

@ -293,8 +293,8 @@ bool entry_base_t::finalize()
(*x)->cost, none, (*x)->actual_date(), (*x)->cost, none, (*x)->actual_date(),
entry ? entry->code : optional<string>()); entry ? entry->code : optional<string>());
if ((*x)->amount.commodity_annotated()) { if ((*x)->amount.annotated()) {
if (ann_amount.annotation_details().price) { if (ann_amount.annotation().price) {
if (balance.is_null()) if (balance.is_null())
balance = basis_cost - final_cost; balance = basis_cost - final_cost;
else else

View file

@ -251,12 +251,14 @@ xact_t * parse_xact(char * line, account_t * account,
per_unit_cost /= xact->amount; per_unit_cost /= xact->amount;
if (xact->amount.commodity() && if (xact->amount.commodity() &&
! xact->amount.commodity().annotated) ! xact->amount.commodity().annotated) {
xact->amount.annotate_commodity if (xact->entry)
(annotation_t xact->amount.annotate(annotation_t(per_unit_cost,
(per_unit_cost, xact->entry->actual_date(),
xact->entry ? optional<datetime_t>(xact->entry->actual_date()) : none, xact->entry->code));
xact->entry ? optional<string>(xact->entry->code) : none)); else
xact->amount.annotate(annotation_t(per_unit_cost));
}
DEBUG("ledger.textual.parse", "line " << linenum << ": " << DEBUG("ledger.textual.parse", "line " << linenum << ": " <<
"Total cost is " << *xact->cost); "Total cost is " << *xact->cost);

View file

@ -44,22 +44,26 @@ value_t::storage_t& value_t::storage_t::operator=(const value_t::storage_t& rhs)
switch (type) { switch (type) {
case DATETIME: case DATETIME:
new(reinterpret_cast<datetime_t *>(data)) new(reinterpret_cast<datetime_t *>(data))
datetime_t(*reinterpret_cast<datetime_t *>(const_cast<char *>(rhs.data))); datetime_t(*reinterpret_cast<datetime_t *>
(const_cast<char *>(rhs.data)));
break; break;
case AMOUNT: case AMOUNT:
new(reinterpret_cast<amount_t *>(data)) new(reinterpret_cast<amount_t *>(data))
amount_t(*reinterpret_cast<amount_t *>(const_cast<char *>(rhs.data))); amount_t(*reinterpret_cast<amount_t *>
(const_cast<char *>(rhs.data)));
break; break;
case BALANCE: case BALANCE:
*reinterpret_cast<balance_t **>(data) = *reinterpret_cast<balance_t **>(data) =
new balance_t(**reinterpret_cast<balance_t **>(const_cast<char *>(rhs.data))); new balance_t(**reinterpret_cast<balance_t **>
(const_cast<char *>(rhs.data)));
break; break;
case BALANCE_PAIR: case BALANCE_PAIR:
*reinterpret_cast<balance_pair_t **>(data) = *reinterpret_cast<balance_pair_t **>(data) =
new balance_pair_t(**reinterpret_cast<balance_pair_t **>(const_cast<char *>(rhs.data))); new balance_pair_t(**reinterpret_cast<balance_pair_t **>
(const_cast<char *>(rhs.data)));
break; break;
case STRING: case STRING:
@ -69,11 +73,13 @@ value_t::storage_t& value_t::storage_t::operator=(const value_t::storage_t& rhs)
case SEQUENCE: case SEQUENCE:
*reinterpret_cast<sequence_t **>(data) = *reinterpret_cast<sequence_t **>(data) =
new sequence_t(**reinterpret_cast<sequence_t **>(const_cast<char *>(rhs.data))); new sequence_t(**reinterpret_cast<sequence_t **>
(const_cast<char *>(rhs.data)));
break; break;
default: default:
// The rest are fundamental types, which can be copied using std::memcpy // The rest are fundamental types, which can be copied using
// std::memcpy
std::memcpy(data, rhs.data, sizeof(data)); std::memcpy(data, rhs.data, sizeof(data));
break; break;
} }
@ -171,10 +177,10 @@ value_t::operator bool() const
switch (type()) { switch (type()) {
case BOOLEAN: case BOOLEAN:
return as_boolean(); return as_boolean();
case INTEGER:
return as_long();
case DATETIME: case DATETIME:
return is_valid(as_datetime()); return is_valid(as_datetime());
case INTEGER:
return as_long();
case AMOUNT: case AMOUNT:
return as_amount(); return as_amount();
case BALANCE: case BALANCE:
@ -206,17 +212,6 @@ bool value_t::to_boolean() const
} }
} }
long value_t::to_long() const
{
if (is_long()) {
return as_long();
} else {
value_t temp(*this);
temp.in_place_cast(INTEGER);
return temp.as_long();
}
}
datetime_t value_t::to_datetime() const datetime_t value_t::to_datetime() const
{ {
if (is_datetime()) { if (is_datetime()) {
@ -228,6 +223,17 @@ datetime_t value_t::to_datetime() const
} }
} }
long value_t::to_long() const
{
if (is_long()) {
return as_long();
} else {
value_t temp(*this);
temp.in_place_cast(INTEGER);
return temp.as_long();
}
}
amount_t value_t::to_amount() const amount_t value_t::to_amount() const
{ {
if (is_amount()) { if (is_amount()) {
@ -1325,6 +1331,7 @@ value_t value_t::unround() const
return NULL_VALUE; return NULL_VALUE;
} }
#if 0
value_t value_t::annotated_price() const value_t value_t::annotated_price() const
{ {
switch (type()) { switch (type()) {
@ -1367,9 +1374,6 @@ value_t value_t::annotated_date() const
value_t value_t::annotated_tag() const value_t value_t::annotated_tag() const
{ {
switch (type()) { switch (type()) {
case DATETIME:
return *this;
case AMOUNT: { case AMOUNT: {
optional<string> temp = as_amount().annotation_details().tag; optional<string> temp = as_amount().annotation_details().tag;
if (! temp) if (! temp)
@ -1377,6 +1381,9 @@ value_t value_t::annotated_tag() const
return value_t(*temp, true); return value_t(*temp, true);
} }
case STRING:
return *this;
default: default:
break; break;
} }
@ -1384,6 +1391,7 @@ value_t value_t::annotated_tag() const
throw_(value_error, "Cannot find the annotated tag of " << label()); throw_(value_error, "Cannot find the annotated tag of " << label());
return NULL_VALUE; return NULL_VALUE;
} }
#endif
value_t value_t::strip_annotations(const bool keep_price, value_t value_t::strip_annotations(const bool keep_price,
const bool keep_date, const bool keep_date,
@ -1612,8 +1620,10 @@ void value_t::read(const char *& data)
set_long(binary::read_long<unsigned long>(data)); set_long(binary::read_long<unsigned long>(data));
break; break;
case DATETIME: case DATETIME:
#if 0
// jww (2008-04-22): I need to record and read a datetime_t directly // jww (2008-04-22): I need to record and read a datetime_t directly
//set_datetime(read_long<unsigned long>(data)); set_datetime(read_long<unsigned long>(data));
#endif
break; break;
case AMOUNT: { case AMOUNT: {
amount_t temp; amount_t temp;
@ -1621,13 +1631,11 @@ void value_t::read(const char *& data)
set_amount(temp); set_amount(temp);
break; break;
} }
//case BALANCE:
//case BALANCE_PAIR:
default: default:
assert(false);
break; break;
} }
throw_(value_error, "Cannot read " << label() << " from a stream");
} }
void value_t::write(std::ostream& out) const void value_t::write(std::ostream& out) const
@ -1649,12 +1657,11 @@ void value_t::write(std::ostream& out) const
case AMOUNT: case AMOUNT:
as_amount().write(out); as_amount().write(out);
break; break;
//case BALANCE:
//case BALANCE_PAIR:
default: default:
throw new error("Cannot write a balance to the binary cache"); break;
} }
throw_(value_error, "Cannot read " << label() << " to a stream");
} }
bool value_t::valid() const bool value_t::valid() const

125
value.h
View file

@ -207,14 +207,14 @@ private:
intrusive_ptr<storage_t> storage; intrusive_ptr<storage_t> storage;
/** /**
* _dup() makes a private copy of the current value so that it can * _dup() makes a private copy of the current value (if necessary)
* subsequently be modified. * so it can subsequently be modified.
* *
* _clear() removes our pointer to the current value and initializes * _clear() removes our pointer to the current value and initializes
* a new value for things to be stored in. * a new storage bin for things to be stored in.
* *
* _reset() makes the current object appear as if it had been * _reset() makes the current object appear as if it were
* default initialized. * uninitialized.
*/ */
void _dup(); void _dup();
void _clear() { void _clear() {
@ -259,17 +259,24 @@ public:
value_t() { value_t() {
TRACE_CTOR(value_t, ""); TRACE_CTOR(value_t, "");
} }
value_t(const bool val) { value_t(const bool val) {
TRACE_CTOR(value_t, "const bool"); TRACE_CTOR(value_t, "const bool");
set_boolean(val); set_boolean(val);
} }
value_t(const datetime_t val) {
TRACE_CTOR(value_t, "const datetime_t");
set_datetime(val);
}
value_t(const long val) { value_t(const long val) {
TRACE_CTOR(value_t, "const long"); TRACE_CTOR(value_t, "const long");
set_long(val); set_long(val);
} }
value_t(const datetime_t val) { value_t(const unsigned long val) {
TRACE_CTOR(value_t, "const datetime_t"); TRACE_CTOR(value_t, "const unsigned long");
set_datetime(val); set_amount(val);
} }
#ifdef HAVE_GDTOA #ifdef HAVE_GDTOA
value_t(const double val) { value_t(const double val) {
@ -277,10 +284,19 @@ public:
set_amount(val); set_amount(val);
} }
#endif #endif
value_t(const unsigned long val) { value_t(const amount_t& val) {
TRACE_CTOR(value_t, "const unsigned long"); TRACE_CTOR(value_t, "const amount_t&");
set_amount(val); set_amount(val);
} }
value_t(const balance_t& val) {
TRACE_CTOR(value_t, "const balance_t&");
set_balance(val);
}
value_t(const balance_pair_t& val) {
TRACE_CTOR(value_t, "const balance_pair_t&");
set_balance_pair(val);
}
explicit value_t(const string& val, bool literal = false) { explicit value_t(const string& val, bool literal = false) {
TRACE_CTOR(value_t, "const string&, bool"); TRACE_CTOR(value_t, "const string&, bool");
if (literal) if (literal)
@ -295,22 +311,12 @@ public:
else else
set_amount(amount_t(val)); set_amount(amount_t(val));
} }
value_t(const amount_t& val) {
TRACE_CTOR(value_t, "const amount_t&");
set_amount(val);
}
value_t(const balance_t& val) {
TRACE_CTOR(value_t, "const balance_t&");
set_balance(val);
}
value_t(const balance_pair_t& val) {
TRACE_CTOR(value_t, "const balance_pair_t&");
set_balance_pair(val);
}
value_t(const sequence_t& val) { value_t(const sequence_t& val) {
TRACE_CTOR(value_t, "const sequence_t&"); TRACE_CTOR(value_t, "const sequence_t&");
set_sequence(val); set_sequence(val);
} }
template <typename T> template <typename T>
explicit value_t(T * item) { explicit value_t(T * item) {
TRACE_CTOR(value_t, "T *"); TRACE_CTOR(value_t, "T *");
@ -369,8 +375,8 @@ public:
value_t& operator*=(const value_t& val); value_t& operator*=(const value_t& val);
value_t& operator/=(const value_t& val); value_t& operator/=(const value_t& val);
// jww (2008-04-24): This could be expensive; perhaps it should be // This special form of add is use to produce a balance pair by
// optional<amount_t&>&? // simultaneously adding both an amount and its cost.
value_t& add(const amount_t& amount, value_t& add(const amount_t& amount,
const optional<amount_t>& cost = none); const optional<amount_t>& cost = none);
@ -382,7 +388,7 @@ public:
temp.in_place_negate(); temp.in_place_negate();
return temp; return temp;
} }
void in_place_negate(); void in_place_negate(); // exists for efficiency's sake
value_t operator-() const { value_t operator-() const {
return negate(); return negate();
@ -397,9 +403,12 @@ public:
temp.in_place_reduce(); temp.in_place_reduce();
return temp; return temp;
} }
void in_place_reduce(); void in_place_reduce(); // exists for efficiency's sake
// Return the "market value" of a given value at a specific time.
value_t value(const optional<datetime_t>& moment = none) const; value_t value(const optional<datetime_t>& moment = none) const;
value_t cost() const;
/** /**
* Truth tests. * Truth tests.
@ -410,6 +419,7 @@ public:
bool is_zero() const; bool is_zero() const;
bool is_null() const { bool is_null() const {
if (! storage) { if (! storage) {
assert(is_type(VOID));
return true; return true;
} else { } else {
assert(! is_type(VOID)); assert(! is_type(VOID));
@ -422,10 +432,10 @@ public:
assert(result >= VOID && result <= POINTER); assert(result >= VOID && result <= POINTER);
return result; return result;
} }
bool is_type(type_t _type) const { bool is_type(type_t _type) const {
return type() == _type; return type() == _type;
} }
private: private:
void set_type(type_t new_type) { void set_type(type_t new_type) {
assert(new_type >= VOID && new_type <= POINTER); assert(new_type >= VOID && new_type <= POINTER);
@ -485,23 +495,6 @@ public:
storage = val ? true_value : false_value; storage = val ? true_value : false_value;
} }
bool is_long() const {
return is_type(INTEGER);
}
long& as_long_lval() {
assert(is_long());
_dup();
return *reinterpret_cast<long *>(storage->data);
}
const long& as_long() const {
assert(is_long());
return *reinterpret_cast<long *>(storage->data);
}
void set_long(const long val) {
set_type(INTEGER);
*reinterpret_cast<long *>(storage->data) = val;
}
bool is_datetime() const { bool is_datetime() const {
return is_type(DATETIME); return is_type(DATETIME);
} }
@ -519,6 +512,23 @@ public:
new(reinterpret_cast<datetime_t *>(storage->data)) datetime_t(val); new(reinterpret_cast<datetime_t *>(storage->data)) datetime_t(val);
} }
bool is_long() const {
return is_type(INTEGER);
}
long& as_long_lval() {
assert(is_long());
_dup();
return *reinterpret_cast<long *>(storage->data);
}
const long& as_long() const {
assert(is_long());
return *reinterpret_cast<long *>(storage->data);
}
void set_long(const long val) {
set_type(INTEGER);
*reinterpret_cast<long *>(storage->data) = val;
}
bool is_amount() const { bool is_amount() const {
return is_type(AMOUNT); return is_type(AMOUNT);
} }
@ -623,6 +633,14 @@ public:
*reinterpret_cast<sequence_t **>(storage->data) = new sequence_t(val); *reinterpret_cast<sequence_t **>(storage->data) = new sequence_t(val);
} }
/**
* Dealing with pointers is bit involved because we actually deal
* with typed pointers. For example, if you call as_pointer it
* returns a boost::any object, but if you use as_pointer<void>,
* then it returns a void *. The latter form only succeeds if the
* stored pointers was assigned to the value as a void*, otherwise
* it throws an exception.
*/
bool is_pointer() const { bool is_pointer() const {
return is_type(POINTER); return is_type(POINTER);
} }
@ -714,16 +732,19 @@ public:
/** /**
* Annotated commodity methods. * Annotated commodity methods.
*/ */
#if 0
// These helper methods only apply to AMOUNT values.
value_t annotated_price() const; value_t annotated_price() const;
value_t annotated_date() const; value_t annotated_date() const;
value_t annotated_tag() const; value_t annotated_tag() const;
#endif
value_t strip_annotations(const bool keep_price = amount_t::keep_price, value_t strip_annotations(const bool keep_price = amount_t::keep_price,
const bool keep_date = amount_t::keep_date, const bool keep_date = amount_t::keep_date,
const bool keep_tag = amount_t::keep_tag) const; const bool keep_tag = amount_t::keep_tag) const;
/** /**
* Collection-style access methods * Collection-style access methods for SEQUENCE values.
*/ */
value_t& operator[](const int index) { value_t& operator[](const int index) {
assert(! is_null()); assert(! is_null());
@ -803,10 +824,10 @@ public:
return "an uninitialized value"; return "an uninitialized value";
case BOOLEAN: case BOOLEAN:
return "a boolean"; return "a boolean";
case INTEGER:
return "an integer";
case DATETIME: case DATETIME:
return "a date/time"; return "a date/time";
case INTEGER:
return "an integer";
case AMOUNT: case AMOUNT:
return "an amount"; return "an amount";
case BALANCE: case BALANCE:
@ -827,8 +848,6 @@ public:
return "<invalid>"; return "<invalid>";
} }
value_t cost() const;
/** /**
* Printing methods. * Printing methods.
*/ */
@ -837,18 +856,16 @@ public:
void print(std::ostream& out, const bool relaxed = true) const; void print(std::ostream& out, const bool relaxed = true) const;
/** /**
* Serialization methods. An amount may be deserialized from an * Serialization methods. A value may be deserialized from an input
* input stream or a character pointer, and it may be serialized to * stream or a character pointer, and it may be serialized to an
* an output stream. The methods used are: * output stream. The methods used are:
*/ */
void read(const char *& data); void read(const char *& data);
void write(std::ostream& out) const; void write(std::ostream& out) const;
/** /**
* Debugging methods. * Debugging methods.
*/ */
bool valid() const; bool valid() const;
}; };