shared_ptr.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright David Abrahams 2002.
  2. // Copyright Stefan Seefeld 2016.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #include "test_class.hpp"
  7. using namespace boost::python;
  8. typedef test_class<> X;
  9. typedef test_class<1> Y;
  10. template <class T>
  11. struct functions
  12. {
  13. static int look(shared_ptr<T> const& x)
  14. {
  15. return (x.get()) ? x->value() : -1;
  16. }
  17. static void store(shared_ptr<T> x)
  18. {
  19. storage = x;
  20. }
  21. static void release_store()
  22. {
  23. store(shared_ptr<T>());
  24. }
  25. static void modify(shared_ptr<T>& x)
  26. {
  27. x.reset();
  28. }
  29. static shared_ptr<T> get() { return storage; }
  30. static shared_ptr<T> &get1() { return storage; }
  31. static int look_store()
  32. {
  33. return look(get());
  34. }
  35. template <class C>
  36. static void expose(C const& c)
  37. {
  38. def("look", &look);
  39. def("store", &store);
  40. def("modify", &modify);
  41. def("identity", &identity);
  42. def("null", &null);
  43. const_cast<C&>(c)
  44. .def("look", &look)
  45. .staticmethod("look")
  46. .def("store", &store)
  47. .staticmethod("store")
  48. .def("modify", &modify)
  49. .staticmethod("modify")
  50. .def("look_store", &look_store)
  51. .staticmethod("look_store")
  52. .def("identity", &identity)
  53. .staticmethod("identity")
  54. .def("null", &null)
  55. .staticmethod("null")
  56. .def("get1", &get1, return_internal_reference<>())
  57. .staticmethod("get1")
  58. .def("get", &get)
  59. .staticmethod("get")
  60. .def("count", &T::count)
  61. .staticmethod("count")
  62. .def("release", &release_store)
  63. .staticmethod("release")
  64. ;
  65. }
  66. static shared_ptr<T> identity(shared_ptr<T> x) { return x; }
  67. static shared_ptr<T> null(T const&) { return shared_ptr<T>(); }
  68. static shared_ptr<T> storage;
  69. };
  70. template <class T> shared_ptr<T> functions<T>::storage;
  71. struct Z : test_class<2>
  72. {
  73. Z(int x) : test_class<2>(x) {}
  74. virtual int v() { return this->value(); }
  75. };
  76. struct ZWrap : Z
  77. {
  78. ZWrap(PyObject* self, int x)
  79. : Z(x), m_self(self) {}
  80. virtual int v() { return call_method<int>(m_self, "v"); }
  81. int default_v() { return Z::v(); }
  82. PyObject* m_self;
  83. };
  84. struct YY : Y
  85. {
  86. YY(int n) : Y(n) {}
  87. };
  88. struct YYY : Y
  89. {
  90. YYY(int n) : Y(n) {}
  91. };
  92. shared_ptr<Y> factory(int n)
  93. {
  94. return shared_ptr<Y>(n < 42 ? new Y(n) : new YY(n));
  95. }
  96. // regressions from Nicodemus
  97. struct A
  98. {
  99. virtual ~A() {}; // silence compiler warnings
  100. virtual int f() = 0;
  101. static int call_f(shared_ptr<A>& a) { return a->f(); }
  102. };
  103. struct B: A
  104. {
  105. int f() { return 1; }
  106. };
  107. shared_ptr<A> New(bool make)
  108. {
  109. return shared_ptr<A>( make ? new B() : 0 );
  110. }
  111. struct A_Wrapper: A
  112. {
  113. A_Wrapper(PyObject* self_):
  114. A(), self(self_) {}
  115. int f() {
  116. return call_method< int >(self, "f");
  117. }
  118. PyObject* self;
  119. };
  120. // ------
  121. // from Neal Becker
  122. struct Test {
  123. shared_ptr<X> x;
  124. };
  125. // ------
  126. BOOST_PYTHON_MODULE(MODULE)
  127. {
  128. class_<A, shared_ptr<A_Wrapper>, boost::noncopyable>("A")
  129. .def("call_f", &A::call_f)
  130. .staticmethod("call_f")
  131. ;
  132. // This is the ugliness required to register a to-python converter
  133. // for shared_ptr<A>.
  134. objects::class_value_wrapper<
  135. shared_ptr<A>
  136. , objects::make_ptr_instance<A, objects::pointer_holder<shared_ptr<A>,A> >
  137. >();
  138. def("New", &New);
  139. def("factory", factory);
  140. functions<X>::expose(
  141. class_<X, boost::noncopyable>("X", init<int>())
  142. .def("value", &X::value)
  143. );
  144. functions<Y>::expose(
  145. class_<Y, shared_ptr<Y> >("Y", init<int>())
  146. .def("value", &Y::value)
  147. );
  148. class_<YY, bases<Y>, boost::noncopyable>("YY", init<int>())
  149. ;
  150. class_<YYY, shared_ptr<YYY>, bases<Y> >("YYY", init<int>())
  151. ;
  152. functions<Z>::expose(
  153. class_<Z, ZWrap>("Z", init<int>())
  154. .def("value", &Z::value)
  155. .def("v", &Z::v, &ZWrap::default_v)
  156. );
  157. // from Neal Becker
  158. class_<Test> ("Test")
  159. .def_readonly ("x", &Test::x, "x")
  160. ;
  161. // ------
  162. }