# mode: run # tag: cpp, werror # cython: experimental_cpp_class_def=True # distutils: extra_compile_args=-std=c++0x cdef double pi from math import pi from libc.math cimport sin, cos from libcpp cimport bool from libcpp.memory cimport unique_ptr from libcpp.vector cimport vector from cython.operator cimport dereference as deref cdef extern from "shapes.h" namespace "shapes": cdef cppclass Shape: float area() const cdef cppclass RegularPolygon(Shape): float radius # major int n __init__(int n, float radius): this.n = n this.radius = radius float area() const: cdef double theta = pi / this.n return this.radius * this.radius * sin(theta) * cos(theta) * this.n def test_Poly(int n, float radius=1): """ >>> test_Poly(4) 2.0 >>> test_Poly(3) #doctest: +ELLIPSIS 1.29903... >>> test_Poly(3, 10.0) #doctest: +ELLIPSIS 129.903... >>> test_Poly(100) #doctest: +ELLIPSIS 3.13952... >>> test_Poly(1000) #doctest: +ELLIPSIS 3.14157... """ cdef RegularPolygon* poly try: poly = new RegularPolygon(n, radius) poly.n = n poly.radius = radius return poly.area() finally: del poly cdef cppclass BaseClass: int n int method(): return this.n cdef cppclass SubClass(BaseClass): bool override __init__(bool override): this.n = 1 this.override = override int method(): if override: return 0 else: return BaseClass.method() def test_BaseMethods(x): """ >>> test_BaseMethods(True) 0 >>> test_BaseMethods(False) 1 """ cdef SubClass* subClass try: subClass = new SubClass(x) return subClass.method() finally: del subClass cdef cppclass WithStatic: @staticmethod double square(double x): return x * x def test_Static(x): """ >>> test_Static(2) 4.0 >>> test_Static(0.5) 0.25 """ return WithStatic.square(x) cdef cppclass InitDealloc: __init__(): try: print "Init" finally: return # swallow any exceptions __dealloc__(): try: print "Dealloc" finally: return # swallow any exceptions def test_init_dealloc(): """ >>> test_init_dealloc() start Init live Dealloc end """ print "start" cdef InitDealloc *ptr = new InitDealloc() print "live" del ptr print "end" cdef cppclass WithTemplate[T]: T value void set_value(T value): this.value = value T get_value(): return this.value cdef cppclass ResolveTemplate(WithTemplate[long]): pass def test_templates(long value): """ >>> test_templates(10) >>> test_templates(-2) """ cdef WithTemplate[long] *base = new WithTemplate[long]() del base cdef ResolveTemplate *resolved = new ResolveTemplate() resolved.set_value(value) assert resolved.value == resolved.get_value() == value, resolved.value base = resolved base.set_value(2 * value) assert base.get_value() == base.value == 2 * value, base.value del base cdef cppclass Simple: pass def test_default_init_no_gil(): with nogil: s = new Simple() del s cdef class NoisyAlloc(object): cdef public name def __init__(self, name): print "NoisyAlloc.__init__", name self.name = name def __dealloc__(self): try: print "NoisyAlloc.__dealloc__", self.name except: pass # Suppress unraisable exception warning. def __repr__(self): return "NoisyAlloc[%s]" % self.name cdef cppclass CppClassWithObjectMember: NoisyAlloc o __init__(name): try: print "CppClassWithObjectMember.__init__", name this.o = NoisyAlloc(name) except: pass # Suppress unraisable exception warning. __dealloc__(): try: print "CppClassWithObjectMember.__dealloc__", this.o.name except: pass # Suppress unraisable exception warning. def test_CppClassWithObjectMember(name): """ >>> test_CppClassWithObjectMember("gertrude") CppClassWithObjectMember.__init__ gertrude NoisyAlloc.__init__ gertrude CppClassWithObjectMember.__dealloc__ gertrude NoisyAlloc.__dealloc__ gertrude """ x = new CppClassWithObjectMember(name) del x def test_CppClassWithObjectMemberCopyAssign(name): """ >>> test_CppClassWithObjectMemberCopyAssign("gretel") CppClassWithObjectMember.__init__ gretel NoisyAlloc.__init__ gretel CppClassWithObjectMember.__dealloc__ gretel Alive in vector NoisyAlloc[gretel] CppClassWithObjectMember.__init__ leterg NoisyAlloc.__init__ leterg NoisyAlloc.__dealloc__ gretel CppClassWithObjectMember.__dealloc__ leterg Alive in vector NoisyAlloc[leterg] CppClassWithObjectMember.__dealloc__ leterg NoisyAlloc.__dealloc__ leterg Nothing alive. """ x = new CppClassWithObjectMember(name) cdef vector[CppClassWithObjectMember] v # Invokes copy constructor. v.push_back(deref(x)) del x print "Alive in vector", v[0].o y = new CppClassWithObjectMember(name[::-1]) # Invokes copy assignment. v[0] = deref(y) del y print "Alive in vector", v[0].o v.clear() print "Nothing alive." # Github issue #1886. cdef public cppclass PublicCppClassWithObjectMember: object o def test_PublicCppClassWithObjectMember(): """ >>> test_PublicCppClassWithObjectMember() """ cdef PublicCppClassWithObjectMember c assert c.o is None cdef cppclass UncopyableConstructorArgument: unique_ptr[vector[int]] member __init__(unique_ptr[vector[int]] arg): this.member.reset(arg.release()) def test_uncopyable_constructor_argument(): """ >>> test_uncopyable_constructor_argument() """ cdef UncopyableConstructorArgument *c = new UncopyableConstructorArgument( unique_ptr[vector[int]](new vector[int]())) del c