default_delete.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/move for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
  11. #define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #
  16. #if defined(BOOST_HAS_PRAGMA_ONCE)
  17. # pragma once
  18. #endif
  19. #include <boost/move/detail/config_begin.hpp>
  20. #include <boost/move/detail/workaround.hpp>
  21. #include <boost/move/detail/unique_ptr_meta_utils.hpp>
  22. #include <boost/move/utility_core.hpp>
  23. #include <boost/static_assert.hpp>
  24. #include <cstddef> //For std::size_t,std::nullptr_t
  25. //!\file
  26. //! Describes the default deleter (destruction policy) of <tt>unique_ptr</tt>: <tt>default_delete</tt>.
  27. namespace boost{
  28. // @cond
  29. namespace move_upd {
  30. namespace bmupmu = ::boost::move_upmu;
  31. ////////////////////////////////////////
  32. //// enable_def_del
  33. ////////////////////////////////////////
  34. //compatible with a pointer type T*:
  35. //When either Y* is convertible to T*
  36. //Y is U[N] and T is U cv []
  37. template<class U, class T>
  38. struct def_del_compatible_cond
  39. : bmupmu::is_convertible<U*, T*>
  40. {};
  41. template<class U, class T, std::size_t N>
  42. struct def_del_compatible_cond<U[N], T[]>
  43. : def_del_compatible_cond<U[], T[]>
  44. {};
  45. template<class U, class T, class Type = bmupmu::nat>
  46. struct enable_def_del
  47. : bmupmu::enable_if_c<def_del_compatible_cond<U, T>::value, Type>
  48. {};
  49. ////////////////////////////////////////
  50. //// enable_defdel_call
  51. ////////////////////////////////////////
  52. //When 2nd is T[N], 1st(*)[N] shall be convertible to T(*)[N];
  53. //When 2nd is T[], 1st(*)[] shall be convertible to T(*)[];
  54. //Otherwise, 1st* shall be convertible to 2nd*.
  55. template<class U, class T, class Type = bmupmu::nat>
  56. struct enable_defdel_call
  57. : public enable_def_del<U, T, Type>
  58. {};
  59. template<class U, class T, class Type>
  60. struct enable_defdel_call<U, T[], Type>
  61. : public enable_def_del<U[], T[], Type>
  62. {};
  63. template<class U, class T, class Type, std::size_t N>
  64. struct enable_defdel_call<U, T[N], Type>
  65. : public enable_def_del<U[N], T[N], Type>
  66. {};
  67. ////////////////////////////////////////
  68. //// Some bool literal zero conversion utilities
  69. ////////////////////////////////////////
  70. struct bool_conversion {int for_bool; int for_arg(); };
  71. typedef int bool_conversion::* explicit_bool_arg;
  72. #if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_CXX11_DECLTYPE)
  73. typedef decltype(nullptr) nullptr_type;
  74. #elif !defined(BOOST_NO_CXX11_NULLPTR)
  75. typedef std::nullptr_t nullptr_type;
  76. #else
  77. typedef int (bool_conversion::*nullptr_type)();
  78. #endif
  79. template<bool B>
  80. struct is_array_del
  81. {};
  82. template<class T>
  83. void call_delete(T *p, is_array_del<true>)
  84. {
  85. delete [] p;
  86. }
  87. template<class T>
  88. void call_delete(T *p, is_array_del<false>)
  89. {
  90. delete p;
  91. }
  92. } //namespace move_upd {
  93. // @endcond
  94. namespace movelib {
  95. namespace bmupd = boost::move_upd;
  96. namespace bmupmu = ::boost::move_upmu;
  97. //!The class template <tt>default_delete</tt> serves as the default deleter
  98. //!(destruction policy) for the class template <tt>unique_ptr</tt>.
  99. //!
  100. //! \tparam T The type to be deleted. It may be an incomplete type
  101. template <class T>
  102. struct default_delete
  103. {
  104. //! Default constructor.
  105. //!
  106. BOOST_CONSTEXPR default_delete()
  107. //Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6
  108. #if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
  109. BOOST_NOEXCEPT
  110. #endif
  111. #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
  112. = default;
  113. #else
  114. {};
  115. #endif
  116. #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
  117. //! Trivial copy constructor
  118. //!
  119. default_delete(const default_delete&) BOOST_NOEXCEPT = default;
  120. //! Trivial assignment
  121. //!
  122. default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default;
  123. #else
  124. typedef typename bmupmu::remove_extent<T>::type element_type;
  125. #endif
  126. //! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
  127. //!
  128. //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
  129. //! - If T is not an array type and U* is implicitly convertible to T*.
  130. //! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
  131. template <class U>
  132. default_delete(const default_delete<U>&
  133. BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_def_del<U BOOST_MOVE_I T>::type* =0)
  134. ) BOOST_NOEXCEPT
  135. {
  136. //If T is not an array type, U derives from T
  137. //and T has no virtual destructor, then you have a problem
  138. BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
  139. }
  140. //! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
  141. //!
  142. //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
  143. //! - If T is not an array type and U* is implicitly convertible to T*.
  144. //! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
  145. template <class U>
  146. BOOST_MOVE_DOC1ST(default_delete&,
  147. typename bmupd::enable_def_del<U BOOST_MOVE_I T BOOST_MOVE_I default_delete &>::type)
  148. operator=(const default_delete<U>&) BOOST_NOEXCEPT
  149. {
  150. //If T is not an array type, U derives from T
  151. //and T has no virtual destructor, then you have a problem
  152. BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
  153. return *this;
  154. }
  155. //! <b>Effects</b>: if T is not an array type, calls <tt>delete</tt> on static_cast<T*>(ptr),
  156. //! otherwise calls <tt>delete[]</tt> on static_cast<remove_extent<T>::type*>(ptr).
  157. //!
  158. //! <b>Remarks</b>: If U is an incomplete type, the program is ill-formed.
  159. //! This operator shall not participate in overload resolution unless:
  160. //! - T is not an array type and U* is convertible to T*, OR
  161. //! - T is an array type, and remove_cv<U>::type is the same type as
  162. //! remove_cv<remove_extent<T>::type>::type and U* is convertible to remove_extent<T>::type*.
  163. template <class U>
  164. BOOST_MOVE_DOC1ST(void, typename bmupd::enable_defdel_call<U BOOST_MOVE_I T BOOST_MOVE_I void>::type)
  165. operator()(U* ptr) const BOOST_NOEXCEPT
  166. {
  167. //U must be a complete type
  168. BOOST_STATIC_ASSERT(sizeof(U) > 0);
  169. //If T is not an array type, U derives from T
  170. //and T has no virtual destructor, then you have a problem
  171. BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
  172. element_type * const p = static_cast<element_type*>(ptr);
  173. move_upd::call_delete(p, move_upd::is_array_del<bmupmu::is_array<T>::value>());
  174. }
  175. //! <b>Effects</b>: Same as <tt>(*this)(static_cast<element_type*>(nullptr))</tt>.
  176. //!
  177. void operator()(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) const BOOST_NOEXCEPT
  178. { BOOST_STATIC_ASSERT(sizeof(element_type) > 0); }
  179. };
  180. } //namespace movelib {
  181. } //namespace boost{
  182. #include <boost/move/detail/config_end.hpp>
  183. #endif //#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED