Jason Rhinelander | b3f3d79 | 2016-07-18 16:43:18 -0400 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | from __future__ import print_function |
| 3 | import sys |
| 4 | sys.path.append('.') |
| 5 | |
| 6 | from example import ExampleVirt, runExampleVirt, runExampleVirtVirtual, runExampleVirtBool |
Jason Rhinelander | d6c365b | 2016-08-05 17:44:28 -0400 | [diff] [blame] | 7 | from example import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_Tpl, B_Tpl, C_Tpl, D_Tpl |
Jason Rhinelander | ed14879 | 2016-07-21 21:31:05 -0400 | [diff] [blame] | 8 | from example import NCVirt, NonCopyable, Movable |
| 9 | |
Jason Rhinelander | b3f3d79 | 2016-07-18 16:43:18 -0400 | [diff] [blame] | 10 | |
| 11 | class ExtendedExampleVirt(ExampleVirt): |
| 12 | def __init__(self, state): |
| 13 | super(ExtendedExampleVirt, self).__init__(state + 1) |
| 14 | self.data = "Hello world" |
| 15 | |
| 16 | def run(self, value): |
| 17 | print('ExtendedExampleVirt::run(%i), calling parent..' % value) |
| 18 | return super(ExtendedExampleVirt, self).run(value + 1) |
| 19 | |
| 20 | def run_bool(self): |
| 21 | print('ExtendedExampleVirt::run_bool()') |
| 22 | return False |
| 23 | |
| 24 | def pure_virtual(self): |
| 25 | print('ExtendedExampleVirt::pure_virtual(): %s' % self.data) |
| 26 | |
| 27 | |
| 28 | ex12 = ExampleVirt(10) |
| 29 | print(runExampleVirt(ex12, 20)) |
| 30 | try: |
| 31 | runExampleVirtVirtual(ex12) |
| 32 | except Exception as e: |
| 33 | print("Caught expected exception: " + str(e)) |
| 34 | |
| 35 | ex12p = ExtendedExampleVirt(10) |
| 36 | print(runExampleVirt(ex12p, 20)) |
| 37 | print(runExampleVirtBool(ex12p)) |
| 38 | runExampleVirtVirtual(ex12p) |
Jason Rhinelander | 0ca96e2 | 2016-08-05 17:02:33 -0400 | [diff] [blame] | 39 | |
Jason Rhinelander | 0ca96e2 | 2016-08-05 17:02:33 -0400 | [diff] [blame] | 40 | class VI_AR(A_Repeat): |
| 41 | def unlucky_number(self): |
| 42 | return 99 |
Jason Rhinelander | 0ca96e2 | 2016-08-05 17:02:33 -0400 | [diff] [blame] | 43 | class VI_AT(A_Tpl): |
| 44 | def unlucky_number(self): |
| 45 | return 999 |
| 46 | |
| 47 | class VI_CR(C_Repeat): |
| 48 | def lucky_number(self): |
| 49 | return C_Repeat.lucky_number(self) + 1.25 |
Jason Rhinelander | 0ca96e2 | 2016-08-05 17:02:33 -0400 | [diff] [blame] | 50 | class VI_CT(C_Tpl): |
| 51 | pass |
| 52 | class VI_CCR(VI_CR): |
| 53 | def lucky_number(self): |
| 54 | return VI_CR.lucky_number(self) * 10 |
Jason Rhinelander | 0ca96e2 | 2016-08-05 17:02:33 -0400 | [diff] [blame] | 55 | class VI_CCT(VI_CT): |
| 56 | def lucky_number(self): |
| 57 | return VI_CT.lucky_number(self) * 1000 |
| 58 | |
| 59 | |
| 60 | class VI_DR(D_Repeat): |
| 61 | def unlucky_number(self): |
| 62 | return 123 |
| 63 | def lucky_number(self): |
| 64 | return 42.0 |
Jason Rhinelander | 0ca96e2 | 2016-08-05 17:02:33 -0400 | [diff] [blame] | 65 | class VI_DT(D_Tpl): |
| 66 | def say_something(self, times): |
| 67 | print("VI_DT says:" + (' quack' * times)) |
| 68 | def unlucky_number(self): |
| 69 | return 1234 |
| 70 | def lucky_number(self): |
| 71 | return -4.25 |
| 72 | |
| 73 | classes = [ |
Jason Rhinelander | d6c365b | 2016-08-05 17:44:28 -0400 | [diff] [blame] | 74 | # A_Repeat, A_Tpl, # abstract (they have a pure virtual unlucky_number) |
| 75 | VI_AR, VI_AT, |
| 76 | B_Repeat, B_Tpl, |
| 77 | C_Repeat, C_Tpl, |
| 78 | VI_CR, VI_CT, VI_CCR, VI_CCT, |
| 79 | D_Repeat, D_Tpl, VI_DR, VI_DT |
Jason Rhinelander | 0ca96e2 | 2016-08-05 17:02:33 -0400 | [diff] [blame] | 80 | ] |
| 81 | |
| 82 | for cl in classes: |
| 83 | print("\n%s:" % cl.__name__) |
| 84 | obj = cl() |
| 85 | obj.say_something(3) |
| 86 | print("Unlucky = %d" % obj.unlucky_number()) |
| 87 | if hasattr(obj, "lucky_number"): |
| 88 | print("Lucky = %.2f" % obj.lucky_number()) |
| 89 | |
Jason Rhinelander | ed14879 | 2016-07-21 21:31:05 -0400 | [diff] [blame] | 90 | class NCVirtExt(NCVirt): |
| 91 | def get_noncopyable(self, a, b): |
| 92 | # Constructs and returns a new instance: |
| 93 | nc = NonCopyable(a*a, b*b) |
| 94 | return nc |
| 95 | def get_movable(self, a, b): |
| 96 | # Return a referenced copy |
| 97 | self.movable = Movable(a, b) |
| 98 | return self.movable |
| 99 | |
| 100 | class NCVirtExt2(NCVirt): |
| 101 | def get_noncopyable(self, a, b): |
| 102 | # Keep a reference: this is going to throw an exception |
| 103 | self.nc = NonCopyable(a, b) |
| 104 | return self.nc |
| 105 | def get_movable(self, a, b): |
| 106 | # Return a new instance without storing it |
| 107 | return Movable(a, b) |
| 108 | |
| 109 | ncv1 = NCVirtExt() |
| 110 | print("2^2 * 3^2 =") |
| 111 | ncv1.print_nc(2, 3) |
| 112 | print("4 + 5 =") |
| 113 | ncv1.print_movable(4, 5) |
| 114 | ncv2 = NCVirtExt2() |
| 115 | print("7 + 7 =") |
| 116 | ncv2.print_movable(7, 7) |
| 117 | try: |
| 118 | ncv2.print_nc(9, 9) |
| 119 | print("Something's wrong: exception not raised!") |
| 120 | except RuntimeError as e: |
| 121 | # Don't print the exception message here because it differs under debug/non-debug mode |
| 122 | print("Caught expected exception") |
Jason Rhinelander | 3f58937 | 2016-08-07 13:05:26 -0400 | [diff] [blame] | 123 | |
| 124 | from example import ConstructorStats |
| 125 | del ex12 |
| 126 | del ex12p |
| 127 | del obj |
| 128 | del ncv1 |
| 129 | del ncv2 |
| 130 | cstats = [ConstructorStats.get(ExampleVirt), ConstructorStats.get(NonCopyable), ConstructorStats.get(Movable)] |
| 131 | print("Instances not destroyed:", [x.alive() for x in cstats]) |
| 132 | print("Constructor values:", [x.values() for x in cstats]) |
| 133 | print("Copy constructions:", [x.copy_constructions for x in cstats]) |
| 134 | print("Move constructions:", [cstats[i].move_constructions >= 1 for i in range(1, len(cstats))]) |
| 135 | |