instance_holder.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // Copyright Daniel Wallin 2008. Use, modification and distribution is
  2. // subject to the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef LUABIND_INSTANCE_HOLDER_081024_HPP
  5. # define LUABIND_INSTANCE_HOLDER_081024_HPP
  6. # include <luabind/detail/inheritance.hpp>
  7. # include <luabind/get_pointer.hpp>
  8. # include <luabind/typeid.hpp>
  9. # include <boost/type_traits/is_polymorphic.hpp>
  10. # include <stdexcept>
  11. namespace luabind { namespace detail {
  12. class instance_holder
  13. {
  14. public:
  15. instance_holder(bool pointee_const)
  16. : m_pointee_const(pointee_const)
  17. {}
  18. virtual ~instance_holder()
  19. {}
  20. virtual std::pair<void*, int> get(
  21. cast_graph const& casts, class_id target) const = 0;
  22. virtual void release() = 0;
  23. bool pointee_const() const
  24. {
  25. return m_pointee_const;
  26. }
  27. private:
  28. bool m_pointee_const;
  29. };
  30. namespace mpl = boost::mpl;
  31. inline mpl::false_ check_const_pointer(void*)
  32. {
  33. return mpl::false_();
  34. }
  35. inline mpl::true_ check_const_pointer(void const*)
  36. {
  37. return mpl::true_();
  38. }
  39. template <class T>
  40. void release_ownership(std::auto_ptr<T>& p)
  41. {
  42. p.release();
  43. }
  44. template <class P>
  45. void release_ownership(P const&)
  46. {
  47. throw std::runtime_error(
  48. "luabind: smart pointer does not allow ownership transfer");
  49. }
  50. template <class T>
  51. class_id static_class_id(T*)
  52. {
  53. return registered_class<T>::id;
  54. }
  55. template <class P, class Pointee = void const>
  56. class pointer_holder : public instance_holder
  57. {
  58. public:
  59. pointer_holder(
  60. P p, class_id dynamic_id, void* dynamic_ptr
  61. )
  62. : instance_holder(check_const_pointer(false ? get_pointer(p) : 0))
  63. , p(p)
  64. , weak(0)
  65. , dynamic_id(dynamic_id)
  66. , dynamic_ptr(dynamic_ptr)
  67. {}
  68. std::pair<void*, int> get(cast_graph const& casts, class_id target) const
  69. {
  70. if (target == registered_class<P>::id)
  71. return std::pair<void*, int>(&this->p, 0);
  72. void* naked_ptr = const_cast<void*>(static_cast<void const*>(
  73. weak ? weak : get_pointer(p)));
  74. if (!naked_ptr)
  75. return std::pair<void*, int>((void*)0, 0);
  76. return casts.cast(
  77. naked_ptr
  78. , static_class_id(false ? get_pointer(p) : 0)
  79. , target
  80. , dynamic_id
  81. , dynamic_ptr
  82. );
  83. }
  84. void release()
  85. {
  86. weak = const_cast<void*>(static_cast<void const*>(
  87. get_pointer(p)));
  88. release_ownership(p);
  89. }
  90. private:
  91. mutable P p;
  92. // weak will hold a possibly stale pointer to the object owned
  93. // by p once p has released it's owership. This is a workaround
  94. // to make adopt() work with virtual function wrapper classes.
  95. void* weak;
  96. class_id dynamic_id;
  97. void* dynamic_ptr;
  98. };
  99. }} // namespace luabind::detail
  100. #endif // LUABIND_INSTANCE_HOLDER_081024_HPP