Commit 241eba4f authored by Ian Henriksen's avatar Ian Henriksen

Added basic tests for exception handling for operators.

parent c815cb28
# tag: cpp
"""
PYTHON setup.py build_ext --inplace
PYTHON -c "from check_operator_exception_handling import test; test()"
"""
######## setup.py ########
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize('*.pyx', language='c++'))
######## wint.cpp ########
#pragma once
#include <stdexcept>
class wrapped_int {
public:
long long val;
wrapped_int() { val = 0; }
wrapped_int(long long val) { this->val = val; }
wrapped_int(long long v1, long long v2) {
if (v2 == 4) {
throw std::domain_error("4 isn't good for initialization!");
}
this->val = v1;
}
wrapped_int operator+(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("tried to add 4");
}
return wrapped_int(this->val + other.val);
}
wrapped_int operator+() {
if (this->val == 4) {
throw std::domain_error("'4' not in valid domain.");
}
return *this;
}
wrapped_int operator-(wrapped_int &other) {
if (other.val == 4) {
throw std::overflow_error("Value '4' is no good.");
}
return *this;
}
wrapped_int operator-() {
if (this->val == 4) {
throw std::range_error("Can't take the negative of 4.");
}
return wrapped_int(-this->val);
}
wrapped_int operator*(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return wrapped_int(this->val * other.val);
}
wrapped_int operator/(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return wrapped_int(this->val / other.val);
}
wrapped_int operator%(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return wrapped_int(this->val % other.val);
}
long long operator^(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return this->val ^ other.val;
}
long long operator&(wrapped_int &other) {
if (other.val == 4) {
throw std::underflow_error("Can't do this with 4!");
}
return this->val & other.val;
}
long long operator|(wrapped_int &other) {
if (other.val == 4) {
throw std::underflow_error("Can't do this with 4!");
}
return this->val & other.val;
}
wrapped_int operator~() {
if (this->val == 4) {
throw std::range_error("4 is really just no good for this!");
}
return *this;
}
long long operator&() {
if (this->val == 4) {
throw std::out_of_range("4 cannot be located!");
}
return this->val;
}
long long operator==(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("4 isn't logical and can't be equal to anything!");
}
return this->val == other.val;
}
long long operator!=(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("4 isn't logical and can'd be not equal to anything either!");
}
return this->val != other.val;
}
long long operator<(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val < other.val;
}
long long operator<=(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val <= other.val;
}
long long operator>(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val > other.val;
}
long long operator>=(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val >= other.val;
}
wrapped_int operator<<(long long &shift) {
if (shift == 4) {
throw std::overflow_error("Shifting by 4 is just bad.");
}
return wrapped_int(this->val << shift);
}
wrapped_int operator>>(long long &shift) {
if (shift == 4) {
throw std::underflow_error("Shifting by 4 is just bad.");
}
return wrapped_int(this->val >> shift);
}
wrapped_int &operator++() {
if (this->val == 4) {
throw std::out_of_range("Can't increment 4!");
}
this->val += 1;
return *this;
}
wrapped_int &operator--() {
if (this->val == 4) {
throw std::out_of_range("Can't decrement 4!");
}
this->val -= 1;
return *this;
}
wrapped_int operator++(int) {
if (this->val == 4) {
throw std::out_of_range("Can't increment 4!");
}
wrapped_int t = *this;
this->val += 1;
return t;
}
wrapped_int operator--(int) {
if (this->val == 4) {
throw std::out_of_range("Can't decrement 4!");
}
wrapped_int t = *this;
this->val -= 1;
return t;
}
wrapped_int operator!() {
if (this->val == 4) {
throw std::out_of_range("Can't negate 4!");
}
return wrapped_int(!this->val);
}
operator bool() {
if (this->val == 4) {
throw std::invalid_argument("4 can't be cast to a boolean value!");
}
return (this->val != 0);
}
wrapped_int &operator[](long long &idx) {
if (idx == 4) {
throw std::invalid_argument("Index of 4 not allowed.");
}
return *this;
}
long long &operator()() {
if (this->val == 4) {
throw std::range_error("Can't call 4!");
}
return this->val;
}
wrapped_int &operator=(const wrapped_int &other) {
if (other.val == 4) {
throw std::overflow_error("4 is really too big!");
}
this->val = other.val;
return *this;
}
wrapped_int &operator=(const long long &v) {
if (v == 4) {
throw std::overflow_error("4 is really too small!");
}
this->val = v;
return *this;
}
};
######## check_operator_exception_handling.pyx ########
from cython.operator import (preincrement, predecrement,
postincrement, postdecrement)
from libcpp cimport bool
cdef extern from "wint.cpp" nogil:
cppclass wrapped_int:
long long val
wrapped_int()
wrapped_int(long long val)
wrapped_int(long long v1, long long v2) except +
wrapped_int operator+(wrapped_int &other) except +
wrapped_int operator+() except +
wrapped_int operator-(wrapped_int &other) except +
wrapped_int operator-() except +
wrapped_int operator*(wrapped_int &other) except +
wrapped_int operator/(wrapped_int &other) except +
wrapped_int operator%(wrapped_int &other) except +
long long operator^(wrapped_int &other) except +
long long operator&(wrapped_int &other) except +
long long operator|(wrapped_int &other) except +
wrapped_int operator~() except +
long long operator&() except +
long long operator==(wrapped_int &other) except +
long long operator!=(wrapped_int &other) except +
long long operator<(wrapped_int &other) except +
long long operator<=(wrapped_int &other) except +
long long operator>(wrapped_int &other) except +
long long operator>=(wrapped_int &other) except +
wrapped_int operator<<(long long shift) except +
wrapped_int operator>>(long long shift) except +
wrapped_int &operator++() except +
wrapped_int &operator--() except +
wrapped_int operator++(int) except +
wrapped_int operator--(int) except +
wrapped_int operator!() except +
bool operator bool() except +
wrapped_int &operator[](long long &index) except +
long long &operator()() except +
wrapped_int &operator=(const wrapped_int &other) except +
wrapped_int &operator=(const long long &vao) except +
def assert_raised(f, *args):
try:
f(*args)
raised = False
except:
raised = True
assert raised
def initialization(long long a, long long b):
cdef wrapped_int w = wrapped_int(a, b)
return w.val
def addition(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa + wb).val
def subtraction(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa - wb).val
def multiplication(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa * wb).val
def division(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa / wb).val
def mod(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa % wb).val
def minus(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (-wa).val
def plus(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (+wa).val
def xor(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa ^ wb
def bitwise_and(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa & wb
def bitwise_or(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa | wb
def bitwise_not(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (~a).val
def address(long long a):
cdef wrapped_int wa = wrapped_int(a)
return &wa
def iseq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa == wb
def neq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa != wb
def less(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa < wb
def leq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa <= wb
def greater(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa > wb
def geq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa < wb
def left_shift(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
return (wa << b).val
def right_shift(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
return (wa >> b).val
def cpp_preincrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return preincrement(wa).val
def cpp_predecrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return predecrement(wa).val
def cpp_postincrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return postincrement(wa).val
def cpp_postdecrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return postdecrement(wa).val
def negate(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (not wa).val
def bool_cast(long long a):
cdef wrapped_int wa = wrapped_int(a)
if wa:
return True
else:
return False
def index(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
return wa[b].val
def assign_index(long long a, long long b, long long c):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
wb[c] = wa
return wb.val
def call(long long a):
cdef wrapped_int wa = wrapped_int(a)
return wa()
def assign_same(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
wa = wb
return wa.val
def assign_different(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
wa = b
return wa.val
def test():
a = 1
b = 4
c = 4
assert_raised(initialization, a, b)
assert_raised(addition, a, b)
assert_raised(subtraction, a, b)
assert_raised(multiplication, a, b)
assert_raised(division, a, b)
assert_raised(mod, a, b)
assert_raised(minus, b)
assert_raised(plus, b)
assert_raised(xor, a, b)
assert_raised(address, b)
assert_raised(iseq, a, b)
assert_raised(neq, a, b)
assert_raised(left_shift, a, b)
assert_raised(right_shift, a, b)
assert_raised(cpp_preincrement, b)
assert_raised(cpp_predecrement, b)
assert_raised(cpp_postincrement, b)
assert_raised(cpp_postdecrement, b)
assert_raised(negate, b)
assert_raised(bool_cast, b)
assert_raised(index, a, b)
assert_raised(assign_index, a, b, c)
assert_raised(assign_same, a, b)
assert_raised(assign_different, a, b)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment