cm_auto_ptr.hxx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2016 Kitware, Inc.
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #ifndef CM_AUTO_PTR_HXX
  11. #define CM_AUTO_PTR_HXX
  12. #include <cmConfigure.h>
  13. // FIXME: Use std::auto_ptr on compilers that do not warn about it.
  14. #define CM_AUTO_PTR cm::auto_ptr
  15. // The HP compiler cannot handle the conversions necessary to use
  16. // auto_ptr_ref to pass an auto_ptr returned from one function
  17. // directly to another function as in use_auto_ptr(get_auto_ptr()).
  18. // We instead use const_cast to achieve the syntax on those platforms.
  19. // We do not use const_cast on other platforms to maintain the C++
  20. // standard design and guarantee that if an auto_ptr is bound
  21. // to a reference-to-const then ownership will be maintained.
  22. #if defined(__HP_aCC)
  23. #define cm_AUTO_PTR_REF 0
  24. #define cm_AUTO_PTR_CONST const
  25. #define cm_AUTO_PTR_CAST(a) cast(a)
  26. #else
  27. #define cm_AUTO_PTR_REF 1
  28. #define cm_AUTO_PTR_CONST
  29. #define cm_AUTO_PTR_CAST(a) a
  30. #endif
  31. // In C++11, clang will warn about using dynamic exception specifications
  32. // as they are deprecated. But as this class is trying to faithfully
  33. // mimic std::auto_ptr, we want to keep the 'throw()' decorations below.
  34. // So we suppress the warning.
  35. #if defined(__clang__) && defined(__has_warning)
  36. #if __has_warning("-Wdeprecated")
  37. #pragma clang diagnostic push
  38. #pragma clang diagnostic ignored "-Wdeprecated"
  39. #endif
  40. #endif
  41. namespace cm {
  42. template <class X>
  43. class auto_ptr;
  44. #if cm_AUTO_PTR_REF
  45. namespace detail {
  46. // The auto_ptr_ref template is supposed to be a private member of
  47. // auto_ptr but Borland 5.8 cannot handle it. Instead put it in
  48. // a private namespace.
  49. template <class Y>
  50. struct auto_ptr_ref
  51. {
  52. Y* p_;
  53. // The extra constructor argument prevents implicit conversion to
  54. // auto_ptr_ref from auto_ptr through the constructor. Normally
  55. // this should be done with the explicit keyword but Borland 5.x
  56. // generates code in the conversion operator to call itself
  57. // infinately.
  58. auto_ptr_ref(Y* p, int)
  59. : p_(p)
  60. {
  61. }
  62. };
  63. }
  64. #endif
  65. /** C++98 Standard Section 20.4.5 - Template class auto_ptr. */
  66. template <class X>
  67. class auto_ptr
  68. {
  69. #if !cm_AUTO_PTR_REF
  70. template <typename Y>
  71. static inline auto_ptr<Y>& cast(auto_ptr<Y> const& a)
  72. {
  73. return const_cast<auto_ptr<Y>&>(a);
  74. }
  75. #endif
  76. /** The pointer to the object held. */
  77. X* x_;
  78. public:
  79. /** The type of object held by the auto_ptr. */
  80. typedef X element_type;
  81. /** Construct from an auto_ptr holding a compatible object. This
  82. transfers ownership to the newly constructed auto_ptr. */
  83. template <class Y>
  84. auto_ptr(auto_ptr<Y> cm_AUTO_PTR_CONST& a) throw()
  85. : x_(cm_AUTO_PTR_CAST(a).release())
  86. {
  87. }
  88. /** Assign from an auto_ptr holding a compatible object. This
  89. transfers ownership to the left-hand-side of the assignment. */
  90. template <class Y>
  91. auto_ptr& operator=(auto_ptr<Y> cm_AUTO_PTR_CONST& a) throw()
  92. {
  93. this->reset(cm_AUTO_PTR_CAST(a).release());
  94. return *this;
  95. }
  96. /**
  97. * Explicitly construct from a raw pointer. This is typically
  98. * called with the result of operator new. For example:
  99. *
  100. * auto_ptr<X> ptr(new X());
  101. */
  102. explicit auto_ptr(X* p = CM_NULLPTR) throw()
  103. : x_(p)
  104. {
  105. }
  106. /** Construct from another auto_ptr holding an object of the same
  107. type. This transfers ownership to the newly constructed
  108. auto_ptr. */
  109. auto_ptr(auto_ptr cm_AUTO_PTR_CONST& a) throw()
  110. : x_(cm_AUTO_PTR_CAST(a).release())
  111. {
  112. }
  113. /** Assign from another auto_ptr holding an object of the same type.
  114. This transfers ownership to the newly constructed auto_ptr. */
  115. auto_ptr& operator=(auto_ptr cm_AUTO_PTR_CONST& a) throw()
  116. {
  117. this->reset(cm_AUTO_PTR_CAST(a).release());
  118. return *this;
  119. }
  120. /** Destruct and delete the object held. */
  121. ~auto_ptr() throw()
  122. {
  123. // Assume object destructor is nothrow.
  124. delete this->x_;
  125. }
  126. /** Dereference and return a reference to the object held. */
  127. X& operator*() const throw() { return *this->x_; }
  128. /** Return a pointer to the object held. */
  129. X* operator->() const throw() { return this->x_; }
  130. /** Return a pointer to the object held. */
  131. X* get() const throw() { return this->x_; }
  132. /** Return a pointer to the object held and reset to hold no object.
  133. This transfers ownership to the caller. */
  134. X* release() throw()
  135. {
  136. X* x = this->x_;
  137. this->x_ = CM_NULLPTR;
  138. return x;
  139. }
  140. /** Assume ownership of the given object. The object previously
  141. held is deleted. */
  142. void reset(X* p = 0) throw()
  143. {
  144. if (this->x_ != p) {
  145. // Assume object destructor is nothrow.
  146. delete this->x_;
  147. this->x_ = p;
  148. }
  149. }
  150. /** Convert to an auto_ptr holding an object of a compatible type.
  151. This transfers ownership to the returned auto_ptr. */
  152. template <class Y>
  153. operator auto_ptr<Y>() throw()
  154. {
  155. return auto_ptr<Y>(this->release());
  156. }
  157. #if cm_AUTO_PTR_REF
  158. /** Construct from an auto_ptr_ref. This is used when the
  159. constructor argument is a call to a function returning an
  160. auto_ptr. */
  161. auto_ptr(detail::auto_ptr_ref<X> r) throw()
  162. : x_(r.p_)
  163. {
  164. }
  165. /** Assign from an auto_ptr_ref. This is used when a function
  166. returning an auto_ptr is passed on the right-hand-side of an
  167. assignment. */
  168. auto_ptr& operator=(detail::auto_ptr_ref<X> r) throw()
  169. {
  170. this->reset(r.p_);
  171. return *this;
  172. }
  173. /** Convert to an auto_ptr_ref. This is used when a function
  174. returning an auto_ptr is the argument to the constructor of
  175. another auto_ptr. */
  176. template <class Y>
  177. operator detail::auto_ptr_ref<Y>() throw()
  178. {
  179. return detail::auto_ptr_ref<Y>(this->release(), 1);
  180. }
  181. #endif
  182. };
  183. } // namespace cm
  184. // Undo warning suppression.
  185. #if defined(__clang__) && defined(__has_warning)
  186. #if __has_warning("-Wdeprecated")
  187. #pragma clang diagnostic pop
  188. #endif
  189. #endif
  190. #endif