reversible_ptr_container.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. //
  2. // Boost.Pointer Container
  3. //
  4. // Copyright Thorsten Ottosen 2003-2005. Use, modification and
  5. // distribution is subject to the Boost Software License, Version
  6. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // For more information, see http://www.boost.org/libs/ptr_container/
  10. //
  11. #ifndef BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
  12. #define BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif
  16. #include <boost/ptr_container/detail/throw_exception.hpp>
  17. #include <boost/ptr_container/detail/scoped_deleter.hpp>
  18. #include <boost/ptr_container/detail/static_move_ptr.hpp>
  19. #include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
  20. #include <boost/ptr_container/exception.hpp>
  21. #include <boost/ptr_container/clone_allocator.hpp>
  22. #include <boost/ptr_container/nullable.hpp>
  23. #ifdef BOOST_NO_SFINAE
  24. #else
  25. #include <boost/range/functions.hpp>
  26. #endif
  27. #include <boost/config.hpp>
  28. #include <boost/iterator/reverse_iterator.hpp>
  29. #include <boost/range/iterator.hpp>
  30. #include <boost/utility/enable_if.hpp>
  31. #include <boost/type_traits/is_pointer.hpp>
  32. #include <boost/type_traits/is_integral.hpp>
  33. #include <boost/core/invoke_swap.hpp>
  34. #include <typeinfo>
  35. #include <memory>
  36. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  37. #pragma warning(push)
  38. #pragma warning(disable:4127)
  39. #pragma warning(disable:4224) // formal parameter was previously defined as a type.
  40. #endif
  41. #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
  42. #pragma GCC diagnostic push
  43. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  44. #endif
  45. namespace boost
  46. {
  47. namespace ptr_container_detail
  48. {
  49. template< class Container >
  50. struct dynamic_clone_deleter
  51. {
  52. dynamic_clone_deleter() { }
  53. dynamic_clone_deleter( Container& cont ) : cont(&cont) { }
  54. Container* cont;
  55. template< class T >
  56. void operator()( const T* p ) const
  57. {
  58. // remark: static_move_ptr already test for null
  59. cont->get_clone_allocator().deallocate_clone( p );
  60. }
  61. };
  62. template< class CloneAllocator >
  63. struct static_clone_deleter
  64. {
  65. static_clone_deleter() { }
  66. template< class Dummy >
  67. static_clone_deleter( const Dummy& ) { }
  68. template< class T >
  69. void operator()( const T* p ) const
  70. {
  71. // remark: static_move_ptr already test for null
  72. CloneAllocator::deallocate_clone( p );
  73. }
  74. };
  75. template< class T >
  76. struct is_pointer_or_integral
  77. {
  78. BOOST_STATIC_CONSTANT(bool, value = is_pointer<T>::value || is_integral<T>::value );
  79. };
  80. struct is_pointer_or_integral_tag {};
  81. struct is_range_tag {};
  82. struct sequence_tag {};
  83. struct fixed_length_sequence_tag : sequence_tag {};
  84. struct associative_container_tag {};
  85. struct ordered_associative_container_tag : associative_container_tag {};
  86. struct unordered_associative_container_tag : associative_container_tag {};
  87. template
  88. <
  89. class Config,
  90. class CloneAllocator
  91. >
  92. class reversible_ptr_container : CloneAllocator
  93. {
  94. private:
  95. BOOST_STATIC_CONSTANT( bool, allow_null = Config::allow_null );
  96. BOOST_STATIC_CONSTANT( bool, is_clone_allocator_empty = sizeof(CloneAllocator) < sizeof(void*) );
  97. typedef BOOST_DEDUCED_TYPENAME Config::value_type Ty_;
  98. typedef BOOST_DEDUCED_TYPENAME Config::void_container_type container_type;
  99. typedef dynamic_clone_deleter<reversible_ptr_container> dynamic_deleter_type;
  100. typedef static_clone_deleter<CloneAllocator> static_deleter_type;
  101. container_type c_;
  102. public:
  103. container_type& base() { return c_; }
  104. protected: // having this public could break encapsulation
  105. const container_type& base() const { return c_; }
  106. public: // typedefs
  107. typedef Ty_ object_type;
  108. typedef Ty_* value_type;
  109. typedef Ty_* pointer;
  110. typedef Ty_& reference;
  111. typedef const Ty_& const_reference;
  112. typedef BOOST_DEDUCED_TYPENAME Config::iterator
  113. iterator;
  114. typedef BOOST_DEDUCED_TYPENAME Config::const_iterator
  115. const_iterator;
  116. typedef boost::reverse_iterator< iterator >
  117. reverse_iterator;
  118. typedef boost::reverse_iterator< const_iterator >
  119. const_reverse_iterator;
  120. typedef BOOST_DEDUCED_TYPENAME container_type::difference_type
  121. difference_type;
  122. typedef BOOST_DEDUCED_TYPENAME container_type::size_type
  123. size_type;
  124. typedef BOOST_DEDUCED_TYPENAME Config::allocator_type
  125. allocator_type;
  126. typedef CloneAllocator clone_allocator_type;
  127. typedef ptr_container_detail::static_move_ptr<Ty_,
  128. BOOST_DEDUCED_TYPENAME boost::mpl::if_c<is_clone_allocator_empty,
  129. static_deleter_type,
  130. dynamic_deleter_type>::type
  131. >
  132. auto_type;
  133. protected:
  134. typedef ptr_container_detail::scoped_deleter<reversible_ptr_container>
  135. scoped_deleter;
  136. typedef BOOST_DEDUCED_TYPENAME container_type::iterator
  137. ptr_iterator;
  138. typedef BOOST_DEDUCED_TYPENAME container_type::const_iterator
  139. ptr_const_iterator;
  140. private:
  141. template< class InputIterator >
  142. void copy( InputIterator first, InputIterator last )
  143. {
  144. std::copy( first, last, begin() );
  145. }
  146. void copy( const reversible_ptr_container& r )
  147. {
  148. this->copy( r.begin(), r.end() );
  149. }
  150. void copy_clones_and_release( scoped_deleter& sd ) // nothrow
  151. {
  152. BOOST_ASSERT( size_type( std::distance( sd.begin(), sd.end() ) ) == c_.size() );
  153. std::copy( sd.begin(), sd.end(), c_.begin() );
  154. sd.release();
  155. }
  156. template< class ForwardIterator >
  157. void clone_assign( ForwardIterator first,
  158. ForwardIterator last ) // strong
  159. {
  160. BOOST_ASSERT( first != last );
  161. scoped_deleter sd( *this, first, last ); // strong
  162. copy_clones_and_release( sd ); // nothrow
  163. }
  164. template< class ForwardIterator >
  165. void clone_back_insert( ForwardIterator first,
  166. ForwardIterator last )
  167. {
  168. BOOST_ASSERT( first != last );
  169. scoped_deleter sd( *this, first, last );
  170. insert_clones_and_release( sd, end() );
  171. }
  172. void remove_all()
  173. {
  174. this->remove( begin(), end() );
  175. }
  176. protected:
  177. void insert_clones_and_release( scoped_deleter& sd,
  178. iterator where ) // strong
  179. {
  180. //
  181. // 'c_.insert' always provides the strong guarantee for T* elements
  182. // since a copy constructor of a pointer cannot throw
  183. //
  184. c_.insert( where.base(),
  185. sd.begin(), sd.end() );
  186. sd.release();
  187. }
  188. void insert_clones_and_release( scoped_deleter& sd ) // strong
  189. {
  190. c_.insert( sd.begin(), sd.end() );
  191. sd.release();
  192. }
  193. template< class U >
  194. void remove( U* ptr )
  195. {
  196. this->deallocate_clone( ptr );
  197. }
  198. template< class I >
  199. void remove( I i )
  200. {
  201. this->deallocate_clone( Config::get_const_pointer(i) );
  202. }
  203. template< class I >
  204. void remove( I first, I last )
  205. {
  206. for( ; first != last; ++first )
  207. this->remove( first );
  208. }
  209. static void enforce_null_policy( const Ty_* x, const char* msg )
  210. {
  211. if( !allow_null )
  212. {
  213. BOOST_PTR_CONTAINER_THROW_EXCEPTION( 0 == x && "null not allowed",
  214. bad_pointer, msg );
  215. }
  216. }
  217. public:
  218. Ty_* null_policy_allocate_clone( const Ty_* x )
  219. {
  220. if( allow_null )
  221. {
  222. if( x == 0 )
  223. return 0;
  224. }
  225. else
  226. {
  227. BOOST_ASSERT( x != 0 && "Cannot insert clone of null!" );
  228. }
  229. Ty_* res = this->get_clone_allocator().allocate_clone( *x );
  230. BOOST_ASSERT( typeid(*res) == typeid(*x) &&
  231. "CloneAllocator::allocate_clone() does not clone the "
  232. "object properly. Check that new_clone() is implemented"
  233. " correctly" );
  234. return res;
  235. }
  236. template< class Iterator >
  237. Ty_* null_policy_allocate_clone_from_iterator( Iterator i )
  238. {
  239. return this->null_policy_allocate_clone(Config::get_const_pointer(i));
  240. }
  241. void null_policy_deallocate_clone( const Ty_* x )
  242. {
  243. if( allow_null )
  244. {
  245. if( x == 0 )
  246. return;
  247. }
  248. this->get_clone_allocator().deallocate_clone( x );
  249. }
  250. private:
  251. template< class ForwardIterator >
  252. ForwardIterator advance( ForwardIterator begin, size_type n )
  253. {
  254. ForwardIterator iter = begin;
  255. std::advance( iter, n );
  256. return iter;
  257. }
  258. template< class I >
  259. void constructor_impl( I first, I last, std::input_iterator_tag ) // basic
  260. {
  261. while( first != last )
  262. {
  263. insert( end(), this->allocate_clone_from_iterator(first) );
  264. ++first;
  265. }
  266. }
  267. template< class I >
  268. void constructor_impl( I first, I last, std::forward_iterator_tag ) // strong
  269. {
  270. if( first == last )
  271. return;
  272. clone_back_insert( first, last );
  273. }
  274. template< class I >
  275. void associative_constructor_impl( I first, I last ) // strong
  276. {
  277. if( first == last )
  278. return;
  279. scoped_deleter sd( *this, first, last );
  280. insert_clones_and_release( sd );
  281. }
  282. public: // foundation: should be protected, but public for poor compilers' sake.
  283. reversible_ptr_container()
  284. { }
  285. template< class SizeType >
  286. reversible_ptr_container( SizeType n, unordered_associative_container_tag )
  287. : c_( n )
  288. { }
  289. template< class SizeType >
  290. reversible_ptr_container( SizeType n, fixed_length_sequence_tag )
  291. : c_( n )
  292. { }
  293. template< class SizeType >
  294. reversible_ptr_container( SizeType n, const allocator_type& a,
  295. fixed_length_sequence_tag )
  296. : c_( n, a )
  297. { }
  298. explicit reversible_ptr_container( const allocator_type& a )
  299. : c_( a )
  300. { }
  301. #ifndef BOOST_NO_AUTO_PTR
  302. template< class PtrContainer >
  303. explicit reversible_ptr_container( std::auto_ptr<PtrContainer> clone )
  304. {
  305. swap( *clone );
  306. }
  307. #endif
  308. #ifndef BOOST_NO_CXX11_SMART_PTR
  309. template< class PtrContainer >
  310. explicit reversible_ptr_container( std::unique_ptr<PtrContainer> clone )
  311. {
  312. swap( *clone );
  313. }
  314. #endif
  315. reversible_ptr_container( const reversible_ptr_container& r )
  316. {
  317. constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() );
  318. }
  319. template< class C, class V >
  320. reversible_ptr_container( const reversible_ptr_container<C,V>& r )
  321. {
  322. constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() );
  323. }
  324. #ifndef BOOST_NO_AUTO_PTR
  325. template< class PtrContainer >
  326. reversible_ptr_container& operator=( std::auto_ptr<PtrContainer> clone ) // nothrow
  327. {
  328. swap( *clone );
  329. return *this;
  330. }
  331. #endif
  332. #ifndef BOOST_NO_CXX11_SMART_PTR
  333. template< class PtrContainer >
  334. reversible_ptr_container& operator=( std::unique_ptr<PtrContainer> clone ) // nothrow
  335. {
  336. swap( *clone );
  337. return *this;
  338. }
  339. #endif
  340. reversible_ptr_container& operator=( reversible_ptr_container r ) // strong
  341. {
  342. swap( r );
  343. return *this;
  344. }
  345. // overhead: null-initilization of container pointer (very cheap compared to cloning)
  346. // overhead: 1 heap allocation (very cheap compared to cloning)
  347. template< class InputIterator >
  348. reversible_ptr_container( InputIterator first,
  349. InputIterator last,
  350. const allocator_type& a = allocator_type() ) // basic, strong
  351. : c_( a )
  352. {
  353. constructor_impl( first, last,
  354. #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
  355. #else
  356. BOOST_DEDUCED_TYPENAME
  357. #endif
  358. iterator_category<InputIterator>::type() );
  359. }
  360. template< class Compare >
  361. reversible_ptr_container( const Compare& comp,
  362. const allocator_type& a )
  363. : c_( comp, a ) {}
  364. template< class ForwardIterator >
  365. reversible_ptr_container( ForwardIterator first,
  366. ForwardIterator last,
  367. fixed_length_sequence_tag )
  368. : c_( std::distance(first,last) )
  369. {
  370. constructor_impl( first, last,
  371. std::forward_iterator_tag() );
  372. }
  373. template< class SizeType, class InputIterator >
  374. reversible_ptr_container( SizeType n,
  375. InputIterator first,
  376. InputIterator last,
  377. fixed_length_sequence_tag )
  378. : c_( n )
  379. {
  380. constructor_impl( first, last,
  381. #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
  382. #else
  383. BOOST_DEDUCED_TYPENAME
  384. #endif
  385. iterator_category<InputIterator>::type() );
  386. }
  387. template< class Compare >
  388. reversible_ptr_container( const Compare& comp,
  389. const allocator_type& a,
  390. associative_container_tag )
  391. : c_( comp, a )
  392. { }
  393. template< class InputIterator >
  394. reversible_ptr_container( InputIterator first,
  395. InputIterator last,
  396. associative_container_tag )
  397. {
  398. associative_constructor_impl( first, last );
  399. }
  400. template< class InputIterator, class Compare >
  401. reversible_ptr_container( InputIterator first,
  402. InputIterator last,
  403. const Compare& comp,
  404. const allocator_type& a,
  405. associative_container_tag )
  406. : c_( comp, a )
  407. {
  408. associative_constructor_impl( first, last );
  409. }
  410. explicit reversible_ptr_container( size_type n )
  411. : c_( n ) {}
  412. template< class Hash, class Pred >
  413. reversible_ptr_container( const Hash& h,
  414. const Pred& pred,
  415. const allocator_type& a )
  416. : c_( h, pred, a ) {}
  417. template< class InputIterator, class Hash, class Pred >
  418. reversible_ptr_container( InputIterator first,
  419. InputIterator last,
  420. const Hash& h,
  421. const Pred& pred,
  422. const allocator_type& a )
  423. : c_( h, pred, a )
  424. {
  425. associative_constructor_impl( first, last );
  426. }
  427. public:
  428. ~reversible_ptr_container()
  429. {
  430. remove_all();
  431. }
  432. public:
  433. allocator_type get_allocator() const
  434. {
  435. return c_.get_allocator();
  436. }
  437. clone_allocator_type& get_clone_allocator()
  438. {
  439. return static_cast<clone_allocator_type&>(*this);
  440. }
  441. const clone_allocator_type& get_clone_allocator() const
  442. {
  443. return static_cast<const clone_allocator_type&>(*this);
  444. }
  445. public: // container requirements
  446. iterator begin()
  447. { return iterator( c_.begin() ); }
  448. const_iterator begin() const
  449. { return const_iterator( c_.begin() ); }
  450. iterator end()
  451. { return iterator( c_.end() ); }
  452. const_iterator end() const
  453. { return const_iterator( c_.end() ); }
  454. reverse_iterator rbegin()
  455. { return reverse_iterator( this->end() ); }
  456. const_reverse_iterator rbegin() const
  457. { return const_reverse_iterator( this->end() ); }
  458. reverse_iterator rend()
  459. { return reverse_iterator( this->begin() ); }
  460. const_reverse_iterator rend() const
  461. { return const_reverse_iterator( this->begin() ); }
  462. const_iterator cbegin() const
  463. { return const_iterator( c_.begin() ); }
  464. const_iterator cend() const
  465. { return const_iterator( c_.end() ); }
  466. const_reverse_iterator crbegin() const
  467. { return const_reverse_iterator( this->end() ); }
  468. const_reverse_iterator crend() const
  469. { return const_reverse_iterator( this->begin() ); }
  470. void swap( reversible_ptr_container& r ) // nothrow
  471. {
  472. boost::core::invoke_swap( get_clone_allocator(), r.get_clone_allocator() ); // nothrow
  473. c_.swap( r.c_ ); // nothrow
  474. }
  475. size_type size() const // nothrow
  476. {
  477. return c_.size();
  478. }
  479. size_type max_size() const // nothrow
  480. {
  481. return c_.max_size();
  482. }
  483. bool empty() const // nothrow
  484. {
  485. return c_.empty();
  486. }
  487. public: // optional container requirements
  488. bool operator==( const reversible_ptr_container& r ) const // nothrow
  489. {
  490. if( size() != r.size() )
  491. return false;
  492. else
  493. return std::equal( begin(), end(), r.begin() );
  494. }
  495. bool operator!=( const reversible_ptr_container& r ) const // nothrow
  496. {
  497. return !(*this == r);
  498. }
  499. bool operator<( const reversible_ptr_container& r ) const // nothrow
  500. {
  501. return std::lexicographical_compare( begin(), end(), r.begin(), r.end() );
  502. }
  503. bool operator<=( const reversible_ptr_container& r ) const // nothrow
  504. {
  505. return !(r < *this);
  506. }
  507. bool operator>( const reversible_ptr_container& r ) const // nothrow
  508. {
  509. return r < *this;
  510. }
  511. bool operator>=( const reversible_ptr_container& r ) const // nothrow
  512. {
  513. return !(*this < r);
  514. }
  515. public: // modifiers
  516. iterator insert( iterator before, Ty_* x )
  517. {
  518. enforce_null_policy( x, "Null pointer in 'insert()'" );
  519. auto_type ptr( x, *this ); // nothrow
  520. iterator res( c_.insert( before.base(), x ) ); // strong, commit
  521. ptr.release(); // nothrow
  522. return res;
  523. }
  524. #ifndef BOOST_NO_AUTO_PTR
  525. template< class U >
  526. iterator insert( iterator before, std::auto_ptr<U> x )
  527. {
  528. return insert( before, x.release() );
  529. }
  530. #endif
  531. #ifndef BOOST_NO_CXX11_SMART_PTR
  532. template< class U >
  533. iterator insert( iterator before, std::unique_ptr<U> x )
  534. {
  535. return insert( before, x.release() );
  536. }
  537. #endif
  538. iterator erase( iterator x ) // nothrow
  539. {
  540. BOOST_ASSERT( !empty() );
  541. BOOST_ASSERT( x != end() );
  542. remove( x );
  543. return iterator( c_.erase( x.base() ) );
  544. }
  545. iterator erase( iterator first, iterator last ) // nothrow
  546. {
  547. remove( first, last );
  548. return iterator( c_.erase( first.base(),
  549. last.base() ) );
  550. }
  551. template< class Range >
  552. iterator erase( const Range& r )
  553. {
  554. return erase( boost::begin(r), boost::end(r) );
  555. }
  556. void clear()
  557. {
  558. remove_all();
  559. c_.clear();
  560. }
  561. public: // access interface
  562. auto_type release( iterator where )
  563. {
  564. BOOST_ASSERT( where != end() );
  565. BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
  566. "'release()' on empty container" );
  567. auto_type ptr( Config::get_pointer(where), *this ); // nothrow
  568. c_.erase( where.base() ); // nothrow
  569. return boost::ptr_container_detail::move( ptr );
  570. }
  571. auto_type replace( iterator where, Ty_* x ) // strong
  572. {
  573. BOOST_ASSERT( where != end() );
  574. enforce_null_policy( x, "Null pointer in 'replace()'" );
  575. auto_type ptr( x, *this );
  576. BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
  577. "'replace()' on empty container" );
  578. auto_type old( Config::get_pointer(where), *this ); // nothrow
  579. const_cast<void*&>(*where.base()) = ptr.release();
  580. return boost::ptr_container_detail::move( old );
  581. }
  582. #ifndef BOOST_NO_AUTO_PTR
  583. template< class U >
  584. auto_type replace( iterator where, std::auto_ptr<U> x )
  585. {
  586. return replace( where, x.release() );
  587. }
  588. #endif
  589. #ifndef BOOST_NO_CXX11_SMART_PTR
  590. template< class U >
  591. auto_type replace( iterator where, std::unique_ptr<U> x )
  592. {
  593. return replace( where, x.release() );
  594. }
  595. #endif
  596. auto_type replace( size_type idx, Ty_* x ) // strong
  597. {
  598. enforce_null_policy( x, "Null pointer in 'replace()'" );
  599. auto_type ptr( x, *this );
  600. BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= size(), bad_index,
  601. "'replace()' out of bounds" );
  602. auto_type old( static_cast<Ty_*>(c_[idx]), *this ); // nothrow
  603. c_[idx] = ptr.release(); // nothrow, commit
  604. return boost::ptr_container_detail::move( old );
  605. }
  606. #ifndef BOOST_NO_AUTO_PTR
  607. template< class U >
  608. auto_type replace( size_type idx, std::auto_ptr<U> x )
  609. {
  610. return replace( idx, x.release() );
  611. }
  612. #endif
  613. #ifndef BOOST_NO_CXX11_SMART_PTR
  614. template< class U >
  615. auto_type replace( size_type idx, std::unique_ptr<U> x )
  616. {
  617. return replace( idx, x.release() );
  618. }
  619. #endif
  620. }; // 'reversible_ptr_container'
  621. #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
  622. #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
  623. typename base_type::auto_type \
  624. release( typename base_type::iterator i ) \
  625. { \
  626. return boost::ptr_container_detail::move(base_type::release(i)); \
  627. }
  628. #else
  629. #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
  630. using base_type::release;
  631. #endif
  632. #ifndef BOOST_NO_AUTO_PTR
  633. #define BOOST_PTR_CONTAINER_COPY_AND_ASSIGN_AUTO( PC, base_type, this_type ) \
  634. explicit PC( std::auto_ptr<this_type> r ) \
  635. : base_type ( r ) { } \
  636. \
  637. PC& operator=( std::auto_ptr<this_type> r ) \
  638. { \
  639. base_type::operator=( r ); \
  640. return *this; \
  641. }
  642. #else
  643. #define BOOST_PTR_CONTAINER_COPY_AND_ASSIGN_AUTO( PC, base_type, this_type )
  644. #endif
  645. #ifndef BOOST_NO_CXX11_SMART_PTR
  646. #define BOOST_PTR_CONTAINER_COPY_AND_ASSIGN_UNIQUE( PC, base_type, this_type ) \
  647. explicit PC( std::unique_ptr<this_type> r ) \
  648. : base_type ( std::move( r ) ) { } \
  649. \
  650. PC& operator=( std::unique_ptr<this_type> r ) \
  651. { \
  652. base_type::operator=( std::move( r ) ); \
  653. return *this; \
  654. }
  655. #else
  656. #define BOOST_PTR_CONTAINER_COPY_AND_ASSIGN_UNIQUE( PC, base_type, this_type )
  657. #endif
  658. #ifndef BOOST_NO_AUTO_PTR
  659. #define BOOST_PTR_CONTAINER_RELEASE_AND_CLONE( this_type ) \
  660. std::auto_ptr<this_type> release() \
  661. { \
  662. std::auto_ptr<this_type> ptr( new this_type );\
  663. this->swap( *ptr ); \
  664. return ptr; \
  665. } \
  666. \
  667. std::auto_ptr<this_type> clone() const \
  668. { \
  669. return std::auto_ptr<this_type>( new this_type( this->begin(), this->end() ) ); \
  670. }
  671. #elif !defined( BOOST_NO_CXX11_SMART_PTR )
  672. #define BOOST_PTR_CONTAINER_RELEASE_AND_CLONE( this_type ) \
  673. std::unique_ptr<this_type> release() \
  674. { \
  675. std::unique_ptr<this_type> ptr( new this_type );\
  676. this->swap( *ptr ); \
  677. return ptr; \
  678. } \
  679. \
  680. std::unique_ptr<this_type> clone() const \
  681. { \
  682. return std::unique_ptr<this_type>( new this_type( this->begin(), this->end() ) ); \
  683. }
  684. #else
  685. #define BOOST_PTR_CONTAINER_RELEASE_AND_CLONE( this_type )
  686. #endif
  687. //
  688. // two-phase lookup of template functions
  689. // is buggy on most compilers, so we use a macro instead
  690. //
  691. #define BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type ) \
  692. BOOST_PTR_CONTAINER_COPY_AND_ASSIGN_AUTO( PC, base_type, this_type ) \
  693. BOOST_PTR_CONTAINER_COPY_AND_ASSIGN_UNIQUE( PC, base_type, this_type ) \
  694. BOOST_PTR_CONTAINER_RELEASE_AND_CLONE( this_type ) \
  695. BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type )
  696. #define BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type ) \
  697. \
  698. template< class U > \
  699. PC( const PC<U>& r ) : base_type( r ) { } \
  700. \
  701. PC& operator=( PC r ) \
  702. { \
  703. this->swap( r ); \
  704. return *this; \
  705. } \
  706. #define BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \
  707. typedef BOOST_DEDUCED_TYPENAME base_type::iterator iterator; \
  708. typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type; \
  709. typedef BOOST_DEDUCED_TYPENAME base_type::const_reference const_reference; \
  710. typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type allocator_type; \
  711. PC() {} \
  712. explicit PC( const allocator_type& a ) : base_type(a) {} \
  713. template< class InputIterator > \
  714. PC( InputIterator first, InputIterator last ) : base_type( first, last ) {} \
  715. template< class InputIterator > \
  716. PC( InputIterator first, InputIterator last, \
  717. const allocator_type& a ) : base_type( first, last, a ) {}
  718. #define BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type ) \
  719. BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \
  720. BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type )
  721. #define BOOST_PTR_CONTAINER_DEFINE_SEQEUENCE_MEMBERS( PC, base_type, this_type ) \
  722. BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type ) \
  723. BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type )
  724. } // namespace 'ptr_container_detail'
  725. //
  726. // @remark: expose movability of internal move-pointer
  727. //
  728. namespace ptr_container
  729. {
  730. using ptr_container_detail::move;
  731. }
  732. } // namespace 'boost'
  733. #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
  734. #pragma GCC diagnostic pop
  735. #endif
  736. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  737. #pragma warning(pop)
  738. #endif
  739. #endif