diff options
Diffstat (limited to 'tests/cpp/tvirtual.nim')
-rw-r--r-- | tests/cpp/tvirtual.nim | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/tests/cpp/tvirtual.nim b/tests/cpp/tvirtual.nim new file mode 100644 index 000000000..385d052b8 --- /dev/null +++ b/tests/cpp/tvirtual.nim @@ -0,0 +1,126 @@ +discard """ + targets: "cpp" + cmd: "nim cpp $file" + output: ''' +hello foo +hello boo +hello boo +Const Message: hello world +NimPrinter: hello world +NimPrinterConstRef: hello world +NimPrinterConstRefByRef: hello world +''' +""" + +{.emit:"""/*TYPESECTION*/ +#include <iostream> + class CppPrinter { + public: + + virtual void printConst(char* message) const { + std::cout << "Const Message: " << message << std::endl; + } + virtual void printConstRef(char* message, const int& flag) const { + std::cout << "Const Ref Message: " << message << std::endl; + } + virtual void printConstRef2(char* message, const int& flag) const { + std::cout << "Const Ref2 Message: " << message << std::endl; + } + +}; +""".} + +proc newCpp*[T](): ptr T {.importcpp:"new '*0()".} +type + Foo = object of RootObj + FooPtr = ptr Foo + Boo = object of Foo + BooPtr = ptr Boo + CppPrinter {.importcpp, inheritable.} = object + NimPrinter {.exportc.} = object of CppPrinter + +proc salute(self: FooPtr) {.virtual.} = + echo "hello foo" + +proc salute(self: BooPtr) {.virtual.} = + echo "hello boo" + +let foo = newCpp[Foo]() +let boo = newCpp[Boo]() +let booAsFoo = cast[FooPtr](newCpp[Boo]()) + +#polymorphism works +foo.salute() +boo.salute() +booAsFoo.salute() +let message = "hello world".cstring + +proc printConst(self: CppPrinter, message: cstring) {.importcpp.} +CppPrinter().printConst(message) + +#notice override is optional. +#Will make the cpp compiler to fail if not virtual function with the same signature if found in the base type +proc printConst(self: NimPrinter, message: cstring) {.virtual:"$1('2 #2) const override".} = + echo "NimPrinter: " & $message + +proc printConstRef(self: NimPrinter, message: cstring, flag: int32) {.virtual:"$1('2 #2, const '3& #3 ) const override".} = + echo "NimPrinterConstRef: " & $message + +proc printConstRef2(self: NimPrinter, message: cstring, flag {.byref.}: int32) {.virtual:"$1('2 #2, const '3 #3 ) const override".} = + echo "NimPrinterConstRefByRef: " & $message + +NimPrinter().printConst(message) +var val : int32 = 10 +NimPrinter().printConstRef(message, val) +NimPrinter().printConstRef2(message, val) + +#bug 22269 +type Doo = object +proc naiveMember(x: Doo): int {. virtual .} = 2 +discard naiveMember(Doo()) + +#asmnostackframe works with virtual +{.emit:"""/*TYPESECTION*/ + template<typename T> + struct Box { + T* first; + + Box(int x){ + first = new T(x); + }; + }; + struct Inner { + int val; + //Coo() = default; + Inner(int x){ + val = x; + }; + }; + struct Base { + virtual Box<Inner> test() = 0; + }; +""".} + +type + Inner {.importcpp.} = object + Base {.importcpp, inheritable.} = object + Child = object of Base + Box[T] {.importcpp, inheritable.} = object + first: T + +proc makeBox[T](x:int32): Box[T] {.importcpp:"Box<'0>(@)", constructor.} + +proc test(self: Child): Box[Inner] {.virtual, asmnostackframe.} = + let res {.exportc.} = makeBox[Inner](100) + {.emit:"return res;".} + + +discard Child().test() + +import virtualptr + +#We dont want to pull Loo directly by using it as we are testing that the pointer pulls it. +proc makeMoo(): Moo {.importcpp:"{ new Loo() }".} + +makeMoo().loo.salute() + |