Chris@102: ////////////////////////////////////////////////////////////////////////////// Chris@102: // Chris@102: // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost Chris@102: // Software License, Version 1.0. (See accompanying file Chris@102: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: // Chris@102: // See http://www.boost.org/libs/move for documentation. Chris@102: // Chris@102: ////////////////////////////////////////////////////////////////////////////// Chris@102: Chris@102: #ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED Chris@102: #define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED Chris@102: Chris@102: #ifndef BOOST_CONFIG_HPP Chris@102: # include Chris@102: #endif Chris@102: # Chris@102: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@102: # pragma once Chris@102: #endif Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include //For std::size_t,std::nullptr_t Chris@102: Chris@102: //!\file Chris@102: //! Describes the default deleter (destruction policy) of unique_ptr: default_delete. Chris@102: Chris@102: namespace boost{ Chris@102: namespace move_upd { Chris@102: Chris@102: namespace bmupmu = ::boost::move_upmu; Chris@102: Chris@102: //////////////////////////////////////// Chris@102: //// enable_def_del Chris@102: //////////////////////////////////////// Chris@102: Chris@102: //compatible with a pointer type T*: Chris@102: //When either Y* is convertible to T* Chris@102: //Y is U[N] and T is U cv [] Chris@102: template Chris@102: struct def_del_compatible_cond Chris@102: : bmupmu::is_convertible Chris@102: {}; Chris@102: Chris@102: template Chris@102: struct def_del_compatible_cond Chris@102: : def_del_compatible_cond Chris@102: {}; Chris@102: Chris@102: template Chris@102: struct enable_def_del Chris@102: : bmupmu::enable_if_c::value, Type> Chris@102: {}; Chris@102: Chris@102: //////////////////////////////////////// Chris@102: //// enable_defdel_call Chris@102: //////////////////////////////////////// Chris@102: Chris@102: //When 2nd is T[N], 1st(*)[N] shall be convertible to T(*)[N]; Chris@102: //When 2nd is T[], 1st(*)[] shall be convertible to T(*)[]; Chris@102: //Otherwise, 1st* shall be convertible to 2nd*. Chris@102: Chris@102: template Chris@102: struct enable_defdel_call Chris@102: : public enable_def_del Chris@102: {}; Chris@102: Chris@102: template Chris@102: struct enable_defdel_call Chris@102: : public enable_def_del Chris@102: {}; Chris@102: Chris@102: template Chris@102: struct enable_defdel_call Chris@102: : public enable_def_del Chris@102: {}; Chris@102: Chris@102: //////////////////////////////////////// Chris@102: //// Some bool literal zero conversion utilities Chris@102: //////////////////////////////////////// Chris@102: Chris@102: struct bool_conversion {int for_bool; int for_arg(); }; Chris@102: typedef int bool_conversion::* explicit_bool_arg; Chris@102: Chris@102: #if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_CXX11_DECLTYPE) Chris@102: typedef decltype(nullptr) nullptr_type; Chris@102: #elif !defined(BOOST_NO_CXX11_NULLPTR) Chris@102: typedef std::nullptr_t nullptr_type; Chris@102: #else Chris@102: typedef int (bool_conversion::*nullptr_type)(); Chris@102: #endif Chris@102: Chris@102: } //namespace move_upd { Chris@102: Chris@102: namespace movelib { Chris@102: Chris@102: namespace bmupd = boost::move_upd; Chris@102: namespace bmupmu = ::boost::move_upmu; Chris@102: Chris@102: //!The class template default_delete serves as the default deleter Chris@102: //!(destruction policy) for the class template unique_ptr. Chris@102: //! Chris@102: //! \tparam T The type to be deleted. It may be an incomplete type Chris@102: template Chris@102: struct default_delete Chris@102: { Chris@102: //! Default constructor. Chris@102: //! Chris@102: BOOST_CONSTEXPR default_delete() Chris@102: //Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6 Chris@102: #if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED) Chris@102: BOOST_NOEXCEPT Chris@102: #endif Chris@102: #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED) Chris@102: = default; Chris@102: #else Chris@102: {}; Chris@102: #endif Chris@102: Chris@102: #if defined(BOOST_MOVE_DOXYGEN_INVOKED) Chris@102: default_delete(const default_delete&) BOOST_NOEXCEPT = default; Chris@102: default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default; Chris@102: #else Chris@102: typedef typename bmupmu::remove_extent::type element_type; Chris@102: #endif Chris@102: Chris@102: //! Effects: Constructs a default_delete object from another default_delete object. Chris@102: //! Chris@102: //! Remarks: This constructor shall not participate in overload resolution unless: Chris@102: //! - If T is not an array type and U* is implicitly convertible to T*. Chris@102: //! - If T is an array type and U* is a more CV qualified pointer to remove_extent::type. Chris@102: template Chris@102: default_delete(const default_delete& Chris@102: BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_def_del::type* =0) Chris@102: ) BOOST_NOEXCEPT Chris@102: { Chris@102: //If T is not an array type, U derives from T Chris@102: //and T has no virtual destructor, then you have a problem Chris@102: BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor::value )); Chris@102: } Chris@102: Chris@102: //! Effects: Constructs a default_delete object from another default_delete object. Chris@102: //! Chris@102: //! Remarks: This constructor shall not participate in overload resolution unless: Chris@102: //! - If T is not an array type and U* is implicitly convertible to T*. Chris@102: //! - If T is an array type and U* is a more CV qualified pointer to remove_extent::type. Chris@102: template Chris@102: BOOST_MOVE_DOC1ST(default_delete&, Chris@102: typename bmupd::enable_def_del::type) Chris@102: operator=(const default_delete&) BOOST_NOEXCEPT Chris@102: { Chris@102: //If T is not an array type, U derives from T Chris@102: //and T has no virtual destructor, then you have a problem Chris@102: BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor::value )); Chris@102: return *this; Chris@102: } Chris@102: Chris@102: //! Effects: if T is not an array type, calls delete on static_cast(ptr), Chris@102: //! otherwise calls delete[] on static_cast::type*>(ptr). Chris@102: //! Chris@102: //! Remarks: If U is an incomplete type, the program is ill-formed. Chris@102: //! This operator shall not participate in overload resolution unless: Chris@102: //! - T is not an array type and U* is convertible to T*, OR Chris@102: //! - T is an array type, and remove_cv::type is the same type as Chris@102: //! remove_cv::type>::type and U* is convertible to remove_extent::type*. Chris@102: template Chris@102: BOOST_MOVE_DOC1ST(void, typename bmupd::enable_defdel_call::type) Chris@102: operator()(U* ptr) const BOOST_NOEXCEPT Chris@102: { Chris@102: //U must be a complete type Chris@102: BOOST_STATIC_ASSERT(sizeof(U) > 0); Chris@102: //If T is not an array type, U derives from T Chris@102: //and T has no virtual destructor, then you have a problem Chris@102: BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor::value )); Chris@102: element_type * const p = static_cast(ptr); Chris@102: bmupmu::is_array::value ? delete [] p : delete p; Chris@102: } Chris@102: Chris@102: //! Effects: Same as (*this)(static_cast(nullptr)). Chris@102: //! Chris@102: void operator()(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) const BOOST_NOEXCEPT Chris@102: { BOOST_STATIC_ASSERT(sizeof(element_type) > 0); } Chris@102: }; Chris@102: Chris@102: } //namespace movelib { Chris@102: } //namespace boost{ Chris@102: Chris@102: #include Chris@102: Chris@102: #endif //#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED