⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp_expression_value.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/*=============================================================================    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 + -