📄 unique_ptr.hpp
字号:
//////////////////////////////////////////////////////////////////////////////// I, Howard Hinnant, hereby place this code in the public domain.////////////////////////////////////////////////////////////////////////////////// This file is the adaptation for Interprocess of// Howard Hinnant's unique_ptr emulation code.//// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost// Software License, Version 1.0. (See accompanying file// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/interprocess for documentation.////////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED#define BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED#include <boost/interprocess/detail/config_begin.hpp>#include <boost/interprocess/detail/workaround.hpp>#include <boost/assert.hpp>#include <boost/interprocess/detail/utilities.hpp>#include <boost/interprocess/detail/pointer_type.hpp>#include <boost/interprocess/detail/move.hpp>#include <boost/compressed_pair.hpp>#include <boost/static_assert.hpp>#include <boost/interprocess/detail/mpl.hpp>#include <boost/interprocess/detail/type_traits.hpp>#include <boost/interprocess/smart_ptr/deleter.hpp>#include <cstddef>//!\file//!Describes the smart pointer unique_ptrnamespace boost{namespace interprocess{/// @condtemplate <class T, class D> class unique_ptr;namespace detail {template <class T> struct unique_ptr_error;template <class T, class D>struct unique_ptr_error<const unique_ptr<T, D> >{ typedef unique_ptr<T, D> type;};} //namespace detail {/// @endcond//!Template unique_ptr stores a pointer to an object and deletes that object//!using the associated deleter when it is itself destroyed (such as when//!leaving block scope.//!//!The unique_ptr provides a semantics of strict ownership. A unique_ptr owns the//!object it holds a pointer to.//!//!A unique_ptr is not CopyConstructible, nor CopyAssignable, however it is//!MoveConstructible and Move-Assignable.//!//!The uses of unique_ptr include providing exception safety for dynamically//!allocated memory, passing ownership of dynamically allocated memory to a//!function, and returning dynamically allocated memory from a function//!//!A client-supplied template argument D must be a//!function pointer or functor for which, given a value d of type D and a pointer//!ptr to a type T*, the expression d(ptr) is//!valid and has the effect of deallocating the pointer as appropriate for that//!deleter. D may also be an lvalue-reference to a deleter.//!//!If the deleter D maintains state, it is intended that this state stay with//!the associated pointer as ownership is transferred//!from unique_ptr to unique_ptr. The deleter state need never be copied,//!only moved or swapped as pointer ownership//!is moved around. That is, the deleter need only be MoveConstructible,//!MoveAssignable, and Swappable, and need not be CopyConstructible//!(unless copied into the unique_ptr) nor CopyAssignable.template <class T, class D>class unique_ptr{ /// @cond struct nat {int for_bool_;}; typedef typename detail::add_reference<D>::type deleter_reference; typedef typename detail::add_reference<const D>::type deleter_const_reference; /// @endcond public: typedef T element_type; typedef D deleter_type; typedef typename detail::pointer_type<T, D>::type pointer; //!Requires: D must be default constructible, and that construction must not //!throw an exception. D must not be a reference type. //! //!Effects: Constructs a unique_ptr which owns nothing. //! //!Postconditions: get() == 0. get_deleter() returns a reference to a //!default constructed deleter D. //! //!Throws: nothing. unique_ptr() : ptr_(pointer(0)) {} //!Requires: The expression D()(p) must be well formed. The default constructor //!of D must not throw an exception. //! //!D must not be a reference type. //! //!Effects: Constructs a unique_ptr which owns p. //! //!Postconditions: get() == p. get_deleter() returns a reference to a default constructed deleter D. //! //!Throws: nothing. explicit unique_ptr(pointer p) : ptr_(p) {} //!Requires: The expression d(p) must be well formed. //! //!Postconditions: get() == p. get_deleter() returns a reference to the //!internally stored deleter. If D is a //!reference type then get_deleter() returns a reference to the lvalue d. //! //!Throws: nothing. unique_ptr(pointer p ,typename detail::if_<detail::is_reference<D> ,D ,typename detail::add_reference<const D>::type>::type d) : ptr_(p, d) {} //!Requires: If the deleter is not a reference type, construction of the //!deleter D from an lvalue D must not throw an exception. //! //!Effects: Constructs a unique_ptr which owns the pointer which u owns //!(if any). If the deleter is not a reference type, it is move constructed //!from u's deleter, otherwise the reference is copy constructed from u's deleter. //! //!After the construction, u no longer owns a pointer. //![ Note: The deleter constructor can be implemented with //!std::detail::forward_impl<D>. -end note ] //! //!Postconditions: get() == value u.get() had before the construction. //!get_deleter() returns a reference to the internally stored deleter which //!was constructed from u.get_deleter(). If D is a reference type then get_- //!deleter() and u.get_deleter() both reference the same lvalue deleter. //! //!Throws: nothing. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE unique_ptr(detail::moved_object<unique_ptr> u) : ptr_(u.get().release(), detail::move_impl(u.get().get_deleter())) {} #else unique_ptr(unique_ptr &&u) : ptr_(u.release(), detail::forward_impl<D>(u.get_deleter())) {} #endif //!Requires: If D is not a reference type, construction of the deleter //!D from an rvalue of type E must be well formed //!and not throw an exception. If D is a reference type, then E must be //!the same type as D (diagnostic required). unique_ptr<U, E>::pointer //!must be implicitly convertible to pointer. //! //!Effects: Constructs a unique_ptr which owns the pointer which u owns //!(if any). If the deleter is not a reference //!type, it is move constructed from u's deleter, otherwise the reference //!is copy constructed from u's deleter. //! //!After the construction, u no longer owns a pointer. //! //!postconditions get() == value u.get() had before the construction, //!modulo any required offset adjustments //!resulting from the cast from U* to T*. get_deleter() returns a reference to the internally stored deleter which //!was constructed from u.get_deleter(). //! //!Throws: nothing. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE template <class U, class E> unique_ptr(detail::moved_object<unique_ptr<U, E> > u, typename detail::enable_if_c< detail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value && detail::is_convertible<E, D>::value && ( !detail::is_reference<D>::value || detail::is_same<D, E>::value ) , nat >::type = nat()) : ptr_(const_cast<unique_ptr<U,E>&>(u.get()).release(), detail::move_impl(u.get().get_deleter())) {} #else template <class U, class E> unique_ptr(unique_ptr<U, E> && u, typename detail::enable_if_c< detail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value && detail::is_convertible<E, D>::value && ( !detail::is_reference<D>::value || detail::is_same<D, E>::value ) , nat >::type = nat()) : ptr_(const_cast<unique_ptr<U,E>&>(u).release(), detail::forward_impl<D>(u.get_deleter())) {} #endif //!Effects: If get() == 0 there are no effects. Otherwise get_deleter()(get()). //! //!Throws: nothing. ~unique_ptr() { reset(); } // assignment //!Requires: Assignment of the deleter D from an rvalue D must not throw an exception. //! //!Effects: reset(u.release()) followed by a move assignment from u's deleter to //!this deleter. //! //!Postconditions: This unique_ptr now owns the pointer which u owned, and u no //!longer owns it. //! //!Returns: *this. //! //!Throws: nothing. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE unique_ptr& operator=(detail::moved_object<unique_ptr> u) { reset(u.get().release()); ptr_.second() = detail::move_impl(u.get().get_deleter()); return *this; } #else unique_ptr& operator=(unique_ptr && u) { reset(u.release()); ptr_.second() = detail::move_impl(u.get_deleter()); return *this; } #endif //!Requires: Assignment of the deleter D from an rvalue D must not //!throw an exception. U* must be implicitly convertible to T*. //! //!Effects: reset(u.release()) followed by a move assignment from //!u's deleter to this deleter. If either D or E is //!a reference type, then the referenced lvalue deleter participates //!in the move assignment. //! //!Postconditions: This unique_ptr now owns the pointer which u owned, //!and u no longer owns it. //! //!Returns: *this. //! //!Throws: nothing. template <class U, class E> #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE unique_ptr& operator=(detail::moved_object<unique_ptr<U, E> > mu) { reset(mu.get().release()); ptr_.second() = detail::move_impl(mu.get().get_deleter()); return *this; } #else unique_ptr& operator=(unique_ptr<U, E> && u) { reset(u.release()); ptr_.second() = detail::move_impl(u.get_deleter()); return *this; } #endif //!Assigns from the literal 0 or NULL. //! //!Effects: reset(). //! //!Postcondition: get() == 0 //! //!Returns: *this. //! //!Throws: nothing. unique_ptr& operator=(int nat::*) { reset(); return *this; } //!Requires: get() != 0. //!Returns: *get(). //!Throws: nothing. typename detail::add_reference<T>::type operator*() const { return *ptr_.first(); } //!Requires: get() != 0. //!Returns: get(). //!Throws: nothing. pointer operator->() const { return ptr_.first(); } //!Returns: The stored pointer. //!Throws: nothing. pointer get() const { return ptr_.first(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -