ptr_set_adapter.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  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_PTR_SET_ADAPTER_HPP
  12. #define BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif
  16. #include <boost/ptr_container/detail/associative_ptr_container.hpp>
  17. #include <boost/ptr_container/detail/meta_functions.hpp>
  18. #include <boost/ptr_container/detail/void_ptr_iterator.hpp>
  19. #include <boost/range/iterator_range.hpp>
  20. namespace boost
  21. {
  22. namespace ptr_container_detail
  23. {
  24. template
  25. <
  26. class Key,
  27. class VoidPtrSet,
  28. bool Ordered
  29. >
  30. struct set_config
  31. {
  32. typedef VoidPtrSet
  33. void_container_type;
  34. typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type
  35. allocator_type;
  36. typedef Key value_type;
  37. typedef value_type
  38. key_type;
  39. typedef BOOST_DEDUCED_TYPENAME
  40. mpl::eval_if_c<Ordered,
  41. select_value_compare<VoidPtrSet>,
  42. mpl::identity<void> >::type
  43. value_compare;
  44. typedef value_compare
  45. key_compare;
  46. typedef BOOST_DEDUCED_TYPENAME
  47. mpl::eval_if_c<Ordered,
  48. mpl::identity<void>,
  49. select_hasher<VoidPtrSet> >::type
  50. hasher;
  51. typedef BOOST_DEDUCED_TYPENAME
  52. mpl::eval_if_c<Ordered,
  53. mpl::identity<void>,
  54. select_key_equal<VoidPtrSet> >::type
  55. key_equal;
  56. typedef BOOST_DEDUCED_TYPENAME
  57. mpl::if_c<Ordered,
  58. ordered_associative_container_tag,
  59. unordered_associative_container_tag>::type
  60. container_type;
  61. typedef void_ptr_iterator<
  62. BOOST_DEDUCED_TYPENAME VoidPtrSet::iterator, Key >
  63. iterator;
  64. typedef void_ptr_iterator<
  65. BOOST_DEDUCED_TYPENAME VoidPtrSet::const_iterator, const Key >
  66. const_iterator;
  67. typedef void_ptr_iterator<
  68. BOOST_DEDUCED_TYPENAME
  69. mpl::eval_if_c<Ordered,
  70. select_iterator<VoidPtrSet>,
  71. select_local_iterator<VoidPtrSet> >::type,
  72. Key >
  73. local_iterator;
  74. typedef void_ptr_iterator<
  75. BOOST_DEDUCED_TYPENAME
  76. mpl::eval_if_c<Ordered,
  77. select_iterator<VoidPtrSet>,
  78. select_const_local_iterator<VoidPtrSet> >::type,
  79. const Key >
  80. const_local_iterator;
  81. template< class Iter >
  82. static Key* get_pointer( Iter i )
  83. {
  84. return static_cast<Key*>( *i.base() );
  85. }
  86. template< class Iter >
  87. static const Key* get_const_pointer( Iter i )
  88. {
  89. return static_cast<const Key*>( *i.base() );
  90. }
  91. BOOST_STATIC_CONSTANT(bool, allow_null = false );
  92. };
  93. template
  94. <
  95. class Key,
  96. class VoidPtrSet,
  97. class CloneAllocator = heap_clone_allocator,
  98. bool Ordered = true
  99. >
  100. class ptr_set_adapter_base
  101. : public ptr_container_detail::associative_ptr_container< set_config<Key,VoidPtrSet,Ordered>,
  102. CloneAllocator >
  103. {
  104. typedef ptr_container_detail::associative_ptr_container< set_config<Key,VoidPtrSet,Ordered>,
  105. CloneAllocator >
  106. base_type;
  107. public:
  108. typedef BOOST_DEDUCED_TYPENAME base_type::iterator
  109. iterator;
  110. typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
  111. const_iterator;
  112. typedef Key key_type;
  113. typedef BOOST_DEDUCED_TYPENAME base_type::size_type
  114. size_type;
  115. public:
  116. ptr_set_adapter_base()
  117. { }
  118. template< class SizeType >
  119. ptr_set_adapter_base( SizeType n,
  120. ptr_container_detail::unordered_associative_container_tag tag )
  121. : base_type( n, tag )
  122. { }
  123. template< class Compare, class Allocator >
  124. ptr_set_adapter_base( const Compare& comp,
  125. const Allocator& a )
  126. : base_type( comp, a )
  127. { }
  128. template< class Hash, class Pred, class Allocator >
  129. ptr_set_adapter_base( const Hash& hash,
  130. const Pred& pred,
  131. const Allocator& a )
  132. : base_type( hash, pred, a )
  133. { }
  134. template< class InputIterator, class Compare, class Allocator >
  135. ptr_set_adapter_base( InputIterator first, InputIterator last,
  136. const Compare& comp,
  137. const Allocator& a )
  138. : base_type( first, last, comp, a )
  139. { }
  140. template< class InputIterator, class Hash, class Pred, class Allocator >
  141. ptr_set_adapter_base( InputIterator first, InputIterator last,
  142. const Hash& hash,
  143. const Pred& pred,
  144. const Allocator& a )
  145. : base_type( first, last, hash, pred, a )
  146. { }
  147. template< class U, class Set, class CA, bool b >
  148. ptr_set_adapter_base( const ptr_set_adapter_base<U,Set,CA,b>& r )
  149. : base_type( r )
  150. { }
  151. ptr_set_adapter_base( const ptr_set_adapter_base& r )
  152. : base_type( r )
  153. { }
  154. template< class PtrContainer >
  155. explicit ptr_set_adapter_base( std::auto_ptr<PtrContainer> clone )
  156. : base_type( clone )
  157. { }
  158. ptr_set_adapter_base& operator=( ptr_set_adapter_base r )
  159. {
  160. this->swap( r );
  161. return *this;
  162. }
  163. template< typename PtrContainer >
  164. ptr_set_adapter_base& operator=( std::auto_ptr<PtrContainer> clone )
  165. {
  166. base_type::operator=( clone );
  167. return *this;
  168. }
  169. using base_type::erase;
  170. size_type erase( const key_type& x ) // nothrow
  171. {
  172. key_type* key = const_cast<key_type*>(&x);
  173. iterator i( this->base().find( key ) );
  174. if( i == this->end() ) // nothrow
  175. return 0u; // nothrow
  176. key = static_cast<key_type*>(*i.base()); // nothrow
  177. size_type res = this->base().erase( key ); // nothrow
  178. this->remove( key ); // nothrow
  179. return res;
  180. }
  181. iterator find( const key_type& x )
  182. {
  183. return iterator( this->base().
  184. find( const_cast<key_type*>(&x) ) );
  185. }
  186. const_iterator find( const key_type& x ) const
  187. {
  188. return const_iterator( this->base().
  189. find( const_cast<key_type*>(&x) ) );
  190. }
  191. size_type count( const key_type& x ) const
  192. {
  193. return this->base().count( const_cast<key_type*>(&x) );
  194. }
  195. iterator lower_bound( const key_type& x )
  196. {
  197. return iterator( this->base().
  198. lower_bound( const_cast<key_type*>(&x) ) );
  199. }
  200. const_iterator lower_bound( const key_type& x ) const
  201. {
  202. return const_iterator( this->base().
  203. lower_bound( const_cast<key_type*>(&x) ) );
  204. }
  205. iterator upper_bound( const key_type& x )
  206. {
  207. return iterator( this->base().
  208. upper_bound( const_cast<key_type*>(&x) ) );
  209. }
  210. const_iterator upper_bound( const key_type& x ) const
  211. {
  212. return const_iterator( this->base().
  213. upper_bound( const_cast<key_type*>(&x) ) );
  214. }
  215. iterator_range<iterator> equal_range( const key_type& x )
  216. {
  217. std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,
  218. BOOST_DEDUCED_TYPENAME base_type::ptr_iterator>
  219. p = this->base().
  220. equal_range( const_cast<key_type*>(&x) );
  221. return make_iterator_range( iterator( p.first ),
  222. iterator( p.second ) );
  223. }
  224. iterator_range<const_iterator> equal_range( const key_type& x ) const
  225. {
  226. std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator,
  227. BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator>
  228. p = this->base().
  229. equal_range( const_cast<key_type*>(&x) );
  230. return make_iterator_range( const_iterator( p.first ),
  231. const_iterator( p.second ) );
  232. }
  233. protected:
  234. size_type bucket( const key_type& key ) const
  235. {
  236. return this->base().bucket( const_cast<key_type*>(&key) );
  237. }
  238. };
  239. } // ptr_container_detail
  240. /////////////////////////////////////////////////////////////////////////
  241. // ptr_set_adapter
  242. /////////////////////////////////////////////////////////////////////////
  243. template
  244. <
  245. class Key,
  246. class VoidPtrSet,
  247. class CloneAllocator = heap_clone_allocator,
  248. bool Ordered = true
  249. >
  250. class ptr_set_adapter :
  251. public ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrSet,CloneAllocator,Ordered>
  252. {
  253. typedef ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrSet,CloneAllocator,Ordered>
  254. base_type;
  255. public: // typedefs
  256. typedef BOOST_DEDUCED_TYPENAME base_type::iterator
  257. iterator;
  258. typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
  259. const_iterator;
  260. typedef BOOST_DEDUCED_TYPENAME base_type::size_type
  261. size_type;
  262. typedef Key key_type;
  263. typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
  264. auto_type;
  265. typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type
  266. allocator_type;
  267. private:
  268. template< typename II >
  269. void set_basic_clone_and_insert( II first, II last ) // basic
  270. {
  271. while( first != last )
  272. {
  273. if( this->find( *first ) == this->end() )
  274. insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit
  275. ++first;
  276. }
  277. }
  278. public:
  279. ptr_set_adapter()
  280. { }
  281. template< class SizeType >
  282. ptr_set_adapter( SizeType n,
  283. ptr_container_detail::unordered_associative_container_tag tag )
  284. : base_type( n, tag )
  285. { }
  286. template< class Comp >
  287. explicit ptr_set_adapter( const Comp& comp,
  288. const allocator_type& a )
  289. : base_type( comp, a )
  290. {
  291. BOOST_ASSERT( this->empty() );
  292. }
  293. template< class Hash, class Pred, class Allocator >
  294. ptr_set_adapter( const Hash& hash,
  295. const Pred& pred,
  296. const Allocator& a )
  297. : base_type( hash, pred, a )
  298. { }
  299. template< class InputIterator >
  300. ptr_set_adapter( InputIterator first, InputIterator last )
  301. : base_type( first, last )
  302. { }
  303. template< class InputIterator, class Compare, class Allocator >
  304. ptr_set_adapter( InputIterator first, InputIterator last,
  305. const Compare& comp,
  306. const Allocator a = Allocator() )
  307. : base_type( comp, a )
  308. {
  309. BOOST_ASSERT( this->empty() );
  310. set_basic_clone_and_insert( first, last );
  311. }
  312. template< class InputIterator, class Hash, class Pred, class Allocator >
  313. ptr_set_adapter( InputIterator first, InputIterator last,
  314. const Hash& hash,
  315. const Pred& pred,
  316. const Allocator& a )
  317. : base_type( first, last, hash, pred, a )
  318. { }
  319. explicit ptr_set_adapter( const ptr_set_adapter& r )
  320. : base_type( r )
  321. { }
  322. template< class U, class Set, class CA, bool b >
  323. explicit ptr_set_adapter( const ptr_set_adapter<U,Set,CA,b>& r )
  324. : base_type( r )
  325. { }
  326. template< class PtrContainer >
  327. explicit ptr_set_adapter( std::auto_ptr<PtrContainer> clone )
  328. : base_type( clone )
  329. { }
  330. template< class U, class Set, class CA, bool b >
  331. ptr_set_adapter& operator=( const ptr_set_adapter<U,Set,CA,b>& r )
  332. {
  333. base_type::operator=( r );
  334. return *this;
  335. }
  336. template< class T >
  337. void operator=( std::auto_ptr<T> r )
  338. {
  339. base_type::operator=( r );
  340. }
  341. std::pair<iterator,bool> insert( key_type* x ) // strong
  342. {
  343. this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" );
  344. auto_type ptr( x );
  345. std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
  346. res = this->base().insert( x );
  347. if( res.second )
  348. ptr.release();
  349. return std::make_pair( iterator( res.first ), res.second );
  350. }
  351. template< class U >
  352. std::pair<iterator,bool> insert( std::auto_ptr<U> x )
  353. {
  354. return insert( x.release() );
  355. }
  356. iterator insert( iterator where, key_type* x ) // strong
  357. {
  358. this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" );
  359. auto_type ptr( x );
  360. BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
  361. res = this->base().insert( where.base(), x );
  362. if( *res == x )
  363. ptr.release();
  364. return iterator( res);
  365. }
  366. template< class U >
  367. iterator insert( iterator where, std::auto_ptr<U> x )
  368. {
  369. return insert( where, x.release() );
  370. }
  371. template< typename InputIterator >
  372. void insert( InputIterator first, InputIterator last ) // basic
  373. {
  374. set_basic_clone_and_insert( first, last );
  375. }
  376. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  377. #else
  378. template< class Range >
  379. BOOST_DEDUCED_TYPENAME
  380. boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
  381. insert( const Range& r )
  382. {
  383. insert( boost::begin(r), boost::end(r) );
  384. }
  385. #endif
  386. template< class PtrSetAdapter >
  387. bool transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object,
  388. PtrSetAdapter& from ) // strong
  389. {
  390. return this->single_transfer( object, from );
  391. }
  392. template< class PtrSetAdapter >
  393. size_type
  394. transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first,
  395. BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last,
  396. PtrSetAdapter& from ) // basic
  397. {
  398. return this->single_transfer( first, last, from );
  399. }
  400. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  401. #else
  402. template< class PtrSetAdapter, class Range >
  403. BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
  404. BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >,
  405. size_type >::type
  406. transfer( const Range& r, PtrSetAdapter& from ) // basic
  407. {
  408. return transfer( boost::begin(r), boost::end(r), from );
  409. }
  410. #endif
  411. template< class PtrSetAdapter >
  412. size_type transfer( PtrSetAdapter& from ) // basic
  413. {
  414. return transfer( from.begin(), from.end(), from );
  415. }
  416. };
  417. /////////////////////////////////////////////////////////////////////////
  418. // ptr_multiset_adapter
  419. /////////////////////////////////////////////////////////////////////////
  420. template
  421. <
  422. class Key,
  423. class VoidPtrMultiSet,
  424. class CloneAllocator = heap_clone_allocator,
  425. bool Ordered = true
  426. >
  427. class ptr_multiset_adapter :
  428. public ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrMultiSet,CloneAllocator,Ordered>
  429. {
  430. typedef ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrMultiSet,CloneAllocator,Ordered> base_type;
  431. public: // typedefs
  432. typedef BOOST_DEDUCED_TYPENAME base_type::iterator
  433. iterator;
  434. typedef BOOST_DEDUCED_TYPENAME base_type::size_type
  435. size_type;
  436. typedef Key key_type;
  437. typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
  438. auto_type;
  439. typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiSet::allocator_type
  440. allocator_type;
  441. private:
  442. template< typename II >
  443. void set_basic_clone_and_insert( II first, II last ) // basic
  444. {
  445. while( first != last )
  446. {
  447. insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit
  448. ++first;
  449. }
  450. }
  451. public:
  452. ptr_multiset_adapter()
  453. { }
  454. template< class SizeType >
  455. ptr_multiset_adapter( SizeType n,
  456. ptr_container_detail::unordered_associative_container_tag tag )
  457. : base_type( n, tag )
  458. { }
  459. template< class Comp >
  460. explicit ptr_multiset_adapter( const Comp& comp,
  461. const allocator_type& a )
  462. : base_type( comp, a )
  463. { }
  464. template< class Hash, class Pred, class Allocator >
  465. ptr_multiset_adapter( const Hash& hash,
  466. const Pred& pred,
  467. const Allocator& a )
  468. : base_type( hash, pred, a )
  469. { }
  470. template< class InputIterator >
  471. ptr_multiset_adapter( InputIterator first, InputIterator last )
  472. : base_type( first, last )
  473. { }
  474. template< class InputIterator, class Comp >
  475. ptr_multiset_adapter( InputIterator first, InputIterator last,
  476. const Comp& comp,
  477. const allocator_type& a = allocator_type() )
  478. : base_type( comp, a )
  479. {
  480. set_basic_clone_and_insert( first, last );
  481. }
  482. template< class InputIterator, class Hash, class Pred, class Allocator >
  483. ptr_multiset_adapter( InputIterator first, InputIterator last,
  484. const Hash& hash,
  485. const Pred& pred,
  486. const Allocator& a )
  487. : base_type( first, last, hash, pred, a )
  488. { }
  489. template< class U, class Set, class CA, bool b >
  490. explicit ptr_multiset_adapter( const ptr_multiset_adapter<U,Set,CA,b>& r )
  491. : base_type( r )
  492. { }
  493. template< class PtrContainer >
  494. explicit ptr_multiset_adapter( std::auto_ptr<PtrContainer> clone )
  495. : base_type( clone )
  496. { }
  497. template< class U, class Set, class CA, bool b >
  498. ptr_multiset_adapter& operator=( const ptr_multiset_adapter<U,Set,CA,b>& r )
  499. {
  500. base_type::operator=( r );
  501. return *this;
  502. }
  503. template< class T >
  504. void operator=( std::auto_ptr<T> r )
  505. {
  506. base_type::operator=( r );
  507. }
  508. iterator insert( iterator before, key_type* x ) // strong
  509. {
  510. return base_type::insert( before, x );
  511. }
  512. template< class U >
  513. iterator insert( iterator before, std::auto_ptr<U> x )
  514. {
  515. return insert( before, x.release() );
  516. }
  517. iterator insert( key_type* x ) // strong
  518. {
  519. this->enforce_null_policy( x, "Null pointer in 'ptr_multiset::insert()'" );
  520. auto_type ptr( x );
  521. BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
  522. res = this->base().insert( x );
  523. ptr.release();
  524. return iterator( res );
  525. }
  526. template< class U >
  527. iterator insert( std::auto_ptr<U> x )
  528. {
  529. return insert( x.release() );
  530. }
  531. template< typename InputIterator >
  532. void insert( InputIterator first, InputIterator last ) // basic
  533. {
  534. set_basic_clone_and_insert( first, last );
  535. }
  536. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  537. #else
  538. template< class Range >
  539. BOOST_DEDUCED_TYPENAME
  540. boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
  541. insert( const Range& r )
  542. {
  543. insert( boost::begin(r), boost::end(r) );
  544. }
  545. #endif
  546. template< class PtrSetAdapter >
  547. void transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object,
  548. PtrSetAdapter& from ) // strong
  549. {
  550. this->multi_transfer( object, from );
  551. }
  552. template< class PtrSetAdapter >
  553. size_type transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first,
  554. BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last,
  555. PtrSetAdapter& from ) // basic
  556. {
  557. return this->multi_transfer( first, last, from );
  558. }
  559. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  560. #else
  561. template< class PtrSetAdapter, class Range >
  562. BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
  563. BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >, size_type >::type
  564. transfer( const Range& r, PtrSetAdapter& from ) // basic
  565. {
  566. return transfer( boost::begin(r), boost::end(r), from );
  567. }
  568. #endif
  569. template< class PtrSetAdapter >
  570. void transfer( PtrSetAdapter& from ) // basic
  571. {
  572. transfer( from.begin(), from.end(), from );
  573. BOOST_ASSERT( from.empty() );
  574. }
  575. };
  576. } // namespace 'boost'
  577. #endif