Changed value_t to use boost::any (more type-safe).
This commit is contained in:
parent
6d4c3ffde5
commit
d726624e60
2 changed files with 104 additions and 240 deletions
187
src/value.cc
187
src/value.cc
|
|
@ -41,128 +41,30 @@ value_t::storage_t& value_t::storage_t::operator=(const value_t::storage_t& rhs)
|
||||||
type = rhs.type;
|
type = rhs.type;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DATETIME:
|
|
||||||
new(reinterpret_cast<datetime_t *>(data))
|
|
||||||
datetime_t(*reinterpret_cast<datetime_t *>
|
|
||||||
(const_cast<char *>(rhs.data)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATE:
|
|
||||||
new(reinterpret_cast<date_t *>(data))
|
|
||||||
date_t(*reinterpret_cast<date_t *>(const_cast<char *>(rhs.data)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AMOUNT:
|
|
||||||
new(reinterpret_cast<amount_t *>(data))
|
|
||||||
amount_t(*reinterpret_cast<amount_t *>
|
|
||||||
(const_cast<char *>(rhs.data)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
*reinterpret_cast<balance_t **>(data) =
|
data = new balance_t(*boost::get<balance_t *>(rhs.data));
|
||||||
new balance_t(**reinterpret_cast<balance_t **>
|
|
||||||
(const_cast<char *>(rhs.data)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STRING:
|
|
||||||
new(reinterpret_cast<string *>(data))
|
|
||||||
string(*reinterpret_cast<string *>(const_cast<char *>(rhs.data)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MASK:
|
|
||||||
new(reinterpret_cast<mask_t *>(data))
|
|
||||||
mask_t(*reinterpret_cast<mask_t *>(const_cast<char *>(rhs.data)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
*reinterpret_cast<sequence_t **>(data) =
|
data = new sequence_t(*boost::get<sequence_t *>(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
|
data = rhs.data;
|
||||||
// std::memcpy
|
|
||||||
std::memcpy(data, rhs.data, sizeof(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::storage_t::destroy()
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case AMOUNT:
|
|
||||||
reinterpret_cast<amount_t *>(data)->~amount_t();
|
|
||||||
break;
|
|
||||||
case BALANCE:
|
|
||||||
checked_delete(*reinterpret_cast<balance_t **>(data));
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
reinterpret_cast<string *>(data)->~string();
|
|
||||||
break;
|
|
||||||
case MASK:
|
|
||||||
reinterpret_cast<mask_t *>(data)->~mask_t();
|
|
||||||
break;
|
|
||||||
case SEQUENCE:
|
|
||||||
checked_delete(*reinterpret_cast<sequence_t **>(data));
|
|
||||||
break;
|
|
||||||
case POINTER:
|
|
||||||
reinterpret_cast<boost::any *>(data)->~any();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
type = VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void value_t::initialize()
|
void value_t::initialize()
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_ON)
|
|
||||||
LOGGER("value.init");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
true_value = new storage_t;
|
true_value = new storage_t;
|
||||||
true_value->type = BOOLEAN;
|
true_value->type = BOOLEAN;
|
||||||
*reinterpret_cast<bool *>(true_value->data) = true;
|
boost::get<bool>(true_value->data) = true;
|
||||||
|
|
||||||
false_value = new storage_t;
|
false_value = new storage_t;
|
||||||
false_value->type = BOOLEAN;
|
false_value->type = BOOLEAN;
|
||||||
*reinterpret_cast<bool *>(false_value->data) = false;
|
boost::get<bool>(true_value->data) = false;
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(bool));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(datetime_t));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(date_t));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(long));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(amount_t));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(balance_t *));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(string));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(mask_t));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(sequence_t *));
|
|
||||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(boost::any));
|
|
||||||
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(bool)
|
|
||||||
<< " sizeof(bool)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(datetime_t)
|
|
||||||
<< " sizeof(datetime_t)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(date_t)
|
|
||||||
<< " sizeof(date_t)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(long)
|
|
||||||
<< " sizeof(long)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(amount_t)
|
|
||||||
<< " sizeof(amount_t)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(balance_t *)
|
|
||||||
<< " sizeof(balance_t *)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(string)
|
|
||||||
<< " sizeof(string)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(mask_t)
|
|
||||||
<< " sizeof(mask_t)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(sequence_t *)
|
|
||||||
<< " sizeof(sequence_t *)");
|
|
||||||
DEBUG_(std::setw(3) << std::right << sizeof(boost::any)
|
|
||||||
<< " sizeof(boost::any)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::shutdown()
|
void value_t::shutdown()
|
||||||
|
|
@ -171,13 +73,6 @@ void value_t::shutdown()
|
||||||
false_value = intrusive_ptr<storage_t>();
|
false_value = intrusive_ptr<storage_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::_dup()
|
|
||||||
{
|
|
||||||
assert(storage);
|
|
||||||
if (storage->refc > 1)
|
|
||||||
storage = new storage_t(*storage.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
value_t::operator bool() const
|
value_t::operator bool() const
|
||||||
{
|
{
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
|
|
@ -1263,69 +1158,33 @@ value_t value_t::unrounded() const
|
||||||
return NULL_VALUE;
|
return NULL_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
void value_t::annotate(const annotation_t& details)
|
||||||
value_t value_t::annotated_price() const
|
|
||||||
{
|
{
|
||||||
switch (type()) {
|
if (is_amount())
|
||||||
case AMOUNT: {
|
as_amount_lval().annotate(details);
|
||||||
optional<amount_t> temp = as_amount().annotation_details().price;
|
else
|
||||||
if (! temp)
|
throw_(value_error, "Cannot annotate " << label());
|
||||||
return false;
|
|
||||||
return *temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw_(value_error, "Cannot find the annotated price of " << label());
|
|
||||||
return NULL_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t value_t::annotated_date() const
|
bool value_t::is_annotated() const
|
||||||
{
|
{
|
||||||
switch (type()) {
|
if (is_amount())
|
||||||
case DATETIME:
|
return as_amount().is_annotated();
|
||||||
return *this;
|
else
|
||||||
case DATE:
|
throw_(value_error,
|
||||||
return *this;
|
"Cannot determine whether " << label() << " is annotated");
|
||||||
|
return false;
|
||||||
case AMOUNT: {
|
|
||||||
optional<datetime_t> temp = as_amount().annotation_details().date;
|
|
||||||
if (! temp)
|
|
||||||
return false;
|
|
||||||
return *temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw_(value_error, "Cannot find the annotated date of " << label());
|
|
||||||
return NULL_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t value_t::annotated_tag() const
|
annotation_t& value_t::annotation()
|
||||||
{
|
{
|
||||||
switch (type()) {
|
if (is_amount())
|
||||||
case AMOUNT: {
|
return as_amount_lval().annotation();
|
||||||
optional<string> temp = as_amount().annotation_details().tag;
|
else {
|
||||||
if (! temp)
|
throw_(value_error, "Cannot request annotation of " << label());
|
||||||
return false;
|
return as_amount_lval().annotation(); // quiet g++ warning
|
||||||
return string_value(*temp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case STRING:
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw_(value_error, "Cannot find the annotated tag of " << label());
|
|
||||||
return NULL_VALUE;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
value_t value_t::strip_annotations(const keep_details_t& what_to_keep) const
|
value_t value_t::strip_annotations(const keep_details_t& what_to_keep) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
157
src/value.h
157
src/value.h
|
|
@ -125,7 +125,18 @@ private:
|
||||||
* The `type' member holds the value_t::type_t value representing
|
* The `type' member holds the value_t::type_t value representing
|
||||||
* the type of the object stored.
|
* the type of the object stored.
|
||||||
*/
|
*/
|
||||||
char data[sizeof(amount_t)];
|
variant<bool, // BOOLEAN
|
||||||
|
datetime_t, // DATETIME
|
||||||
|
date_t, // DATE
|
||||||
|
long, // INTEGER
|
||||||
|
amount_t, // AMOUNT
|
||||||
|
balance_t *, // BALANCE
|
||||||
|
string, // STRING
|
||||||
|
mask_t, // MASK
|
||||||
|
sequence_t *, // SEQUENCE
|
||||||
|
boost::any // POINTER
|
||||||
|
> data;
|
||||||
|
|
||||||
type_t type;
|
type_t type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -157,10 +168,18 @@ private:
|
||||||
TRACE_DTOR(value_t::storage_t);
|
TRACE_DTOR(value_t::storage_t);
|
||||||
DEBUG("value.storage.refcount", "Destroying " << this);
|
DEBUG("value.storage.refcount", "Destroying " << this);
|
||||||
assert(refc == 0);
|
assert(refc == 0);
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy();
|
switch (type) {
|
||||||
|
case BALANCE:
|
||||||
|
checked_delete(boost::get<balance_t *>(data));
|
||||||
|
break;
|
||||||
|
case SEQUENCE:
|
||||||
|
checked_delete(boost::get<sequence_t *>(data));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
@ -202,7 +221,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual data for each value_t is kept in the `storage' member.
|
* The actual data for each value_t is kept in reference counted storage.
|
||||||
* Data is modified using a copy-on-write policy.
|
* Data is modified using a copy-on-write policy.
|
||||||
*/
|
*/
|
||||||
intrusive_ptr<storage_t> storage;
|
intrusive_ptr<storage_t> storage;
|
||||||
|
|
@ -213,20 +232,19 @@ private:
|
||||||
*
|
*
|
||||||
* _clear() removes our pointer to the current value and initializes
|
* _clear() removes our pointer to the current value and initializes
|
||||||
* a new storage bin 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 were
|
|
||||||
* uninitialized.
|
|
||||||
*/
|
*/
|
||||||
void _dup();
|
void _dup() {
|
||||||
void _clear() {
|
assert(storage);
|
||||||
if (! storage || storage->refc > 1)
|
if (storage->refc > 1)
|
||||||
storage = new storage_t;
|
storage = new storage_t(*storage.get());
|
||||||
else
|
|
||||||
storage->destroy();
|
|
||||||
}
|
}
|
||||||
void _reset() {
|
void _clear() {
|
||||||
if (storage)
|
if (! storage || storage->refc > 1) {
|
||||||
storage = intrusive_ptr<storage_t>();
|
storage = new storage_t;
|
||||||
|
} else {
|
||||||
|
storage->data = false; // destruct any other type
|
||||||
|
storage->type = VOID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -455,7 +473,7 @@ 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);
|
||||||
if (new_type == VOID) {
|
if (new_type == VOID) {
|
||||||
_reset();
|
storage.reset();
|
||||||
assert(is_null());
|
assert(is_null());
|
||||||
} else {
|
} else {
|
||||||
_clear();
|
_clear();
|
||||||
|
|
@ -500,11 +518,11 @@ public:
|
||||||
bool& as_boolean_lval() {
|
bool& as_boolean_lval() {
|
||||||
assert(is_boolean());
|
assert(is_boolean());
|
||||||
_dup();
|
_dup();
|
||||||
return *reinterpret_cast<bool *>(storage->data);
|
return boost::get<bool>(storage->data);
|
||||||
}
|
}
|
||||||
const bool& as_boolean() const {
|
const bool& as_boolean() const {
|
||||||
assert(is_boolean());
|
assert(is_boolean());
|
||||||
return *reinterpret_cast<bool *>(storage->data);
|
return boost::get<bool>(storage->data);
|
||||||
}
|
}
|
||||||
void set_boolean(const bool val) {
|
void set_boolean(const bool val) {
|
||||||
set_type(BOOLEAN);
|
set_type(BOOLEAN);
|
||||||
|
|
@ -517,15 +535,15 @@ public:
|
||||||
datetime_t& as_datetime_lval() {
|
datetime_t& as_datetime_lval() {
|
||||||
assert(is_datetime());
|
assert(is_datetime());
|
||||||
_dup();
|
_dup();
|
||||||
return *reinterpret_cast<datetime_t *>(storage->data);
|
return boost::get<datetime_t>(storage->data);
|
||||||
}
|
}
|
||||||
const datetime_t& as_datetime() const {
|
const datetime_t& as_datetime() const {
|
||||||
assert(is_datetime());
|
assert(is_datetime());
|
||||||
return *reinterpret_cast<datetime_t *>(storage->data);
|
return boost::get<datetime_t>(storage->data);
|
||||||
}
|
}
|
||||||
void set_datetime(const datetime_t& val) {
|
void set_datetime(const datetime_t& val) {
|
||||||
set_type(DATETIME);
|
set_type(DATETIME);
|
||||||
new(reinterpret_cast<datetime_t *>(storage->data)) datetime_t(val);
|
storage->data = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_date() const {
|
bool is_date() const {
|
||||||
|
|
@ -534,15 +552,15 @@ public:
|
||||||
date_t& as_date_lval() {
|
date_t& as_date_lval() {
|
||||||
assert(is_date());
|
assert(is_date());
|
||||||
_dup();
|
_dup();
|
||||||
return *reinterpret_cast<date_t *>(storage->data);
|
return boost::get<date_t>(storage->data);
|
||||||
}
|
}
|
||||||
const date_t& as_date() const {
|
const date_t& as_date() const {
|
||||||
assert(is_date());
|
assert(is_date());
|
||||||
return *reinterpret_cast<date_t *>(storage->data);
|
return boost::get<date_t>(storage->data);
|
||||||
}
|
}
|
||||||
void set_date(const date_t& val) {
|
void set_date(const date_t& val) {
|
||||||
set_type(DATE);
|
set_type(DATE);
|
||||||
new(reinterpret_cast<date_t *>(storage->data)) date_t(val);
|
storage->data = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_long() const {
|
bool is_long() const {
|
||||||
|
|
@ -551,15 +569,15 @@ public:
|
||||||
long& as_long_lval() {
|
long& as_long_lval() {
|
||||||
assert(is_long());
|
assert(is_long());
|
||||||
_dup();
|
_dup();
|
||||||
return *reinterpret_cast<long *>(storage->data);
|
return boost::get<long>(storage->data);
|
||||||
}
|
}
|
||||||
const long& as_long() const {
|
const long& as_long() const {
|
||||||
assert(is_long());
|
assert(is_long());
|
||||||
return *reinterpret_cast<long *>(storage->data);
|
return boost::get<long>(storage->data);
|
||||||
}
|
}
|
||||||
void set_long(const long val) {
|
void set_long(const long val) {
|
||||||
set_type(INTEGER);
|
set_type(INTEGER);
|
||||||
*reinterpret_cast<long *>(storage->data) = val;
|
storage->data = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_amount() const {
|
bool is_amount() const {
|
||||||
|
|
@ -568,20 +586,16 @@ public:
|
||||||
amount_t& as_amount_lval() {
|
amount_t& as_amount_lval() {
|
||||||
assert(is_amount());
|
assert(is_amount());
|
||||||
_dup();
|
_dup();
|
||||||
amount_t& amt(*reinterpret_cast<amount_t *>(storage->data));
|
return boost::get<amount_t>(storage->data);
|
||||||
assert(amt.valid());
|
|
||||||
return amt;
|
|
||||||
}
|
}
|
||||||
const amount_t& as_amount() const {
|
const amount_t& as_amount() const {
|
||||||
assert(is_amount());
|
assert(is_amount());
|
||||||
amount_t& amt(*reinterpret_cast<amount_t *>(storage->data));
|
return boost::get<amount_t>(storage->data);
|
||||||
assert(amt.valid());
|
|
||||||
return amt;
|
|
||||||
}
|
}
|
||||||
void set_amount(const amount_t& val) {
|
void set_amount(const amount_t& val) {
|
||||||
assert(val.valid());
|
assert(val.valid());
|
||||||
set_type(AMOUNT);
|
set_type(AMOUNT);
|
||||||
new(reinterpret_cast<amount_t *>(storage->data)) amount_t(val);
|
storage->data = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_balance() const {
|
bool is_balance() const {
|
||||||
|
|
@ -590,20 +604,16 @@ public:
|
||||||
balance_t& as_balance_lval() {
|
balance_t& as_balance_lval() {
|
||||||
assert(is_balance());
|
assert(is_balance());
|
||||||
_dup();
|
_dup();
|
||||||
balance_t& bal(**reinterpret_cast<balance_t **>(storage->data));
|
return *boost::get<balance_t *>(storage->data);
|
||||||
assert(bal.valid());
|
|
||||||
return bal;
|
|
||||||
}
|
}
|
||||||
const balance_t& as_balance() const {
|
const balance_t& as_balance() const {
|
||||||
assert(is_balance());
|
assert(is_balance());
|
||||||
balance_t& bal(**reinterpret_cast<balance_t **>(storage->data));
|
return *boost::get<balance_t *>(storage->data);
|
||||||
assert(bal.valid());
|
|
||||||
return bal;
|
|
||||||
}
|
}
|
||||||
void set_balance(const balance_t& val) {
|
void set_balance(const balance_t& val) {
|
||||||
assert(val.valid());
|
assert(val.valid());
|
||||||
set_type(BALANCE);
|
set_type(BALANCE);
|
||||||
*reinterpret_cast<balance_t **>(storage->data) = new balance_t(val);
|
storage->data = new balance_t(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_string() const {
|
bool is_string() const {
|
||||||
|
|
@ -612,19 +622,19 @@ public:
|
||||||
string& as_string_lval() {
|
string& as_string_lval() {
|
||||||
assert(is_string());
|
assert(is_string());
|
||||||
_dup();
|
_dup();
|
||||||
return *reinterpret_cast<string *>(storage->data);
|
return boost::get<string>(storage->data);
|
||||||
}
|
}
|
||||||
const string& as_string() const {
|
const string& as_string() const {
|
||||||
assert(is_string());
|
assert(is_string());
|
||||||
return *reinterpret_cast<string *>(storage->data);
|
return boost::get<string>(storage->data);
|
||||||
}
|
}
|
||||||
void set_string(const string& val = "") {
|
void set_string(const string& val = "") {
|
||||||
set_type(STRING);
|
set_type(STRING);
|
||||||
new(reinterpret_cast<string *>(storage->data)) string(val);
|
storage->data = val;
|
||||||
}
|
}
|
||||||
void set_string(const char * val = "") {
|
void set_string(const char * val = "") {
|
||||||
set_type(STRING);
|
set_type(STRING);
|
||||||
new(reinterpret_cast<string *>(storage->data)) string(val);
|
storage->data = string(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_mask() const {
|
bool is_mask() const {
|
||||||
|
|
@ -633,19 +643,19 @@ public:
|
||||||
mask_t& as_mask_lval() {
|
mask_t& as_mask_lval() {
|
||||||
assert(is_mask());
|
assert(is_mask());
|
||||||
_dup();
|
_dup();
|
||||||
return *reinterpret_cast<mask_t *>(storage->data);
|
return boost::get<mask_t>(storage->data);
|
||||||
}
|
}
|
||||||
const mask_t& as_mask() const {
|
const mask_t& as_mask() const {
|
||||||
assert(is_mask());
|
assert(is_mask());
|
||||||
return *reinterpret_cast<mask_t *>(storage->data);
|
return boost::get<mask_t>(storage->data);
|
||||||
}
|
}
|
||||||
void set_mask(const string& val) {
|
void set_mask(const string& val) {
|
||||||
set_type(MASK);
|
set_type(MASK);
|
||||||
new(reinterpret_cast<mask_t *>(storage->data)) mask_t(val);
|
storage->data = mask_t(val);
|
||||||
}
|
}
|
||||||
void set_mask(const mask_t& val) {
|
void set_mask(const mask_t& val) {
|
||||||
set_type(MASK);
|
set_type(MASK);
|
||||||
new(reinterpret_cast<mask_t *>(storage->data)) mask_t(val);
|
storage->data = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_sequence() const {
|
bool is_sequence() const {
|
||||||
|
|
@ -654,15 +664,15 @@ public:
|
||||||
sequence_t& as_sequence_lval() {
|
sequence_t& as_sequence_lval() {
|
||||||
assert(is_sequence());
|
assert(is_sequence());
|
||||||
_dup();
|
_dup();
|
||||||
return **reinterpret_cast<sequence_t **>(storage->data);
|
return *boost::get<sequence_t *>(storage->data);
|
||||||
}
|
}
|
||||||
const sequence_t& as_sequence() const {
|
const sequence_t& as_sequence() const {
|
||||||
assert(is_sequence());
|
assert(is_sequence());
|
||||||
return **reinterpret_cast<sequence_t **>(storage->data);
|
return *boost::get<sequence_t *>(storage->data);
|
||||||
}
|
}
|
||||||
void set_sequence(const sequence_t& val) {
|
void set_sequence(const sequence_t& val) {
|
||||||
set_type(SEQUENCE);
|
set_type(SEQUENCE);
|
||||||
*reinterpret_cast<sequence_t **>(storage->data) = new sequence_t(val);
|
storage->data = new sequence_t(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -679,42 +689,36 @@ public:
|
||||||
boost::any& as_any_pointer_lval() {
|
boost::any& as_any_pointer_lval() {
|
||||||
assert(is_pointer());
|
assert(is_pointer());
|
||||||
_dup();
|
_dup();
|
||||||
return *reinterpret_cast<boost::any *>(storage->data);
|
return boost::get<boost::any>(storage->data);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T * as_pointer_lval() {
|
T * as_pointer_lval() {
|
||||||
assert(is_pointer());
|
return any_cast<T *>(as_any_pointer_lval());
|
||||||
_dup();
|
|
||||||
return any_cast<T *>(*reinterpret_cast<boost::any *>(storage->data));
|
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T& as_ref_lval() {
|
T& as_ref_lval() {
|
||||||
assert(is_pointer());
|
return *as_pointer_lval<T>();
|
||||||
_dup();
|
|
||||||
return *any_cast<T *>(*reinterpret_cast<boost::any *>(storage->data));
|
|
||||||
}
|
}
|
||||||
const boost::any& as_any_pointer() const {
|
const boost::any& as_any_pointer() const {
|
||||||
assert(is_pointer());
|
assert(is_pointer());
|
||||||
return *reinterpret_cast<boost::any *>(storage->data);
|
return boost::get<boost::any>(storage->data);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T * as_pointer() const {
|
T * as_pointer() const {
|
||||||
assert(is_pointer());
|
return any_cast<T *>(as_any_pointer());
|
||||||
return any_cast<T *>(*reinterpret_cast<boost::any *>(storage->data));
|
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T& as_ref() const {
|
T& as_ref() const {
|
||||||
assert(is_pointer());
|
return *as_pointer<T>();
|
||||||
return *any_cast<T *>(*reinterpret_cast<boost::any *>(storage->data));
|
|
||||||
}
|
}
|
||||||
void set_any_pointer(const boost::any& val) {
|
void set_any_pointer(const boost::any& val) {
|
||||||
set_type(POINTER);
|
set_type(POINTER);
|
||||||
new(reinterpret_cast<boost::any *>(storage->data)) boost::any(val);
|
storage->data = val;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void set_pointer(T * val) {
|
void set_pointer(T * val) {
|
||||||
set_type(POINTER);
|
set_type(POINTER);
|
||||||
new(reinterpret_cast<boost::any *>(storage->data)) boost::any(val);
|
storage->data = boost::any(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -765,12 +769,13 @@ public:
|
||||||
/**
|
/**
|
||||||
* Annotated commodity methods.
|
* Annotated commodity methods.
|
||||||
*/
|
*/
|
||||||
#if 0
|
void annotate(const annotation_t& details);
|
||||||
// These helper methods only apply to AMOUNT values.
|
bool is_annotated() const;
|
||||||
value_t annotated_price() const;
|
|
||||||
value_t annotated_date() const;
|
annotation_t& annotation();
|
||||||
value_t annotated_tag() const;
|
const annotation_t& annotation() const {
|
||||||
#endif
|
return const_cast<value_t&>(*this).annotation();
|
||||||
|
}
|
||||||
|
|
||||||
value_t strip_annotations(const keep_details_t& what_to_keep) const;
|
value_t strip_annotations(const keep_details_t& what_to_keep) const;
|
||||||
|
|
||||||
|
|
@ -821,14 +826,14 @@ public:
|
||||||
assert(! is_null());
|
assert(! is_null());
|
||||||
|
|
||||||
if (! is_sequence()) {
|
if (! is_sequence()) {
|
||||||
_reset();
|
storage.reset();
|
||||||
} else {
|
} else {
|
||||||
as_sequence_lval().pop_back();
|
as_sequence_lval().pop_back();
|
||||||
|
|
||||||
const sequence_t& seq(as_sequence());
|
const sequence_t& seq(as_sequence());
|
||||||
std::size_t new_size = seq.size();
|
std::size_t new_size = seq.size();
|
||||||
if (new_size == 0)
|
if (new_size == 0)
|
||||||
_reset();
|
storage.reset();
|
||||||
else if (new_size == 1)
|
else if (new_size == 1)
|
||||||
*this = seq.front();
|
*this = seq.front();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue