associative_ptr_container.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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_ASSOCIATIVE_PTR_CONTAINER_HPP
  12. #define BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif
  16. #include <boost/ptr_container/detail/reversible_ptr_container.hpp>
  17. namespace boost
  18. {
  19. namespace ptr_container_detail
  20. {
  21. template
  22. <
  23. class Config,
  24. class CloneAllocator
  25. >
  26. class associative_ptr_container :
  27. public reversible_ptr_container<Config,CloneAllocator>
  28. {
  29. typedef reversible_ptr_container<Config,CloneAllocator>
  30. base_type;
  31. typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
  32. scoped_deleter;
  33. typedef BOOST_DEDUCED_TYPENAME Config::container_type
  34. container_type;
  35. public: // typedefs
  36. typedef BOOST_DEDUCED_TYPENAME Config::key_type
  37. key_type;
  38. typedef BOOST_DEDUCED_TYPENAME Config::key_compare
  39. key_compare;
  40. typedef BOOST_DEDUCED_TYPENAME Config::value_compare
  41. value_compare;
  42. typedef BOOST_DEDUCED_TYPENAME Config::hasher
  43. hasher;
  44. typedef BOOST_DEDUCED_TYPENAME Config::key_equal
  45. key_equal;
  46. typedef BOOST_DEDUCED_TYPENAME Config::iterator
  47. iterator;
  48. typedef BOOST_DEDUCED_TYPENAME Config::const_iterator
  49. const_iterator;
  50. typedef BOOST_DEDUCED_TYPENAME Config::local_iterator
  51. local_iterator;
  52. typedef BOOST_DEDUCED_TYPENAME Config::const_local_iterator
  53. const_local_iterator;
  54. typedef BOOST_DEDUCED_TYPENAME base_type::size_type
  55. size_type;
  56. typedef BOOST_DEDUCED_TYPENAME base_type::reference
  57. reference;
  58. typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
  59. const_reference;
  60. public: // foundation
  61. associative_ptr_container()
  62. { }
  63. template< class SizeType >
  64. associative_ptr_container( SizeType n, unordered_associative_container_tag tag )
  65. : base_type( n, tag )
  66. { }
  67. template< class Compare, class Allocator >
  68. associative_ptr_container( const Compare& comp,
  69. const Allocator& a )
  70. : base_type( comp, a, container_type() )
  71. { }
  72. template< class Hash, class Pred, class Allocator >
  73. associative_ptr_container( const Hash& hash,
  74. const Pred& pred,
  75. const Allocator& a )
  76. : base_type( hash, pred, a )
  77. { }
  78. template< class InputIterator, class Compare, class Allocator >
  79. associative_ptr_container( InputIterator first, InputIterator last,
  80. const Compare& comp,
  81. const Allocator& a )
  82. : base_type( first, last, comp, a, container_type() )
  83. { }
  84. template< class InputIterator, class Hash, class Pred, class Allocator >
  85. associative_ptr_container( InputIterator first, InputIterator last,
  86. const Hash& hash,
  87. const Pred& pred,
  88. const Allocator& a )
  89. : base_type( first, last, hash, pred, a )
  90. { }
  91. template< class PtrContainer >
  92. explicit associative_ptr_container( std::auto_ptr<PtrContainer> r )
  93. : base_type( r )
  94. { }
  95. associative_ptr_container( const associative_ptr_container& r )
  96. : base_type( r.begin(), r.end(), container_type() )
  97. { }
  98. template< class C, class V >
  99. associative_ptr_container( const associative_ptr_container<C,V>& r )
  100. : base_type( r.begin(), r.end(), container_type() )
  101. { }
  102. template< class PtrContainer >
  103. associative_ptr_container& operator=( std::auto_ptr<PtrContainer> r ) // nothrow
  104. {
  105. base_type::operator=( r );
  106. return *this;
  107. }
  108. associative_ptr_container& operator=( associative_ptr_container r ) // strong
  109. {
  110. this->swap( r );
  111. return *this;
  112. }
  113. public: // associative container interface
  114. key_compare key_comp() const
  115. {
  116. return this->base().key_comp();
  117. }
  118. value_compare value_comp() const
  119. {
  120. return this->base().value_comp();
  121. }
  122. iterator erase( iterator before ) // nothrow
  123. {
  124. BOOST_ASSERT( !this->empty() );
  125. BOOST_ASSERT( before != this->end() );
  126. this->remove( before ); // nothrow
  127. iterator res( before ); // nothrow
  128. ++res; // nothrow
  129. this->base().erase( before.base() ); // nothrow
  130. return res; // nothrow
  131. }
  132. size_type erase( const key_type& x ) // nothrow
  133. {
  134. iterator i( this->base().find( x ) );
  135. // nothrow
  136. if( i == this->end() ) // nothrow
  137. return 0u; // nothrow
  138. this->remove( i ); // nothrow
  139. return this->base().erase( x ); // nothrow
  140. }
  141. iterator erase( iterator first,
  142. iterator last ) // nothrow
  143. {
  144. iterator res( last ); // nothrow
  145. if( res != this->end() )
  146. ++res; // nothrow
  147. this->remove( first, last ); // nothrow
  148. this->base().erase( first.base(), last.base() ); // nothrow
  149. return res; // nothrow
  150. }
  151. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  152. #else
  153. template< class Range >
  154. BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_convertible<Range&,key_type&>,
  155. iterator >::type
  156. erase( const Range& r )
  157. {
  158. return erase( boost::begin(r), boost::end(r) );
  159. }
  160. #endif
  161. protected:
  162. template< class AssociatePtrCont >
  163. void multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object,
  164. AssociatePtrCont& from ) // strong
  165. {
  166. BOOST_ASSERT( (void*)&from != (void*)this );
  167. BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
  168. this->base().insert( *object.base() ); // strong
  169. from.base().erase( object.base() ); // nothrow
  170. }
  171. template< class AssociatePtrCont >
  172. size_type multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first,
  173. BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last,
  174. AssociatePtrCont& from ) // basic
  175. {
  176. BOOST_ASSERT( (void*)&from != (void*)this );
  177. size_type res = 0;
  178. for( ; first != last; )
  179. {
  180. BOOST_ASSERT( first != from.end() );
  181. this->base().insert( *first.base() ); // strong
  182. BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator
  183. to_delete( first );
  184. ++first;
  185. from.base().erase( to_delete.base() ); // nothrow
  186. ++res;
  187. }
  188. return res;
  189. }
  190. template< class AssociatePtrCont >
  191. bool single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object,
  192. AssociatePtrCont& from ) // strong
  193. {
  194. BOOST_ASSERT( (void*)&from != (void*)this );
  195. BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
  196. std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p =
  197. this->base().insert( *object.base() ); // strong
  198. if( p.second )
  199. from.base().erase( object.base() ); // nothrow
  200. return p.second;
  201. }
  202. template< class AssociatePtrCont >
  203. size_type single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first,
  204. BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last,
  205. AssociatePtrCont& from ) // basic
  206. {
  207. BOOST_ASSERT( (void*)&from != (void*)this );
  208. size_type res = 0;
  209. for( ; first != last; )
  210. {
  211. BOOST_ASSERT( first != from.end() );
  212. std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p =
  213. this->base().insert( *first.base() ); // strong
  214. BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator
  215. to_delete( first );
  216. ++first;
  217. if( p.second )
  218. {
  219. from.base().erase( to_delete.base() ); // nothrow
  220. ++res;
  221. }
  222. }
  223. return res;
  224. }
  225. reference front()
  226. {
  227. BOOST_ASSERT( !this->empty() );
  228. BOOST_ASSERT( *this->begin().base() != 0 );
  229. return *this->begin();
  230. }
  231. const_reference front() const
  232. {
  233. return const_cast<associative_ptr_container*>(this)->front();
  234. }
  235. reference back()
  236. {
  237. BOOST_ASSERT( !this->empty() );
  238. BOOST_ASSERT( *(--this->end()).base() != 0 );
  239. return *--this->end();
  240. }
  241. const_reference back() const
  242. {
  243. return const_cast<associative_ptr_container*>(this)->back();
  244. }
  245. protected: // unordered interface
  246. hasher hash_function() const
  247. {
  248. return this->base().hash_function();
  249. }
  250. key_equal key_eq() const
  251. {
  252. return this->base().key_eq();
  253. }
  254. size_type bucket_count() const
  255. {
  256. return this->base().bucket_count();
  257. }
  258. size_type max_bucket_count() const
  259. {
  260. return this->base().max_bucket_count();
  261. }
  262. size_type bucket_size( size_type n ) const
  263. {
  264. return this->base().bucket_size( n );
  265. }
  266. float load_factor() const
  267. {
  268. return this->base().load_factor();
  269. }
  270. float max_load_factor() const
  271. {
  272. return this->base().max_load_factor();
  273. }
  274. void max_load_factor( float factor )
  275. {
  276. return this->base().max_load_factor( factor );
  277. }
  278. void rehash( size_type n )
  279. {
  280. this->base().rehash( n );
  281. }
  282. public:
  283. #if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006))
  284. iterator begin()
  285. {
  286. return base_type::begin();
  287. }
  288. const_iterator begin() const
  289. {
  290. return base_type::begin();
  291. }
  292. iterator end()
  293. {
  294. return base_type::end();
  295. }
  296. const_iterator end() const
  297. {
  298. return base_type::end();
  299. }
  300. const_iterator cbegin() const
  301. {
  302. return base_type::cbegin();
  303. }
  304. const_iterator cend() const
  305. {
  306. return base_type::cend();
  307. }
  308. #else
  309. using base_type::begin;
  310. using base_type::end;
  311. using base_type::cbegin;
  312. using base_type::cend;
  313. #endif
  314. protected:
  315. local_iterator begin( size_type n )
  316. {
  317. return local_iterator( this->base().begin( n ) );
  318. }
  319. const_local_iterator begin( size_type n ) const
  320. {
  321. return const_local_iterator( this->base().begin( n ) );
  322. }
  323. local_iterator end( size_type n )
  324. {
  325. return local_iterator( this->base().end( n ) );
  326. }
  327. const_local_iterator end( size_type n ) const
  328. {
  329. return const_local_iterator( this->base().end( n ) );
  330. }
  331. const_local_iterator cbegin( size_type n ) const
  332. {
  333. return const_local_iterator( this->base().cbegin( n ) );
  334. }
  335. const_local_iterator cend( size_type n )
  336. {
  337. return const_local_iterator( this->base().cend( n ) );
  338. }
  339. }; // class 'associative_ptr_container'
  340. } // namespace 'ptr_container_detail'
  341. } // namespace 'boost'
  342. #endif