test_policies.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
  2. // Permission is hereby granted, free of charge, to any person obtaining a
  3. // copy of this software and associated documentation files (the "Software"),
  4. // to deal in the Software without restriction, including without limitation
  5. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  6. // and/or sell copies of the Software, and to permit persons to whom the
  7. // Software is furnished to do so, subject to the following conditions:
  8. // The above copyright notice and this permission notice shall be included
  9. // in all copies or substantial portions of the Software.
  10. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
  11. // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12. // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  14. // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  15. // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  16. // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
  18. // OR OTHER DEALINGS IN THE SOFTWARE.
  19. #include "test.hpp"
  20. #include <luabind/out_value_policy.hpp>
  21. #include <luabind/return_reference_to_policy.hpp>
  22. #include <luabind/copy_policy.hpp>
  23. #include <luabind/adopt_policy.hpp>
  24. #include <luabind/discard_result_policy.hpp>
  25. #include <luabind/dependency_policy.hpp>
  26. #include <luabind/luabind.hpp>
  27. struct test_copy {};
  28. struct secret_type {};
  29. secret_type sec_;
  30. struct policies_test_class
  31. {
  32. policies_test_class(const char* name): name_(name)
  33. { ++count; }
  34. policies_test_class() { ++count; }
  35. ~policies_test_class()
  36. { --count; }
  37. std::string name_;
  38. policies_test_class* make(const char* name) const
  39. {
  40. return new policies_test_class(name);
  41. }
  42. void f(policies_test_class* p)
  43. {
  44. delete p;
  45. }
  46. const policies_test_class* internal_ref() { return this; }
  47. policies_test_class* self_ref()
  48. { return this; }
  49. static int count;
  50. // private:
  51. policies_test_class(policies_test_class const& c): name_(c.name_)
  52. { ++count; }
  53. void member_out_val(int a, int* v) { *v = a * 2; }
  54. secret_type* member_secret() { return &sec_; }
  55. };
  56. int policies_test_class::count = 0;
  57. policies_test_class global;
  58. void out_val(float* f) { *f = 3.f; }
  59. policies_test_class* copy_val() { return &global; }
  60. policies_test_class const* copy_val_const() { return &global; }
  61. secret_type* secret() { return &sec_; }
  62. void aux_test();
  63. struct test_t {
  64. test_t *make(int) { return new test_t(); }
  65. void take(test_t*) {}
  66. };
  67. struct MI2;
  68. struct MI1
  69. {
  70. void add(MI2 *) {}
  71. };
  72. struct MI2 : public MI1
  73. {
  74. virtual ~MI2()
  75. {}
  76. };
  77. struct MI2W : public MI2, public luabind::wrap_base {};
  78. void test_main(lua_State* L)
  79. {
  80. using namespace luabind;
  81. module(L)
  82. [
  83. class_<test_t>("test_t")
  84. .def("make", &test_t::make, adopt(return_value))
  85. .def("take", &test_t::take, adopt(_2))
  86. ];
  87. module(L)
  88. [
  89. class_<policies_test_class>("test")
  90. .def(constructor<>())
  91. .def("member_out_val", &policies_test_class::member_out_val, pure_out_value(_3))
  92. .def("member_secret", &policies_test_class::member_secret, discard_result)
  93. .def("f", &policies_test_class::f, adopt(_2))
  94. .def("make", &policies_test_class::make, adopt(return_value))
  95. .def("internal_ref", &policies_test_class::internal_ref, dependency(result, _1))
  96. .def("self_ref", &policies_test_class::self_ref, return_reference_to(_1)),
  97. def("out_val", &out_val, pure_out_value(_1)),
  98. def("copy_val", &copy_val, copy(result)),
  99. def("copy_val_const", &copy_val_const, copy(result)),
  100. def("secret", &secret, discard_result),
  101. class_<MI1>("mi1")
  102. .def(constructor<>())
  103. .def("add",&MI1::add,adopt(_2)),
  104. class_<MI2,MI2W,MI1>("mi2")
  105. .def(constructor<>())
  106. ];
  107. // test copy
  108. DOSTRING(L, "a = secret()\n");
  109. TEST_CHECK(policies_test_class::count == 1);
  110. DOSTRING(L, "a = copy_val()\n");
  111. TEST_CHECK(policies_test_class::count == 2);
  112. DOSTRING(L, "b = copy_val_const()\n");
  113. TEST_CHECK(policies_test_class::count == 3);
  114. DOSTRING(L,
  115. "a = nil\n"
  116. "b = nil\n"
  117. "collectgarbage()\n");
  118. // only the global variable left here
  119. TEST_CHECK(policies_test_class::count == 1);
  120. // out_value
  121. DOSTRING(L,
  122. "a = out_val()\n"
  123. "assert(a == 3)");
  124. // return_reference_to
  125. DOSTRING(L,
  126. "a = test()\n"
  127. "b = a:self_ref()\n"
  128. "a = nil\n"
  129. "collectgarbage()");
  130. // a is kept alive as long as b is alive
  131. TEST_CHECK(policies_test_class::count == 2);
  132. DOSTRING(L,
  133. "b = nil\n"
  134. "collectgarbage()");
  135. TEST_CHECK(policies_test_class::count == 1);
  136. DOSTRING(L, "a = test()");
  137. TEST_CHECK(policies_test_class::count == 2);
  138. DOSTRING(L,
  139. "b = a:internal_ref()\n"
  140. "a = nil\n"
  141. "collectgarbage()");
  142. // a is kept alive as long as b is alive
  143. TEST_CHECK(policies_test_class::count == 2);
  144. // two gc-cycles because dependency-table won't be collected in the
  145. // same cycle as the object_rep
  146. DOSTRING(L,
  147. "b = nil\n"
  148. "collectgarbage()\n"
  149. "collectgarbage()");
  150. TEST_CHECK(policies_test_class::count == 1);
  151. // adopt
  152. DOSTRING(L, "a = test()");
  153. TEST_CHECK(policies_test_class::count == 2);
  154. DOSTRING(L, "b = a:make('tjosan')");
  155. DOSTRING(L, "assert(a:member_out_val(3) == 6)");
  156. DOSTRING(L, "a:member_secret()");
  157. // make instantiated a new policies_test_class
  158. TEST_CHECK(policies_test_class::count == 3);
  159. DOSTRING(L, "a:f(b)\n");
  160. // b was adopted by c++ and deleted the object
  161. TEST_CHECK(policies_test_class::count == 2);
  162. DOSTRING(L, "a = nil\n"
  163. "collectgarbage()");
  164. TEST_CHECK(policies_test_class::count == 1);
  165. // adopt with wrappers
  166. DOSTRING(L, "mi1():add(mi2())");
  167. }