📄 cpp_expression_value.hpp
字号:
break;
case is_uint:
if (rhs.value.ui != 0) {
value.ui /= rhs.value.ui;
type = is_uint;
}
else {
valid = error_division_by_zero; // division by zero
}
break;
}
break;
case is_uint:
if (as_ulong(rhs) != 0)
value.ui /= as_ulong(rhs);
else
valid = error_division_by_zero; // division by zero
break;
case is_bool:
if (as_bool(rhs)) {
switch(rhs.type) {
case is_int:
value.i = (value.b ? 1 : 0) / rhs.value.i;
type = is_int;
break;
case is_uint:
value.i = (value.b ? 1 : 0) / rhs.value.ui;
type = is_int;
break;
case is_bool:
break;
}
}
else {
valid = error_division_by_zero; // division by zero
}
}
return *this;
}
closure_value &operator%= (closure_value const &rhs)
{
switch (type) {
case is_int:
switch(rhs.type) {
case is_bool:
case is_int:
if (as_long(rhs) != 0) {
if (value.i == -value.i && -1 == rhs.value.i) {
// LONG_MIN % -1 on two's complement
valid = error_integer_overflow;
}
else {
value.i %= as_long(rhs);
}
}
else {
valid = error_division_by_zero; // division by zero
}
break;
case is_uint:
if (rhs.value.ui != 0) {
value.ui %= rhs.value.ui;
type = is_uint;
}
else {
valid = error_division_by_zero; // division by zero
}
break;
}
break;
case is_uint:
if (as_ulong(rhs) != 0)
value.ui %= as_ulong(rhs);
else
valid = error_division_by_zero; // division by zero
break;
case is_bool:
if (as_bool(rhs)) {
switch(rhs.type) {
case is_int:
value.i = (value.b ? 1 : 0) % rhs.value.i;
type = is_int;
break;
case is_uint:
value.i = (value.b ? 1 : 0) % rhs.value.ui;
type = is_int;
break;
case is_bool:
break;
}
}
else {
valid = error_division_by_zero; // division by zero
}
}
return *this;
}
friend closure_value
operator- (closure_value const &rhs)
{
switch (rhs.type) {
case is_int:
{
long value = as_long(rhs);
if (value != 0 && value == -value)
return closure_value(-value, error_integer_overflow);
return closure_value(-value, rhs.valid);
}
case is_bool: return closure_value(-as_long(rhs), rhs.valid);
case is_uint: break;
}
long value = as_ulong(rhs);
if (value != 0 && value == -value)
return closure_value(-value, error_integer_overflow);
return closure_value(-value, rhs.valid);
}
friend closure_value
operator~ (closure_value const &rhs)
{
return closure_value(~as_ulong(rhs), rhs.valid);
}
friend closure_value
operator! (closure_value const &rhs)
{
switch (rhs.type) {
case is_int: return closure_value(!as_long(rhs), rhs.valid);
case is_bool: return closure_value(!as_bool(rhs), rhs.valid);
case is_uint: break;
}
return closure_value(!as_ulong(rhs), rhs.valid);
}
// comparison
friend closure_value
operator== (closure_value const &lhs, closure_value const &rhs)
{
bool cmp = false;
switch (lhs.type) {
case is_int:
switch(rhs.type) {
case is_bool: cmp = as_bool(lhs) == rhs.value.b; break;
case is_int: cmp = lhs.value.i == rhs.value.i; break;
case is_uint: cmp = lhs.value.ui == rhs.value.ui; break;
}
break;
case is_uint: cmp = lhs.value.ui == as_ulong(rhs); break;
case is_bool: cmp = lhs.value.b == as_bool(rhs); break;
}
return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator!= (closure_value const &lhs, closure_value const &rhs)
{
return closure_value(!as_bool(lhs == rhs), (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator> (closure_value const &lhs, closure_value const &rhs)
{
bool cmp = false;
switch (lhs.type) {
case is_int:
switch(rhs.type) {
case is_bool: cmp = lhs.value.i > as_long(rhs); break;
case is_int: cmp = lhs.value.i > rhs.value.i; break;
case is_uint: cmp = lhs.value.ui > rhs.value.ui; break;
}
break;
case is_uint: cmp = lhs.value.ui > as_ulong(rhs); break;
case is_bool: cmp = lhs.value.b > as_bool(rhs); break;
}
return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator< (closure_value const &lhs, closure_value const &rhs)
{
bool cmp = false;
switch (lhs.type) {
case is_int:
switch(rhs.type) {
case is_bool: cmp = lhs.value.i < as_long(rhs); break;
case is_int: cmp = lhs.value.i < rhs.value.i; break;
case is_uint: cmp = lhs.value.ui < rhs.value.ui; break;
}
break;
case is_uint: cmp = lhs.value.ui < as_ulong(rhs); break;
case is_bool: cmp = as_bool(lhs) < as_bool(rhs); break;
}
return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator<= (closure_value const &lhs, closure_value const &rhs)
{
return closure_value(!as_bool(lhs > rhs), (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator>= (closure_value const &lhs, closure_value const &rhs)
{
return closure_value(!as_bool(lhs < rhs), (value_error)(lhs.valid | rhs.valid));
}
closure_value &
operator<<= (closure_value const &rhs)
{
switch (type) {
case is_bool:
case is_int:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = as_long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.i <<= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = as_ulong(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui <<= shift_by;
// Note: The usual arithmetic conversions are not performed on
// bit shift operations.
}
break;
}
break;
case is_uint:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = as_long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.ui <<= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = as_ulong(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui <<= shift_by;
}
break;
}
}
valid = (value_error)(valid | rhs.valid);
return *this;
}
closure_value &
operator>>= (closure_value const &rhs)
{
switch (type) {
case is_bool:
case is_int:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = as_long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.i >>= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = as_ulong(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui >>= shift_by;
// Note: The usual arithmetic conversions are not performed on
// bit shift operations.
}
break;
}
break;
case is_uint:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = as_long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.ui >>= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = as_ulong(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui >>= shift_by;
}
break;
}
break;
}
valid = (value_error)(valid | rhs.valid);
return *this;
}
friend closure_value
operator|| (closure_value const &lhs, closure_value const &rhs)
{
bool result = as_bool(lhs) || as_bool(rhs);
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator&& (closure_value const &lhs, closure_value const &rhs)
{
bool result = as_bool(lhs) && as_bool(rhs);
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator| (closure_value const &lhs, closure_value const &rhs)
{
unsigned long result = as_ulong(lhs) | as_ulong(rhs);
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator& (closure_value const &lhs, closure_value const &rhs)
{
unsigned long result = as_ulong(lhs) & as_ulong(rhs);
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
}
friend closure_value
operator^ (closure_value const &lhs, closure_value const &rhs)
{
unsigned long result = as_ulong(lhs) ^ as_ulong(rhs);
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
}
// handle the ?: operator
closure_value &
handle_questionmark(closure_value const &cond, closure_value const &val2)
{
switch (type) {
case is_int:
switch (val2.type) {
case is_bool: value.b = as_bool(cond) ? value.b : as_bool(val2); break;
case is_int: value.i = as_bool(cond) ? value.i : as_long(val2); break;
case is_uint:
value.ui = as_bool(cond) ? value.ui : as_ulong(val2);
type = is_uint; // changing type!
break;
}
break;
case is_uint: value.ui = as_bool(cond) ? value.ui : as_ulong(val2); break;
case is_bool: value.b = as_bool(cond) ? value.b : as_bool(val2); break;
}
valid = as_bool(cond) ? valid : val2.valid;
return *this;
}
#if defined (BOOST_SPIRIT_DEBUG)
friend std::ostream&
operator<< (std::ostream &o, closure_value const &val)
{
switch (val.type) {
case is_int: o << "int(" << as_long(val) << ")"; break;
case is_uint: o << "unsigned int(" << as_ulong(val) << ")"; break;
case is_bool: o << "bool(" << as_bool(val) << ")"; break;
}
return o;
}
#endif // defined(BOOST_SPIRIT_DEBUG)
private:
value_type type;
union {
long i;
unsigned long ui;
bool b;
} value;
value_error valid;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace closures
} // namespace grammars
} // namespace wave
} // namespace boost
// the suffix header occurs after all of the code
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif
#endif // !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -