Changed the value object to allocate its larger members.
This commit is contained in:
parent
7ddf6baf2c
commit
565d8eeb87
2 changed files with 73 additions and 28 deletions
42
src/value.cc
42
src/value.cc
|
|
@ -44,16 +44,16 @@ void value_t::storage_t::destroy()
|
|||
((amount_t *)data)->~amount_t();
|
||||
break;
|
||||
case BALANCE:
|
||||
((balance_t *)data)->~balance_t();
|
||||
checked_delete(*(balance_t **)data);
|
||||
break;
|
||||
case BALANCE_PAIR:
|
||||
((balance_pair_t *)data)->~balance_pair_t();
|
||||
checked_delete(*(balance_pair_t **)data);
|
||||
break;
|
||||
case STRING:
|
||||
((string *)data)->~string();
|
||||
break;
|
||||
case SEQUENCE:
|
||||
((sequence_t *)data)->~sequence_t();
|
||||
checked_delete(*(sequence_t **)data);
|
||||
break;
|
||||
case POINTER:
|
||||
((boost::any *)data)->~any();
|
||||
|
|
@ -67,6 +67,10 @@ void value_t::storage_t::destroy()
|
|||
|
||||
void value_t::initialize()
|
||||
{
|
||||
#if 0
|
||||
LOGGER("value.initialize");
|
||||
#endif
|
||||
|
||||
true_value = new storage_t;
|
||||
true_value->type = BOOLEAN;
|
||||
*(bool *) true_value->data = true;
|
||||
|
|
@ -74,6 +78,38 @@ void value_t::initialize()
|
|||
false_value = new storage_t;
|
||||
false_value->type = BOOLEAN;
|
||||
*(bool *) false_value->data = false;
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(bool));
|
||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(moment_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(balance_pair_t *));
|
||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(string));
|
||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(sequence_t *));
|
||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(xml::node_t *));
|
||||
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(boost::any));
|
||||
|
||||
#if 0
|
||||
DEBUG_(std::setw(3) << std::right << sizeof(bool)
|
||||
<< " sizeof(bool)");
|
||||
DEBUG_(std::setw(3) << std::right << sizeof(moment_t)
|
||||
<< " sizeof(moment_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(balance_pair_t *)
|
||||
<< " sizeof(balance_pair_t *)");
|
||||
DEBUG_(std::setw(3) << std::right << sizeof(string)
|
||||
<< " sizeof(string)");
|
||||
DEBUG_(std::setw(3) << std::right << sizeof(sequence_t *)
|
||||
<< " sizeof(sequence_t *)");
|
||||
DEBUG_(std::setw(3) << std::right << sizeof(boost::any)
|
||||
<< " sizeof(boost::any)");
|
||||
#endif
|
||||
}
|
||||
|
||||
void value_t::shutdown()
|
||||
|
|
|
|||
59
src/value.h
59
src/value.h
|
|
@ -82,25 +82,16 @@ public:
|
|||
private:
|
||||
class storage_t
|
||||
{
|
||||
char data[sizeof(balance_pair_t)];
|
||||
char data[sizeof(amount_t)];
|
||||
type_t type;
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(bool));
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(moment_t));
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(long));
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(amount_t));
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(balance_t));
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(string));
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(sequence_t));
|
||||
BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(xml::node_t *));
|
||||
|
||||
explicit storage_t() : type(VOID), refc(0) {
|
||||
TRACE_CTOR(value_t::storage_t, "");
|
||||
}
|
||||
explicit storage_t(const storage_t& rhs)
|
||||
: type(rhs.type), refc(0) {
|
||||
TRACE_CTOR(value_t::storage_t, "");
|
||||
std::memcpy(data, rhs.data, sizeof(balance_pair_t));
|
||||
std::memcpy(data, rhs.data, sizeof(data));
|
||||
}
|
||||
|
||||
public: // so `checked_delete' can access it
|
||||
|
|
@ -114,7 +105,7 @@ private:
|
|||
private:
|
||||
storage_t& operator=(const storage_t& rhs) {
|
||||
type = rhs.type;
|
||||
std::memcpy(data, rhs.data, sizeof(balance_pair_t));
|
||||
std::memcpy(data, rhs.data, sizeof(data));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -244,8 +235,28 @@ public:
|
|||
*/
|
||||
void _dup() {
|
||||
assert(storage);
|
||||
if (storage->refc > 1)
|
||||
if (storage->refc > 1) {
|
||||
storage = new storage_t(*storage.get());
|
||||
|
||||
// If the data referenced by storage is an allocated pointer, we
|
||||
// need to create a new object in order to achieve duplication.
|
||||
switch (storage->type) {
|
||||
case BALANCE:
|
||||
*(balance_t **) storage->data =
|
||||
new balance_t(**(balance_t **) storage->data);
|
||||
break;
|
||||
case BALANCE_PAIR:
|
||||
*(balance_pair_t **) storage->data =
|
||||
new balance_pair_t(**(balance_pair_t **) storage->data);
|
||||
break;
|
||||
case SEQUENCE:
|
||||
*(sequence_t **) storage->data =
|
||||
new sequence_t(**(sequence_t **) storage->data);
|
||||
break;
|
||||
default:
|
||||
break; // everything else has been duplicated
|
||||
}
|
||||
}
|
||||
}
|
||||
void _clear() {
|
||||
if (! storage || storage->refc > 1)
|
||||
|
|
@ -254,10 +265,8 @@ public:
|
|||
storage->destroy();
|
||||
}
|
||||
void _reset() {
|
||||
if (storage) {
|
||||
storage->destroy();
|
||||
if (storage)
|
||||
storage = intrusive_ptr<storage_t>();
|
||||
}
|
||||
}
|
||||
|
||||
operator bool() const;
|
||||
|
|
@ -367,15 +376,15 @@ public:
|
|||
balance_t& as_balance_lval() {
|
||||
assert(is_balance());
|
||||
_dup();
|
||||
return *(balance_t *) storage->data;
|
||||
return **(balance_t **) storage->data;
|
||||
}
|
||||
const balance_t& as_balance() const {
|
||||
assert(is_balance());
|
||||
return *(balance_t *) storage->data;
|
||||
return **(balance_t **) storage->data;
|
||||
}
|
||||
void set_balance(const balance_t& val) {
|
||||
set_type(BALANCE);
|
||||
new((balance_t *) storage->data) balance_t(val);
|
||||
*(balance_t **) storage->data = new balance_t(val);
|
||||
}
|
||||
|
||||
bool is_balance_pair() const {
|
||||
|
|
@ -384,15 +393,15 @@ public:
|
|||
balance_pair_t& as_balance_pair_lval() {
|
||||
assert(is_balance_pair());
|
||||
_dup();
|
||||
return *(balance_pair_t *) storage->data;
|
||||
return **(balance_pair_t **) storage->data;
|
||||
}
|
||||
const balance_pair_t& as_balance_pair() const {
|
||||
assert(is_balance_pair());
|
||||
return *(balance_pair_t *) storage->data;
|
||||
return **(balance_pair_t **) storage->data;
|
||||
}
|
||||
void set_balance_pair(const balance_pair_t& val) {
|
||||
set_type(BALANCE_PAIR);
|
||||
new((balance_pair_t *) storage->data) balance_pair_t(val);
|
||||
*(balance_pair_t **) storage->data = new balance_pair_t(val);
|
||||
}
|
||||
|
||||
bool is_string() const {
|
||||
|
|
@ -418,15 +427,15 @@ public:
|
|||
sequence_t& as_sequence_lval() {
|
||||
assert(is_sequence());
|
||||
_dup();
|
||||
return *(sequence_t *) storage->data;
|
||||
return **(sequence_t **) storage->data;
|
||||
}
|
||||
const sequence_t& as_sequence() const {
|
||||
assert(is_sequence());
|
||||
return *(sequence_t *) storage->data;
|
||||
return **(sequence_t **) storage->data;
|
||||
}
|
||||
void set_sequence(const sequence_t& val) {
|
||||
set_type(SEQUENCE);
|
||||
new((sequence_t *) storage->data) sequence_t(val);
|
||||
*(sequence_t **) storage->data = new sequence_t(val);
|
||||
}
|
||||
|
||||
bool is_xml_node() const {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue