📄 cpp_expression_value.hpp
字号:
/*============================================================================= Boost.Wave: A Standard compliant C++ preprocessor library http://www.boost.org/ Copyright (c) 2001-2008 Hartmut Kaiser. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#if !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)#define CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED#if defined (BOOST_SPIRIT_DEBUG)#include <iostream>#endif // defined(BOOST_SPIRIT_DEBUG)#include <boost/wave/wave_config.hpp>#include <boost/wave/grammars/cpp_value_error.hpp> // value_error// this must occur after all of the includes and before any code appears#ifdef BOOST_HAS_ABI_HEADERS#include BOOST_ABI_PREFIX#endif///////////////////////////////////////////////////////////////////////////////namespace boost {namespace wave {namespace grammars {namespace closures {class closure_value;inline bool as_bool(closure_value const& v);/////////////////////////////////////////////////////////////////////////////////// The closure_value class represents the closure type, which is used for the // expression grammar. //// This class was introduced to allow the expression grammar to respect // the numeric type of a numeric literal or expression result./////////////////////////////////////////////////////////////////////////////////class closure_value {public: enum value_type { is_int = 1, is_uint = 2, is_bool = 3 }; closure_value(value_error valid_ = error_noerror) : type(is_int), valid(valid_) { value.i = 0; } explicit closure_value(int i, value_error valid_ = error_noerror) : type(is_int), valid(valid_) { value.i = i; } explicit closure_value(unsigned int ui, value_error valid_ = error_noerror) : type(is_uint), valid(valid_) { value.ui = ui; } explicit closure_value(int_literal_type i, value_error valid_ = error_noerror) : type(is_int), valid(valid_) { value.i = i; } explicit closure_value(uint_literal_type ui, value_error valid_ = error_noerror) : type(is_uint), valid(valid_) { value.ui = ui; } explicit closure_value(bool b, value_error valid_ = error_noerror) : type(is_bool), valid(valid_) { value.b = b; } value_type get_type() const { return type; } value_error is_valid() const { return valid; } // explicit conversion friend int_literal_type as_int(closure_value const& v) { switch (v.type) { case is_uint: return v.value.ui; case is_bool: return v.value.b ? 1 : 0; case is_int: break; } return v.value.i; } friend uint_literal_type as_uint(closure_value const& v) { switch (v.type) { case is_uint: return v.value.ui; case is_bool: return v.value.b ? 1 : 0; case is_int: break; } return v.value.i; } friend int_literal_type as_long(closure_value const& v) { switch (v.type) { case is_uint: return v.value.ui; case is_bool: return v.value.b ? 1 : 0; case is_int: break; } return v.value.i; } friend uint_literal_type as_ulong(closure_value const& v) { switch (v.type) { case is_uint: return v.value.ui; case is_bool: return v.value.b ? 1 : 0; case is_int: break; } return v.value.i; } friend bool as_bool(closure_value const& v) { switch (v.type) { case is_uint: return v.value.ui != 0; case is_bool: return v.value.b; case is_int: break; } return v.value.i != 0.0; }// assignment closure_value &operator= (closure_value const &rhs) { switch (rhs.get_type()) { case is_int: value.i = as_long(rhs); type = is_int; break; case is_uint: value.ui = as_ulong(rhs); type = is_uint; break; case is_bool: value.b = as_bool(rhs); type = is_bool; break; } valid = rhs.valid; return *this; } closure_value &operator= (int rhs) { type = is_int; value.i = rhs; valid = error_noerror; return *this; } closure_value &operator= (unsigned int rhs) { type = is_uint; value.ui = rhs; valid = error_noerror; return *this; } closure_value &operator= (int_literal_type rhs) { type = is_int; value.i = rhs; valid = error_noerror; return *this; } closure_value &operator= (uint_literal_type rhs) { type = is_uint; value.ui = rhs; valid = error_noerror; return *this; } closure_value &operator= (bool rhs) { type = is_bool; value.b = rhs; valid = error_noerror; return *this; }// arithmetics closure_value &operator+= (closure_value const &rhs) { switch (type) { case is_int: switch(rhs.type) { case is_bool: { int_literal_type result = value.i + as_long(rhs); if ((rhs.value.i > 0L && value.i > result) || (rhs.value.i < 0L && value.i < result)) { valid = error_integer_overflow; } else { value.i = result; } } break; case is_int: { int_literal_type result = value.i + rhs.value.i; if ((rhs.value.i > 0L && value.i > result) || (rhs.value.i < 0L && value.i < result)) { valid = error_integer_overflow; } else { value.i = result; } } break; case is_uint: { uint_literal_type result = value.ui + rhs.value.ui; if (result < value.ui) { valid = error_integer_overflow; } else { value.ui = result; type = is_uint; } } break; } break; case is_uint: { uint_literal_type result = value.ui + as_ulong(rhs); if (result < value.ui) { valid = error_integer_overflow; } else { value.ui = result; } } break; case is_bool: value.i = value.b + as_bool(rhs); type = is_int; } valid = (value_error)(valid | rhs.valid); return *this; } closure_value &operator-= (closure_value const &rhs) { switch (type) { case is_int: switch(rhs.type) { case is_bool: { int_literal_type result = value.i - as_long(rhs); if ((rhs.value.i > 0L && result > value.i) || (rhs.value.i < 0L && result < value.i)) { valid = error_integer_overflow; } else { value.i = result; } } break; case is_int: { int_literal_type result = value.i - rhs.value.i; if ((rhs.value.i > 0L && result > value.i) || (rhs.value.i < 0L && result < value.i)) { valid = error_integer_overflow; } else { value.i = result; } } break; case is_uint: { uint_literal_type result = value.ui - rhs.value.ui; if (result > value.ui) { valid = error_integer_overflow; } else { value.ui = result; type = is_uint; } } break; } break; case is_uint: switch(rhs.type) { case is_bool: { uint_literal_type result = value.ui - as_ulong(rhs); if (result > value.ui) { valid = error_integer_overflow; } else { value.ui = result; } } break; case is_int: { uint_literal_type result = value.ui - rhs.value.i; if ((rhs.value.i > 0L && result > value.ui) || (rhs.value.i < 0L && result < value.ui)) { valid = error_integer_overflow; } else { value.ui = result; } } break; case is_uint: { uint_literal_type result = value.ui - rhs.value.ui; if (result > value.ui) { valid = error_integer_overflow; } else { value.ui = result; } } break; } break; case is_bool: value.i = value.b - as_bool(rhs); type = is_int; } valid = (value_error)(valid | rhs.valid); return *this; } closure_value &operator*= (closure_value const &rhs) { switch (type) { case is_int: switch(rhs.type) { case is_bool: value.i *= as_long(rhs); break; case is_int: { int_literal_type result = value.i * rhs.value.i; if (0 != value.i && 0 != rhs.value.i && (result / value.i != rhs.value.i || result / rhs.value.i != value.i) ) { valid = error_integer_overflow; } else { value.i = result; } } break; case is_uint: { uint_literal_type result = value.ui * rhs.value.ui; if (0 != value.ui && 0 != rhs.value.ui && (result / value.ui != rhs.value.ui || result / rhs.value.ui != value.ui) ) { valid = error_integer_overflow; } else { value.ui = result; type = is_uint; } } break; } break; case is_uint: { uint_literal_type rhs_val = as_ulong(rhs); uint_literal_type result = value.ui * rhs_val; if (0 != value.ui && 0 != rhs_val && (result / value.ui != rhs_val || result / rhs_val != value.ui) ) { valid = error_integer_overflow; } else { value.ui = result; type = is_uint; } } break; case is_bool: switch (rhs.type) { case is_int: value.i = (value.b ? 1 : 0) * rhs.value.i; type = is_int; break; case is_uint: value.ui = (value.b ? 1 : 0) * rhs.value.ui; type = is_uint; break; case is_bool: value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0)); break; } } valid = (value_error)(valid | rhs.valid); 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -