Commit 9f850fb4 authored by Robert Bradshaw's avatar Robert Bradshaw

Support operator bool() for C++ classes.

parent 3511ed4e
......@@ -68,6 +68,8 @@ Features added
* External C++ classes that overload the assignment operator can be used.
Patch by Ian Henriksen.
* Support operator bool() for C++ classes so they can be used in if statements.
Bugs fixed
----------
......
......@@ -846,6 +846,12 @@ class ExprNode(Node):
return self
elif type.is_pyobject or type.is_int or type.is_ptr or type.is_float:
return CoerceToBooleanNode(self, env)
elif type.is_cpp_class:
return SimpleCallNode(
self.pos,
function=AttributeNode(
self.pos, obj=self, attribute='operator bool'),
args=[]).analyse_types(env)
elif type.is_ctuple:
bool_value = len(type.components) == 0
return BoolNode(self.pos, value=bool_value,
......
......@@ -2543,7 +2543,8 @@ supported_overloaded_operators = cython.declare(set, set([
'+', '-', '*', '/', '%',
'++', '--', '~', '|', '&', '^', '<<', '>>', ',',
'==', '!=', '>=', '>', '<=', '<',
'[]', '()', '!', '='
'[]', '()', '!', '=',
'bool',
]))
def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
......@@ -2620,6 +2621,13 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
s.error("Overloading operator '%s' not yet supported." % op,
fatal=False)
name += op
elif op == 'IDENT':
op = s.systring;
if op not in supported_overloaded_operators:
s.error("Overloading operator '%s' not yet supported." % op,
fatal=False)
name = name + ' ' + op
s.next()
result = Nodes.CNameDeclaratorNode(pos,
name = name, cname = cname, default = rhs)
result.calling_convention = calling_convention
......
......@@ -7,6 +7,7 @@ cimport cython.operator
from cython.operator cimport dereference as deref
from libc.string cimport const_char
from libcpp cimport bool
cdef out(s, result_type=None):
print '%s [%s]' % (s.decode('ascii'), result_type)
......@@ -49,6 +50,12 @@ cdef extern from "cpp_operators_helper.h":
const_char* operator[](int)
const_char* operator()(int)
cppclass TruthClass:
TruthClass()
TruthClass(bool)
bool operator bool()
bool value
def test_unops():
"""
>>> test_unops()
......@@ -148,3 +155,30 @@ def test_index_call():
out(t[0][100], typeof(t[0][100]))
out(t[0](100), typeof(t[0](100)))
del t
def test_bool_op():
"""
>>> test_bool_op()
"""
cdef TruthClass yes = TruthClass(True)
cdef TruthClass no = TruthClass(False)
if yes:
pass
else:
assert False
if no:
assert False
def test_bool_cond():
"""
>>> test_bool_cond()
"""
assert (TruthClass(False) or TruthClass(False)).value == False
assert (TruthClass(False) or TruthClass(True)).value == True
assert (TruthClass(True) or TruthClass(False)).value == True
assert (TruthClass(True) or TruthClass(True)).value == True
assert (TruthClass(False) and TruthClass(False)).value == False
assert (TruthClass(False) and TruthClass(True)).value == False
assert (TruthClass(True) and TruthClass(False)).value == False
assert (TruthClass(True) and TruthClass(True)).value == True
......@@ -45,3 +45,11 @@ public:
BIN_OP(());
};
class TruthClass {
public:
TruthClass() : value(false) {}
TruthClass(bool value) : value(value) {}
operator bool() { return value; }
bool value;
};
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