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

📄 cpp_expression_value.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
                    if (value.i == -value.i && -1 == rhs.value.i) {
                    // LONG_MIN / -1 on two's complement
                        valid = error_overflow;
                    }
                    else {
                        value.i /= 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 ((unsigned long)(rhs) != 0) 
                value.ui /= (unsigned long)(rhs); 
            else
                valid = error_division_by_zero;         // division by zero
            break;

        case is_bool:  
            if (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 (long(rhs) != 0) {
                    if (value.i == -value.i && -1 == rhs.value.i) {
                    // LONG_MIN % -1 on two's complement
                        valid = error_overflow;
                    }
                    else {
                        value.i %= 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 ((unsigned long)(rhs) != 0) 
                value.ui %= (unsigned long)(rhs); 
            else
                valid = error_division_by_zero;      // division by zero
            break;

        case is_bool:  
            if (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 = long(rhs);
                if (value != 0 && value == -value)
                    return closure_value(-value, error_overflow);
                return closure_value(-value, rhs.valid);
            }
            
        case is_bool:   return closure_value(-long(rhs), rhs.valid); 
        case is_uint:   break;
        }

        long value = (unsigned long)(rhs);
        if (value != 0 && value == -value)
            return closure_value(-value, error_overflow);
        return closure_value(-value, rhs.valid);
    }
    friend closure_value 
    operator~ (closure_value const &rhs)
    {
        return closure_value(~(unsigned long)(rhs), rhs.valid);
    }
    friend closure_value 
    operator! (closure_value const &rhs)
    {
        switch (rhs.type) {
        case is_int:    return closure_value(!long(rhs), rhs.valid);
        case is_bool:   return closure_value(!bool(rhs), rhs.valid); 
        case is_uint:   break;
        }
        return closure_value(!(unsigned long)(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 = 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 == (unsigned long)(rhs); break;
        case is_bool:   cmp = lhs.value.b == 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(!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 > 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 > (unsigned long)(rhs); break;
        case is_bool:   cmp = lhs.value.b > 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:    cmp = long(lhs) < long(rhs); break;
            switch(rhs.type) {
            case is_bool:   cmp = lhs.value.i < 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 < (unsigned long)(rhs); break;
        case is_bool:   cmp = bool(lhs) < 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(!bool(lhs > rhs), (value_error)(lhs.valid & rhs.valid));
    }
    friend closure_value 
    operator>= (closure_value const &lhs, closure_value const &rhs)
    {
        return closure_value(!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 = 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 = (unsigned long)(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 = 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 = (unsigned long)(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 = 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 = (unsigned long)(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 = 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 = (unsigned long)(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 = bool(lhs) || 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 = bool(lhs) && bool(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 = bool(cond) ? value.b : bool(val2); break;
            case is_int:  value.i = bool(cond) ? value.i : long(val2); break;
            case is_uint: 
                value.ui = bool(cond) ? value.ui : (unsigned long)(val2); 
                type = is_uint;   // changing type!
                break;
            }
            break;
            
        case is_uint:   value.ui = bool(cond) ? value.ui : (unsigned long)(val2); break;
        case is_bool:   value.b = bool(cond) ? value.b : bool(val2); break;
        }
        valid = 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(" << long(val) << ")"; break;
        case is_uint:   o << "unsigned int(" << (unsigned long)(val) << ")"; break;
        case is_bool:   o << "bool(" << 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

#endif // !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)

⌨️ 快捷键说明

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