unique_ptr.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. //////////////////////////////////////////////////////////////////////////////
  2. // I, Howard Hinnant, hereby place this code in the public domain.
  3. //////////////////////////////////////////////////////////////////////////////
  4. //
  5. // This file is the adaptation for Interprocess of
  6. // Howard Hinnant's unique_ptr emulation code.
  7. //
  8. // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
  9. // Software License, Version 1.0. (See accompanying file
  10. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. // See http://www.boost.org/libs/interprocess for documentation.
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #ifndef BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED
  16. #define BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED
  17. #include <boost/interprocess/detail/config_begin.hpp>
  18. #include <boost/interprocess/detail/workaround.hpp>
  19. #include <boost/assert.hpp>
  20. #include <boost/interprocess/detail/utilities.hpp>
  21. #include <boost/interprocess/detail/pointer_type.hpp>
  22. #include <boost/move/move.hpp>
  23. #include <boost/compressed_pair.hpp>
  24. #include <boost/static_assert.hpp>
  25. #include <boost/interprocess/detail/mpl.hpp>
  26. #include <boost/interprocess/detail/type_traits.hpp>
  27. #include <boost/interprocess/smart_ptr/deleter.hpp>
  28. #include <cstddef>
  29. //!\file
  30. //!Describes the smart pointer unique_ptr
  31. namespace boost{
  32. namespace interprocess{
  33. /// @cond
  34. template <class T, class D> class unique_ptr;
  35. namespace ipcdetail {
  36. template <class T> struct unique_ptr_error;
  37. template <class T, class D>
  38. struct unique_ptr_error<const unique_ptr<T, D> >
  39. {
  40. typedef unique_ptr<T, D> type;
  41. };
  42. } //namespace ipcdetail {
  43. /// @endcond
  44. //!Template unique_ptr stores a pointer to an object and deletes that object
  45. //!using the associated deleter when it is itself destroyed (such as when
  46. //!leaving block scope.
  47. //!
  48. //!The unique_ptr provides a semantics of strict ownership. A unique_ptr owns the
  49. //!object it holds a pointer to.
  50. //!
  51. //!A unique_ptr is not CopyConstructible, nor CopyAssignable, however it is
  52. //!MoveConstructible and Move-Assignable.
  53. //!
  54. //!The uses of unique_ptr include providing exception safety for dynamically
  55. //!allocated memory, passing ownership of dynamically allocated memory to a
  56. //!function, and returning dynamically allocated memory from a function
  57. //!
  58. //!A client-supplied template argument D must be a
  59. //!function pointer or functor for which, given a value d of type D and a pointer
  60. //!ptr to a type T*, the expression d(ptr) is
  61. //!valid and has the effect of deallocating the pointer as appropriate for that
  62. //!deleter. D may also be an lvalue-reference to a deleter.
  63. //!
  64. //!If the deleter D maintains state, it is intended that this state stay with
  65. //!the associated pointer as ownership is transferred
  66. //!from unique_ptr to unique_ptr. The deleter state need never be copied,
  67. //!only moved or swapped as pointer ownership
  68. //!is moved around. That is, the deleter need only be MoveConstructible,
  69. //!MoveAssignable, and Swappable, and need not be CopyConstructible
  70. //!(unless copied into the unique_ptr) nor CopyAssignable.
  71. template <class T, class D>
  72. class unique_ptr
  73. {
  74. /// @cond
  75. struct nat {int for_bool;};
  76. struct nat2 {int for_nullptr;};
  77. typedef int nat2::*nullptr_t;
  78. typedef typename ipcdetail::add_reference<D>::type deleter_reference;
  79. typedef typename ipcdetail::add_reference<const D>::type deleter_const_reference;
  80. /// @endcond
  81. public:
  82. typedef T element_type;
  83. typedef D deleter_type;
  84. typedef typename ipcdetail::pointer_type<T, D>::type pointer;
  85. //!Requires: D must be default constructible, and that construction must not
  86. //!throw an exception. D must not be a reference type.
  87. //!
  88. //!Effects: Constructs a unique_ptr which owns nothing.
  89. //!
  90. //!Postconditions: get() == 0. get_deleter() returns a reference to a
  91. //!default constructed deleter D.
  92. //!
  93. //!Throws: nothing.
  94. unique_ptr()
  95. : ptr_(pointer(0))
  96. {}
  97. //!Requires: The expression D()(p) must be well formed. The default constructor
  98. //!of D must not throw an exception.
  99. //!
  100. //!D must not be a reference type.
  101. //!
  102. //!Effects: Constructs a unique_ptr which owns p.
  103. //!
  104. //!Postconditions: get() == p. get_deleter() returns a reference to a default constructed deleter D.
  105. //!
  106. //!Throws: nothing.
  107. explicit unique_ptr(pointer p)
  108. : ptr_(p)
  109. {}
  110. //!Requires: The expression d(p) must be well formed.
  111. //!
  112. //!Postconditions: get() == p. get_deleter() returns a reference to the
  113. //!internally stored deleter. If D is a
  114. //!reference type then get_deleter() returns a reference to the lvalue d.
  115. //!
  116. //!Throws: nothing.
  117. unique_ptr(pointer p
  118. ,typename ipcdetail::if_<ipcdetail::is_reference<D>
  119. ,D
  120. ,typename ipcdetail::add_reference<const D>::type>::type d)
  121. : ptr_(p, d)
  122. {}
  123. //!Requires: If the deleter is not a reference type, construction of the
  124. //!deleter D from an lvalue D must not throw an exception.
  125. //!
  126. //!Effects: Constructs a unique_ptr which owns the pointer which u owns
  127. //!(if any). If the deleter is not a reference type, it is move constructed
  128. //!from u's deleter, otherwise the reference is copy constructed from u's deleter.
  129. //!
  130. //!After the construction, u no longer owns a pointer.
  131. //![ Note: The deleter constructor can be implemented with
  132. //! boost::forward<D>. -end note ]
  133. //!
  134. //!Postconditions: get() == value u.get() had before the construction.
  135. //!get_deleter() returns a reference to the internally stored deleter which
  136. //!was constructed from u.get_deleter(). If D is a reference type then get_-
  137. //!deleter() and u.get_deleter() both reference the same lvalue deleter.
  138. //!
  139. //!Throws: nothing.
  140. unique_ptr(BOOST_RV_REF(unique_ptr) u)
  141. : ptr_(u.release(), boost::forward<D>(u.get_deleter()))
  142. {}
  143. //!Requires: If D is not a reference type, construction of the deleter
  144. //!D from an rvalue of type E must be well formed
  145. //!and not throw an exception. If D is a reference type, then E must be
  146. //!the same type as D (diagnostic required). unique_ptr<U, E>::pointer
  147. //!must be implicitly convertible to pointer.
  148. //!
  149. //!Effects: Constructs a unique_ptr which owns the pointer which u owns
  150. //!(if any). If the deleter is not a reference
  151. //!type, it is move constructed from u's deleter, otherwise the reference
  152. //!is copy constructed from u's deleter.
  153. //!
  154. //!After the construction, u no longer owns a pointer.
  155. //!
  156. //!postconditions get() == value u.get() had before the construction,
  157. //!modulo any required offset adjustments
  158. //!resulting from the cast from U* to T*. get_deleter() returns a reference to the internally stored deleter which
  159. //!was constructed from u.get_deleter().
  160. //!
  161. //!Throws: nothing.
  162. template <class U, class E>
  163. unique_ptr(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u,
  164. typename ipcdetail::enable_if_c<
  165. ipcdetail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
  166. ipcdetail::is_convertible<E, D>::value &&
  167. (
  168. !ipcdetail::is_reference<D>::value ||
  169. ipcdetail::is_same<D, E>::value
  170. )
  171. ,
  172. nat
  173. >::type = nat())
  174. : ptr_(const_cast<unique_ptr<U,E>&>(u).release(), boost::move<D>(u.get_deleter()))
  175. {}
  176. //!Effects: If get() == 0 there are no effects. Otherwise get_deleter()(get()).
  177. //!
  178. //!Throws: nothing.
  179. ~unique_ptr()
  180. { reset(); }
  181. // assignment
  182. //!Requires: Assignment of the deleter D from an rvalue D must not throw an exception.
  183. //!
  184. //!Effects: reset(u.release()) followed by a move assignment from u's deleter to
  185. //!this deleter.
  186. //!
  187. //!Postconditions: This unique_ptr now owns the pointer which u owned, and u no
  188. //!longer owns it.
  189. //!
  190. //!Returns: *this.
  191. //!
  192. //!Throws: nothing.
  193. unique_ptr& operator=(BOOST_RV_REF(unique_ptr) u)
  194. {
  195. reset(u.release());
  196. ptr_.second() = boost::move(u.get_deleter());
  197. return *this;
  198. }
  199. //!Requires: Assignment of the deleter D from an rvalue D must not
  200. //!throw an exception. U* must be implicitly convertible to T*.
  201. //!
  202. //!Effects: reset(u.release()) followed by a move assignment from
  203. //!u's deleter to this deleter. If either D or E is
  204. //!a reference type, then the referenced lvalue deleter participates
  205. //!in the move assignment.
  206. //!
  207. //!Postconditions: This unique_ptr now owns the pointer which u owned,
  208. //!and u no longer owns it.
  209. //!
  210. //!Returns: *this.
  211. //!
  212. //!Throws: nothing.
  213. template <class U, class E>
  214. unique_ptr& operator=(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u)
  215. {
  216. reset(u.release());
  217. ptr_.second() = boost::move(u.get_deleter());
  218. return *this;
  219. }
  220. //!Assigns from the literal 0 or NULL.
  221. //!
  222. //!Effects: reset().
  223. //!
  224. //!Postcondition: get() == 0
  225. //!
  226. //!Returns: *this.
  227. //!
  228. //!Throws: nothing.
  229. unique_ptr& operator=(nullptr_t)
  230. {
  231. reset();
  232. return *this;
  233. }
  234. //!Requires: get() != 0.
  235. //!Returns: *get().
  236. //!Throws: nothing.
  237. typename ipcdetail::add_reference<T>::type operator*() const
  238. { return *ptr_.first(); }
  239. //!Requires: get() != 0.
  240. //!Returns: get().
  241. //!Throws: nothing.
  242. pointer operator->() const
  243. { return ptr_.first(); }
  244. //!Returns: The stored pointer.
  245. //!Throws: nothing.
  246. pointer get() const
  247. { return ptr_.first(); }
  248. //!Returns: A reference to the stored deleter.
  249. //!
  250. //!Throws: nothing.
  251. deleter_reference get_deleter()
  252. { return ptr_.second(); }
  253. //!Returns: A const reference to the stored deleter.
  254. //!
  255. //!Throws: nothing.
  256. deleter_const_reference get_deleter() const
  257. { return ptr_.second(); }
  258. //!Returns: An unspecified value that, when used in boolean
  259. //!contexts, is equivalent to get() != 0.
  260. //!
  261. //!Throws: nothing.
  262. operator int nat::*() const
  263. { return ptr_.first() ? &nat::for_bool : 0; }
  264. //!Postcondition: get() == 0.
  265. //!
  266. //!Returns: The value get() had at the start of the call to release.
  267. //!
  268. //!Throws: nothing.
  269. pointer release()
  270. {
  271. pointer tmp = ptr_.first();
  272. ptr_.first() = 0;
  273. return tmp;
  274. }
  275. //!Effects: If p == get() there are no effects. Otherwise get_deleter()(get()).
  276. //!
  277. //!Postconditions: get() == p.
  278. //!
  279. //!Throws: nothing.
  280. void reset(pointer p = 0)
  281. {
  282. if (ptr_.first() != p){
  283. if (ptr_.first())
  284. ptr_.second()(ptr_.first());
  285. ptr_.first() = p;
  286. }
  287. }
  288. //!Requires: The deleter D is Swappable and will not throw an exception under swap.
  289. //!
  290. //!Effects: The stored pointers of this and u are exchanged.
  291. //! The stored deleters are swapped (unqualified).
  292. //!Throws: nothing.
  293. void swap(unique_ptr& u)
  294. { ptr_.swap(u.ptr_); }
  295. /// @cond
  296. private:
  297. boost::compressed_pair<pointer, D> ptr_;
  298. BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
  299. template <class U, class E> unique_ptr(unique_ptr<U, E>&);
  300. template <class U> unique_ptr(U&, typename ipcdetail::unique_ptr_error<U>::type = 0);
  301. template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&);
  302. template <class U> typename ipcdetail::unique_ptr_error<U>::type operator=(U&);
  303. /// @endcond
  304. };
  305. /*
  306. template <class T, class D>
  307. class unique_ptr<T[], D>
  308. {
  309. struct nat {int for_bool_;};
  310. typedef typename ipcdetail::add_reference<D>::type deleter_reference;
  311. typedef typename ipcdetail::add_reference<const D>::type deleter_const_reference;
  312. public:
  313. typedef T element_type;
  314. typedef D deleter_type;
  315. typedef typename ipcdetail::pointer_type<T, D>::type pointer;
  316. // constructors
  317. unique_ptr() : ptr_(pointer()) {}
  318. explicit unique_ptr(pointer p) : ptr_(p) {}
  319. unique_ptr(pointer p, typename if_<
  320. boost::is_reference<D>,
  321. D,
  322. typename ipcdetail::add_reference<const D>::type>::type d)
  323. : ptr_(p, d) {}
  324. unique_ptr(const unique_ptr& u)
  325. : ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter()) {}
  326. // destructor
  327. ~unique_ptr() {reset();}
  328. // assignment
  329. unique_ptr& operator=(const unique_ptr& cu)
  330. {
  331. unique_ptr& u = const_cast<unique_ptr&>(cu);
  332. reset(u.release());
  333. ptr_.second() = u.get_deleter();
  334. return *this;
  335. }
  336. unique_ptr& operator=(int nat::*)
  337. {
  338. reset();
  339. return *this;
  340. }
  341. // observers
  342. typename ipcdetail::add_reference<T>::type operator[](std::size_t i) const {return ptr_.first()[i];}
  343. pointer get() const {return ptr_.first();}
  344. deleter_reference get_deleter() {return ptr_.second();}
  345. deleter_const_reference get_deleter() const {return ptr_.second();}
  346. operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;}
  347. // modifiers
  348. pointer release()
  349. {
  350. pointer tmp = ptr_.first();
  351. ptr_.first() = 0;
  352. return tmp;
  353. }
  354. void reset(pointer p = 0)
  355. {
  356. if (ptr_.first() != p)
  357. {
  358. if (ptr_.first())
  359. ptr_.second()(ptr_.first());
  360. ptr_.first() = p;
  361. }
  362. }
  363. void swap(unique_ptr& u) {ptr_.swap(u.ptr_);}
  364. private:
  365. boost::compressed_pair<pointer, D> ptr_;
  366. template <class U, class E> unique_ptr(U p, E,
  367. typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
  368. template <class U> explicit unique_ptr(U,
  369. typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
  370. unique_ptr(unique_ptr&);
  371. template <class U> unique_ptr(U&, typename ipcdetail::unique_ptr_error<U>::type = 0);
  372. unique_ptr& operator=(unique_ptr&);
  373. template <class U> typename ipcdetail::unique_ptr_error<U>::type operator=(U&);
  374. };
  375. template <class T, class D, std::size_t N>
  376. class unique_ptr<T[N], D>
  377. {
  378. struct nat {int for_bool_;};
  379. typedef typename ipcdetail::add_reference<D>::type deleter_reference;
  380. typedef typename ipcdetail::add_reference<const D>::type deleter_const_reference;
  381. public:
  382. typedef T element_type;
  383. typedef D deleter_type;
  384. typedef typename ipcdetail::pointer_type<T, D>::type pointer;
  385. static const std::size_t size = N;
  386. // constructors
  387. unique_ptr() : ptr_(0) {}
  388. explicit unique_ptr(pointer p) : ptr_(p) {}
  389. unique_ptr(pointer p, typename if_<
  390. boost::is_reference<D>,
  391. D,
  392. typename ipcdetail::add_reference<const D>::type>::type d)
  393. : ptr_(p, d) {}
  394. unique_ptr(const unique_ptr& u)
  395. : ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter()) {}
  396. // destructor
  397. ~unique_ptr() {reset();}
  398. // assignment
  399. unique_ptr& operator=(const unique_ptr& cu)
  400. {
  401. unique_ptr& u = const_cast<unique_ptr&>(cu);
  402. reset(u.release());
  403. ptr_.second() = u.get_deleter();
  404. return *this;
  405. }
  406. unique_ptr& operator=(int nat::*)
  407. {
  408. reset();
  409. return *this;
  410. }
  411. // observers
  412. typename ipcdetail::add_reference<T>::type operator[](std::size_t i) const {return ptr_.first()[i];}
  413. pointer get() const {return ptr_.first();}
  414. deleter_reference get_deleter() {return ptr_.second();}
  415. deleter_const_reference get_deleter() const {return ptr_.second();}
  416. operator int nat::*() const {return ptr_.first() ? &nat::for_bool : 0;}
  417. // modifiers
  418. pointer release()
  419. {
  420. pointer tmp = ptr_.first();
  421. ptr_.first() = 0;
  422. return tmp;
  423. }
  424. void reset(pointer p = 0)
  425. {
  426. if (ptr_.first() != p)
  427. {
  428. if (ptr_.first())
  429. ptr_.second()(ptr_.first(), N);
  430. ptr_.first() = p;
  431. }
  432. }
  433. void swap(unique_ptr& u) {ptr_.swap(u.ptr_);}
  434. private:
  435. boost::compressed_pair<pointer, D> ptr_;
  436. template <class U, class E> unique_ptr(U p, E,
  437. typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
  438. template <class U> explicit unique_ptr(U,
  439. typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
  440. unique_ptr(unique_ptr&);
  441. template <class U> unique_ptr(U&, typename ipcdetail::unique_ptr_error<U>::type = 0);
  442. unique_ptr& operator=(unique_ptr&);
  443. template <class U> typename ipcdetail::unique_ptr_error<U>::type operator=(U&);
  444. };
  445. */
  446. template <class T, class D> inline
  447. void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y)
  448. { x.swap(y); }
  449. template <class T1, class D1, class T2, class D2> inline
  450. bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
  451. { return x.get() == y.get(); }
  452. template <class T1, class D1, class T2, class D2> inline
  453. bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
  454. { return x.get() != y.get(); }
  455. template <class T1, class D1, class T2, class D2> inline
  456. bool operator <(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
  457. { return x.get() < y.get(); }
  458. template <class T1, class D1, class T2, class D2> inline
  459. bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
  460. { return x.get() <= y.get(); }
  461. template <class T1, class D1, class T2, class D2> inline
  462. bool operator >(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
  463. { return x.get() > y.get(); }
  464. template <class T1, class D1, class T2, class D2> inline
  465. bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
  466. { return x.get() >= y.get(); }
  467. //!Returns the type of a unique pointer
  468. //!of type T with boost::interprocess::deleter deleter
  469. //!that can be constructed in the given managed segment type.
  470. template<class T, class ManagedMemory>
  471. struct managed_unique_ptr
  472. {
  473. typedef unique_ptr
  474. < T
  475. , typename ManagedMemory::template deleter<T>::type
  476. > type;
  477. };
  478. //!Returns an instance of a unique pointer constructed
  479. //!with boost::interproces::deleter from a pointer
  480. //!of type T that has been allocated in the passed managed segment
  481. template<class T, class ManagedMemory>
  482. inline typename managed_unique_ptr<T, ManagedMemory>::type
  483. make_managed_unique_ptr(T *constructed_object, ManagedMemory &managed_memory)
  484. {
  485. return typename managed_unique_ptr<T, ManagedMemory>::type
  486. (constructed_object, managed_memory.template get_deleter<T>());
  487. }
  488. } //namespace interprocess{
  489. } //namespace boost{
  490. #include <boost/interprocess/detail/config_end.hpp>
  491. #endif //#ifndef BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED