ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

201 lines
3.9 KiB

  1. #ifndef CPPCMS_INTRUSIVE_PTR_H_INCLUDED
  2. #define CPPCMS_INTRUSIVE_PTR_H_INCLUDED
  3. //
  4. // intrusive_ptr.hpp
  5. //
  6. // Copyright (c) 2001, 2002 Peter Dimov
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See
  9. // accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. // See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
  13. //
  14. #include <functional> // for std::less
  15. #include <iosfwd> // for std::basic_ostream
  16. namespace cppcms
  17. {
  18. //
  19. // intrusive_ptr
  20. //
  21. // A smart pointer that uses intrusive reference counting.
  22. //
  23. // Relies on unqualified calls to
  24. //
  25. // void intrusive_ptr_add_ref(T * p);
  26. // void intrusive_ptr_release(T * p);
  27. //
  28. // (p != 0)
  29. //
  30. // The object is responsible for destroying itself.
  31. //
  32. template<class T> class intrusive_ptr
  33. {
  34. private:
  35. typedef intrusive_ptr this_type;
  36. public:
  37. typedef T element_type;
  38. intrusive_ptr(): p_(0)
  39. {
  40. }
  41. intrusive_ptr(T * p, bool add_ref = true): p_(p)
  42. {
  43. if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);
  44. }
  45. intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
  46. {
  47. if(p_ != 0) intrusive_ptr_add_ref(p_);
  48. }
  49. ~intrusive_ptr()
  50. {
  51. if(p_ != 0) intrusive_ptr_release(p_);
  52. }
  53. template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
  54. {
  55. if(p_ != 0) intrusive_ptr_add_ref(p_);
  56. }
  57. intrusive_ptr & operator=(intrusive_ptr const & rhs)
  58. {
  59. this_type(rhs).swap(*this);
  60. return *this;
  61. }
  62. intrusive_ptr & operator=(T * rhs)
  63. {
  64. this_type(rhs).swap(*this);
  65. return *this;
  66. }
  67. T * get() const
  68. {
  69. return p_;
  70. }
  71. T & operator*() const
  72. {
  73. return *p_;
  74. }
  75. T * operator->() const
  76. {
  77. return p_;
  78. }
  79. typedef T * this_type::*unspecified_bool_type;
  80. operator unspecified_bool_type () const
  81. {
  82. return p_ == 0? 0: &this_type::p_;
  83. }
  84. // operator! is a Borland-specific workaround
  85. bool operator! () const
  86. {
  87. return p_ == 0;
  88. }
  89. void swap(intrusive_ptr & rhs)
  90. {
  91. T * tmp = p_;
  92. p_ = rhs.p_;
  93. rhs.p_ = tmp;
  94. }
  95. private:
  96. T * p_;
  97. };
  98. template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
  99. {
  100. return a.get() == b.get();
  101. }
  102. template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
  103. {
  104. return a.get() != b.get();
  105. }
  106. template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
  107. {
  108. return a.get() == b;
  109. }
  110. template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
  111. {
  112. return a.get() != b;
  113. }
  114. template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
  115. {
  116. return a == b.get();
  117. }
  118. template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
  119. {
  120. return a != b.get();
  121. }
  122. template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
  123. {
  124. return std::less<T *>()(a.get(), b.get());
  125. }
  126. template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
  127. {
  128. lhs.swap(rhs);
  129. }
  130. // mem_fn support
  131. template<class T> T * get_pointer(intrusive_ptr<T> const & p)
  132. {
  133. return p.get();
  134. }
  135. template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
  136. {
  137. return static_cast<T *>(p.get());
  138. }
  139. template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
  140. {
  141. return const_cast<T *>(p.get());
  142. }
  143. template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
  144. {
  145. return dynamic_cast<T *>(p.get());
  146. }
  147. // operator<<
  148. template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
  149. {
  150. os << p.get();
  151. return os;
  152. }
  153. } // namespace cppcms
  154. #endif // #ifndef CPPCMS_INTRUSIVE_PTR_H_INCLUDED