1# mode: run
2# tag: cpp, werror
3
4from cython.operator import dereference as deref
5from libcpp.pair cimport pair
6from libcpp.vector cimport vector
7
8cdef extern from "cpp_template_subclasses_helper.h":
9    cdef cppclass Base:
10        char* name()
11
12    cdef cppclass A[A1](Base):
13        A1 funcA(A1)
14
15    cdef cppclass B[B1, B2](A[B2]):
16        pair[B1, B2] funcB(B1, B2)
17
18    cdef cppclass C[C1](B[long, C1]):
19        C1 funcC(C1)
20
21    cdef cppclass D[D1](C[pair[D1, D1]]):
22        pass
23
24    cdef cppclass E(D[double]):
25        pass
26
27def testA(x):
28    """
29    >>> testA(10)
30    10.0
31    """
32    cdef Base *base
33    cdef A[double] *a = NULL
34    try:
35        a = new A[double]()
36        base = a
37        assert base.name() == b"A", base.name()
38        return a.funcA(x)
39    finally:
40        del a
41
42def testB(x, y):
43    """
44    >>> testB(1, 2)
45    >>> testB(1, 1.5)
46    """
47    cdef Base *base
48    cdef A[double] *a
49    cdef B[long, double] *b = NULL
50    try:
51        base = a = b = new B[long, double]()
52        assert base.name() == b"B", base.name()
53        assert a.funcA(y) == y
54        assert <object>b.funcB(x, y) == (x, y)
55    finally:
56        del b
57
58def testC(x, y):
59    """
60    >>> testC(37, [1, 37])
61    >>> testC(25, [1, 5, 25])
62    >>> testC(105, [1, 3, 5, 7, 15, 21, 35, 105])
63    """
64    cdef Base *base
65    cdef A[vector[long]] *a
66    cdef B[long, vector[long]] *b
67    cdef C[vector[long]] *c = NULL
68    try:
69        base = a = b = c = new C[vector[long]]()
70        assert base.name() == b"C", base.name()
71        assert <object>a.funcA(y) == y
72        assert <object>b.funcB(x, y) == (x, y)
73        assert <object>c.funcC(y) == y
74    finally:
75        del c
76
77def testD(x, y):
78    """
79    >>> testD(1, 1.0)
80    >>> testD(2, 0.5)
81    >>> testD(4, 0.25)
82    """
83    cdef Base *base
84    cdef A[pair[double, double]] *a
85    cdef B[long, pair[double, double]] *b
86    cdef C[pair[double, double]] *c
87    cdef D[double] *d = NULL
88    try:
89        base = a = b = c = d = new D[double]()
90        assert base.name() == b"D", base.name()
91        assert <object>a.funcA((y, y)) == (y, y)
92        assert <object>b.funcB(x, (y, y + 1)) == (x, (y, y + 1))
93        assert <object>c.funcC((y, y)) == (y, y)
94    finally:
95        del d
96
97def testE(x, y):
98    """
99    >>> testD(1, 1.0)
100    >>> testD(2, 0.5)
101    >>> testD(4, 0.25)
102    """
103    cdef Base *base
104    cdef A[pair[double, double]] *a
105    cdef B[long, pair[double, double]] *b
106    cdef C[pair[double, double]] *c
107    cdef D[double] *d
108    cdef E *e = NULL
109    try:
110        base = a = b = c = d = e = new E()
111        assert base.name() == b"E", base.name()
112        assert <object>a.funcA((y, y)) == (y, y)
113        assert <object>b.funcB(x, (y, y + 1)) == (x, (y, y + 1))
114        assert <object>c.funcC((y, y)) == (y, y)
115    finally:
116        del e
117
118
119cdef public pair[int, double] public_return_pair(a, b) except *:
120  return pair[int, double](a, b)
121
122def test_GH1599(a, b):
123  """
124  >>> test_GH1599(1, 2)
125  (1, 2.0)
126  """
127  return public_return_pair(a, b)
128
129
130# Related to GH Issue #1852.
131
132cdef cppclass Callback[T]:#(UntypedCallback):
133    pass
134
135cdef cppclass MyClass[O]:
136    void Invoke(Callback[O]*)
137
138cdef cppclass MySubclass[T](MyClass[T]):
139    void Invoke(Callback[T]* callback):
140      pass
141
142
143cdef cppclass Getter[T]:
144    T get(bint fire) except *:
145        if fire:
146            raise RuntimeError
147        else:
148           raise NotImplementedError
149
150cdef cppclass GetInt(Getter[int]):
151    int get(bint fire) except *:
152        if fire:
153            raise RuntimeError
154        else:
155            return 389
156
157def test_subclass_exception_values(bint fire):
158    """
159    >>> test_subclass_exception_values(False)
160    389
161    >>> test_subclass_exception_values(True)
162    Traceback (most recent call last):
163    ...
164    RuntimeError
165    """
166    cdef GetInt getter
167    return getter.get(fire)
168