reversible_ptr_container.hpp 26 KB

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