1# mode: run
2# tag: cpp, werror
3# cython: experimental_cpp_class_def=True
4
5from libcpp.vector cimport vector
6
7cdef cppclass Wrapper[T]:
8    T value
9    __init__(T &value):
10        this.value = value
11    void set(T &value):
12        this.value = value
13    T get() const:
14        return this.value
15
16
17def test_const_get(int x):
18    """
19    >>> test_const_get(10)
20    10
21    """
22    cdef const Wrapper[int] *wrapper = new Wrapper[int](x)
23    try:
24        return const_get(wrapper[0])
25    finally:
26        del wrapper
27
28cdef int const_get(const Wrapper[int] wrapper):
29    return wrapper.get()
30
31def test_const_ref_get(int x):
32    """
33    >>> test_const_ref_get(100)
34    100
35    """
36    cdef const Wrapper[int] *wrapper = new Wrapper[int](x)
37    try:
38        return const_ref_get(wrapper[0])
39    finally:
40        del wrapper
41
42cdef int const_ref_get(const Wrapper[int] &wrapper):
43    return wrapper.get()
44
45def test_const_pointer_get(int x):
46    """
47    >>> test_const_pointer_get(1000)
48    1000
49    """
50    cdef Wrapper[int] *wrapper = new Wrapper[int](x)
51    cdef const Wrapper[int] *const_wrapper = wrapper
52    try:
53        return const_wrapper.get()
54    finally:
55        del wrapper
56
57
58# TODO: parse vector[Wrapper[int]*]
59ctypedef Wrapper[int] wrapInt
60
61def test_vector_members(py_a, py_b):
62    """
63    >>> test_vector_members([1, 2, 3], [4,5, 6])
64    ([1, 2, 3], 4)
65    """
66    cdef Wrapper[int] *value
67    cdef const Wrapper[int] *const_value
68    cdef vector[const Wrapper[int]*] a
69    cdef vector[wrapInt*] b
70    for x in py_a:
71        a.push_back(new Wrapper[int](x))
72    for x in py_b:
73        b.push_back(new Wrapper[int](x))
74    try:
75        return vector_members(a, b)
76    finally:
77        for const_value in a:
78            del const_value
79        for value in b:
80            del value
81
82cdef vector_members(vector[const Wrapper[int]*] a, const vector[wrapInt*] b):
83    # TODO: Cython-level error.
84    # b[0].set(100)
85
86    # TODO: const_iterator
87    return [x.get() for x in a], b[0].get()
88