Commit b20ed656 authored by Ian Henriksen's avatar Ian Henriksen

Changed tests for operator exception handling to be separate files rather

than a single srctree.
parent ebc47ed9
# tag: cpp # mode: run
# tag: cpp, werror
"""
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) && (this->val == 4)) {
throw std::overflow_error("Can't assign 4 to 4!");
}
this->val = other.val;
return *this;
}
wrapped_int &operator=(const long long &v) {
if ((v == 4) && (this->val == 4)) {
throw std::overflow_error("Can't assign 4 to 4!");
}
this->val = v;
return *this;
}
};
######## check_operator_exception_handling.pyx ########
from cython.operator import (preincrement, predecrement, from cython.operator import (preincrement, predecrement,
postincrement, postdecrement) postincrement, postdecrement)
from libcpp cimport bool from libcpp cimport bool
cdef extern from "wint.cpp" nogil: cdef extern from "cpp_operator_exc_handling_helper.hpp" nogil:
cppclass wrapped_int: cppclass wrapped_int:
long long val long long val
wrapped_int() wrapped_int()
...@@ -448,7 +230,10 @@ def call_temp_separation(long long a, long long b, long long c): ...@@ -448,7 +230,10 @@ def call_temp_separation(long long a, long long b, long long c):
wa[b] = wc() wa[b] = wc()
return wa.val return wa.val
def test(): def test_operator_exception_handling():
"""
>>> test_operator_exception_handling()
"""
assert_raised(initialization, 1, 4) assert_raised(initialization, 1, 4)
assert_raised(addition, 1, 4) assert_raised(addition, 1, 4)
assert_raised(subtraction, 1, 4) assert_raised(subtraction, 1, 4)
......
#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) && (this->val == 4)) {
throw std::overflow_error("Can't assign 4 to 4!");
}
this->val = other.val;
return *this;
}
wrapped_int &operator=(const long long &v) {
if ((v == 4) && (this->val == 4)) {
throw std::overflow_error("Can't assign 4 to 4!");
}
this->val = v;
return *this;
}
};
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