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

📄 cpp_expression_value.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library

    http://www.boost.org/

    Copyright (c) 2001-2005 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)

///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
namespace closures {

///////////////////////////////////////////////////////////////////////////////
//
//  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
    };
    
    enum value_error {
        error_noerror = 0x0,
        error_division_by_zero = 0x1,
        error_overflow = 0x2
    };
    
    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(long i, value_error valid_ = error_noerror) 
    : type(is_int), valid(valid_) 
    { value.i = i; }
    explicit closure_value(unsigned long 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; }
    
// implicit conversion
    operator int() const 
    {
        switch (type) {
        case is_uint:   return value.ui;
        case is_bool:   return value.b ? 1 : 0;
        case is_int:    break;
        }
        return value.i;
    }
    operator unsigned int() const 
    {
        switch (type) {
        case is_uint:   return value.ui;
        case is_bool:   return value.b ? 1 : 0;
        case is_int:    break;
        }
        return value.i;
    }
    operator long() const 
    {
        switch (type) {
        case is_uint:   return value.ui;
        case is_bool:   return value.b ? 1 : 0;
        case is_int:    break;
        }
        return value.i;
    }
    operator unsigned long() const 
    {
        switch (type) {
        case is_uint:   return value.ui;
        case is_bool:   return value.b ? 1 : 0;
        case is_int:    break;
        }
        return value.i;
    }
    operator bool() const 
    {
        switch (type) {
        case is_uint:   return value.ui != 0;
        case is_bool:   return value.b;
        case is_int:    break;
        }
        return value.i != 0.0;
    }

// assignment    
    closure_value &operator= (closure_value const &rhs)
    {
        switch (rhs.get_type()) {
        case is_int:    
            value.i = long(rhs); 
            type = is_int;
            break;
        
        case is_uint:   
            value.ui = (unsigned long)(rhs); 
            type = is_uint;
            break;
        
        case is_bool:   
            value.b = 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= (long rhs)
    {
        type = is_int;
        value.i = rhs;
        valid = error_noerror;
        return *this;
    }
    closure_value &operator= (unsigned long 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:
                {
                    long result = value.i + long(rhs); 
                    if (rhs.value.i > 0L && value.i > result || 
                        rhs.value.i < 0L && value.i < result)
                    {
                        valid = error_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;
                
            case is_int:
                {
                    long result = value.i + rhs.value.i;
                    if (rhs.value.i > 0L && value.i > result || 
                        rhs.value.i < 0L && value.i < result)
                    {
                        valid = error_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;
                
            case is_uint:
                {
                    unsigned long result = value.ui + rhs.value.ui; 
                    if (result < value.ui) {
                        valid = error_overflow;
                    }
                    else {
                        value.ui = result;
                        type = is_uint; 
                    }
                }
                break;
            }
            break;
            
        case is_uint:
            {
                unsigned long result = value.ui + (unsigned long)(rhs); 
                if (result < value.ui) {
                    valid = error_overflow;
                }
                else {
                    value.ui = result;
                }
            }
            break;
            
        case is_bool:   
            value.i = value.b + 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:
                {
                    long result = value.i - long(rhs); 
                    if (rhs.value.i > 0L && result > value.i || 
                        rhs.value.i < 0L && result < value.i)
                    {
                        valid = error_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;

            case is_int:
                {
                    long result = value.i - rhs.value.i;
                    if (rhs.value.i > 0L && result > value.i || 
                        rhs.value.i < 0L && result < value.i)
                    {
                        valid = error_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;
                
            case is_uint:
                {
                    unsigned long result = value.ui - rhs.value.ui; 
                    if (result > value.ui) {
                        valid = error_overflow;
                    }
                    else {
                        value.ui = result;
                        type = is_uint; 
                    }
                }
                break;
            }
            break;
            
        case is_uint:
            switch(rhs.type) {
            case is_bool:
                {
                    unsigned long result = value.ui - (unsigned long)(rhs); 
                    if (result > value.ui)
                    {
                        valid = error_overflow;
                    }
                    else {
                        value.ui = result;
                    }
                }
                break;

            case is_int:
                {
                    unsigned long result = value.ui - rhs.value.i;
                    if (rhs.value.i > 0L && result > value.ui || 
                        rhs.value.i < 0L && result < value.ui)
                    {
                        valid = error_overflow;
                    }
                    else {
                        value.ui = result;
                    }
                }
                break;
                
            case is_uint:
                {
                    unsigned long result = value.ui - rhs.value.ui; 
                    if (result > value.ui) {
                        valid = error_overflow;
                    }
                    else {
                        value.ui = result;
                    }
                }
                break;
            }
            break;

        case is_bool:   
            value.i = value.b - 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 *= long(rhs); break;
            case is_int:
                {
                    long 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_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;
                
            case is_uint:
                {
                    unsigned long 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_overflow;
                    }
                    else {
                        value.ui = result;
                        type = is_uint; 
                    }
                }
                break;
            }
            break;
            
        case is_uint:
            {
                unsigned long rhs_val = (unsigned long)(rhs);
                unsigned long result = value.ui * rhs_val; 
                if (0 != value.ui && 0 != rhs_val &&
                    (result / value.ui != rhs_val ||
                      result / rhs_val != value.ui)
                    )
                {
                    valid = error_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 (long(rhs) != 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -