tvirtual.nim 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. discard """
  2. targets: "cpp"
  3. cmd: "nim cpp $file"
  4. output: '''
  5. hello foo
  6. hello boo
  7. hello boo
  8. Const Message: hello world
  9. NimPrinter: hello world
  10. NimPrinterConstRef: hello world
  11. NimPrinterConstRefByRef: hello world
  12. '''
  13. """
  14. {.emit:"""/*TYPESECTION*/
  15. #include <iostream>
  16. class CppPrinter {
  17. public:
  18. virtual void printConst(char* message) const {
  19. std::cout << "Const Message: " << message << std::endl;
  20. }
  21. virtual void printConstRef(char* message, const int& flag) const {
  22. std::cout << "Const Ref Message: " << message << std::endl;
  23. }
  24. virtual void printConstRef2(char* message, const int& flag) const {
  25. std::cout << "Const Ref2 Message: " << message << std::endl;
  26. }
  27. };
  28. """.}
  29. proc newCpp*[T](): ptr T {.importcpp:"new '*0()".}
  30. type
  31. Foo = object of RootObj
  32. FooPtr = ptr Foo
  33. Boo = object of Foo
  34. BooPtr = ptr Boo
  35. CppPrinter {.importcpp, inheritable.} = object
  36. NimPrinter {.exportc.} = object of CppPrinter
  37. proc salute(self: FooPtr) {.virtual.} =
  38. echo "hello foo"
  39. proc salute(self: BooPtr) {.virtual.} =
  40. echo "hello boo"
  41. let foo = newCpp[Foo]()
  42. let boo = newCpp[Boo]()
  43. let booAsFoo = cast[FooPtr](newCpp[Boo]())
  44. #polymorphism works
  45. foo.salute()
  46. boo.salute()
  47. booAsFoo.salute()
  48. let message = "hello world".cstring
  49. proc printConst(self: CppPrinter, message: cstring) {.importcpp.}
  50. CppPrinter().printConst(message)
  51. #notice override is optional.
  52. #Will make the cpp compiler to fail if not virtual function with the same signature if found in the base type
  53. proc printConst(self: NimPrinter, message: cstring) {.virtual:"$1('2 #2) const override".} =
  54. echo "NimPrinter: " & $message
  55. proc printConstRef(self: NimPrinter, message: cstring, flag: int32) {.virtual:"$1('2 #2, const '3& #3 ) const override".} =
  56. echo "NimPrinterConstRef: " & $message
  57. proc printConstRef2(self: NimPrinter, message: cstring, flag {.byref.}: int32) {.virtual:"$1('2 #2, const '3 #3 ) const override".} =
  58. echo "NimPrinterConstRefByRef: " & $message
  59. NimPrinter().printConst(message)
  60. var val : int32 = 10
  61. NimPrinter().printConstRef(message, val)
  62. NimPrinter().printConstRef2(message, val)
  63. #bug 22269
  64. type Doo = object
  65. proc naiveMember(x: Doo): int {. virtual .} = 2
  66. discard naiveMember(Doo())
  67. #asmnostackframe works with virtual
  68. {.emit:"""/*TYPESECTION*/
  69. template<typename T>
  70. struct Box {
  71. T* first;
  72. Box(int x){
  73. first = new T(x);
  74. };
  75. };
  76. struct Inner {
  77. int val;
  78. //Coo() = default;
  79. Inner(int x){
  80. val = x;
  81. };
  82. };
  83. struct Base {
  84. virtual Box<Inner> test() = 0;
  85. };
  86. """.}
  87. type
  88. Inner {.importcpp.} = object
  89. Base {.importcpp, inheritable.} = object
  90. Child = object of Base
  91. Box[T] {.importcpp, inheritable.} = object
  92. first: T
  93. proc makeBox[T](x:int32): Box[T] {.importcpp:"Box<'0>(@)", constructor.}
  94. proc test(self: Child): Box[Inner] {.virtual, asmnostackframe.} =
  95. let res {.exportc.} = makeBox[Inner](100)
  96. {.emit:"return res;".}
  97. discard Child().test()
  98. import virtualptr
  99. #We dont want to pull Loo directly by using it as we are testing that the pointer pulls it.
  100. proc makeMoo(): Moo {.importcpp:"{ new Loo() }".}
  101. makeMoo().loo.salute()