File indexing completed on 2025-07-11 08:06:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
0012 #define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024
0025
0026 #include <boost/container/allocator_traits.hpp>
0027
0028 #include <boost/container/detail/addressof.hpp>
0029 #include <boost/container/detail/alloc_helpers.hpp>
0030 #include <boost/container/detail/allocator_version_traits.hpp>
0031 #include <boost/container/detail/construct_in_place.hpp>
0032 #include <boost/container/detail/destroyers.hpp>
0033 #include <boost/move/detail/iterator_to_raw_pointer.hpp>
0034 #include <boost/move/detail/launder.hpp>
0035 #include <boost/container/detail/mpl.hpp>
0036 #include <boost/container/detail/placement_new.hpp>
0037 #include <boost/move/detail/to_raw_pointer.hpp>
0038 #include <boost/container/detail/type_traits.hpp>
0039 #include <boost/container/detail/version_type.hpp>
0040 #include <boost/container/detail/is_pair.hpp>
0041 #include <boost/container/detail/pair.hpp>
0042
0043 #include <boost/intrusive/detail/mpl.hpp>
0044 #include <boost/intrusive/options.hpp>
0045
0046 #include <boost/move/utility_core.hpp>
0047 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0048 #include <boost/move/detail/fwd_macros.hpp>
0049 #endif
0050
0051
0052 namespace boost {
0053 namespace container {
0054
0055
0056
0057 template<class T, bool>
0058 struct node_internal_data_type
0059 {
0060 typedef T type;
0061 };
0062
0063 template<class T>
0064 struct node_internal_data_type< T, true>
0065 {
0066 typedef dtl::pair< typename dtl::remove_const<typename T::first_type>::type
0067 , typename T::second_type>
0068 type;
0069 };
0070
0071 template <class T, class HookDefiner, bool PairBased = false>
0072 struct base_node
0073 : public HookDefiner::type
0074 {
0075 public:
0076 typedef T value_type;
0077 typedef typename node_internal_data_type<T, PairBased && dtl::is_pair<T>::value>::type internal_type;
0078 typedef typename HookDefiner::type hook_type;
0079
0080 typedef typename dtl::aligned_storage<sizeof(T), dtl::alignment_of<T>::value>::type storage_t;
0081 storage_t m_storage;
0082
0083 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) && (BOOST_GCC < 80000)
0084 #pragma GCC diagnostic push
0085 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
0086 #define BOOST_CONTAINER_DISABLE_ALIASING_WARNING
0087 # endif
0088 public:
0089
0090 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0091
0092 template<class Alloc, class ...Args>
0093 explicit base_node(Alloc &a, Args &&...args)
0094 : hook_type()
0095 {
0096 ::boost::container::allocator_traits<Alloc>::construct
0097 (a, &this->get_real_data(), ::boost::forward<Args>(args)...);
0098 }
0099
0100 #else
0101
0102 #define BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL(N) \
0103 template< class Alloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
0104 explicit base_node(Alloc &a BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0105 : hook_type()\
0106 {\
0107 ::boost::container::allocator_traits<Alloc>::construct\
0108 (a, &this->get_real_data() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
0109 }\
0110
0111 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL)
0112 #undef BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL
0113
0114 #endif
0115
0116 template<class Alloc, class It>
0117 explicit base_node(iterator_arg_t, Alloc &a, It it)
0118 : hook_type()
0119 {
0120 ::boost::container::construct_in_place(a, &this->get_real_data(), it);
0121 }
0122
0123 inline T &get_data()
0124 { return *move_detail::force_ptr<T*>(&this->m_storage); }
0125
0126 inline const T &get_data() const
0127 { return *move_detail::launder_cast<const T*>(&this->m_storage); }
0128
0129 inline internal_type &get_real_data()
0130 { return *move_detail::launder_cast<internal_type*>(&this->m_storage); }
0131
0132 inline const internal_type &get_real_data() const
0133 { return *move_detail::launder_cast<const internal_type*>(&this->m_storage); }
0134
0135 #if defined(BOOST_CONTAINER_DISABLE_ALIASING_WARNING)
0136 #pragma GCC diagnostic pop
0137 #undef BOOST_CONTAINER_DISABLE_ALIASING_WARNING
0138 # endif
0139
0140 template<class Alloc>
0141 inline void destructor(Alloc &a) BOOST_NOEXCEPT
0142 {
0143 allocator_traits<Alloc>::destroy
0144 (a, &this->get_real_data());
0145 this->~base_node();
0146 }
0147
0148 template<class Pair>
0149 inline
0150 typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
0151 do_assign(const Pair &p)
0152 {
0153 typedef typename Pair::first_type first_type;
0154 const_cast<typename dtl::remove_const<first_type>::type &>(this->get_real_data().first) = p.first;
0155 this->get_real_data().second = p.second;
0156 }
0157
0158 template<class V>
0159 inline
0160 typename dtl::disable_if< dtl::is_pair<V>, void >::type
0161 do_assign(const V &v)
0162 { this->get_real_data() = v; }
0163
0164 template<class Pair>
0165 inline
0166 typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
0167 do_move_assign(Pair &p)
0168 {
0169 typedef typename Pair::first_type first_type;
0170 const_cast<first_type&>(this->get_real_data().first) = ::boost::move(p.first);
0171 this->get_real_data().second = ::boost::move(p.second);
0172 }
0173
0174 template<class V>
0175 inline
0176 typename dtl::disable_if< dtl::is_pair<V>, void >::type
0177 do_move_assign(V &v)
0178 { this->get_real_data() = ::boost::move(v); }
0179
0180 private:
0181 base_node();
0182
0183 inline ~base_node()
0184 { }
0185 };
0186
0187
0188 namespace dtl {
0189
0190 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_compare)
0191 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_equal)
0192 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(hasher)
0193 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
0194 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(bucket_traits)
0195 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(bucket_type)
0196
0197 template<class Allocator, class ICont>
0198 struct node_alloc_holder
0199 : public allocator_traits<Allocator>::template
0200 portable_rebind_alloc<typename ICont::value_type>::type
0201 {
0202
0203
0204 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
0205 ( boost::container::dtl::
0206 , ICont, key_compare, dtl::nat) intrusive_key_compare;
0207
0208
0209
0210 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
0211 (boost::container::dtl::
0212 , ICont, key_equal, dtl::nat2) intrusive_val_equal;
0213 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
0214 (boost::container::dtl::
0215 , ICont, hasher, dtl::nat3) intrusive_val_hasher;
0216 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
0217 (boost::container::dtl::
0218 , ICont, bucket_traits, dtl::natN<0>) intrusive_bucket_traits;
0219 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
0220 (boost::container::dtl::
0221 , ICont, bucket_type, dtl::natN<1>) intrusive_bucket_type;
0222
0223
0224 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
0225 (boost::container::dtl::
0226 , intrusive_val_equal
0227 , predicate_type, dtl::nat2) val_equal;
0228 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
0229 (boost::container::dtl::
0230 , intrusive_val_hasher
0231 , predicate_type, dtl::nat3) val_hasher;
0232
0233 typedef allocator_traits<Allocator> allocator_traits_type;
0234 typedef typename allocator_traits_type::value_type val_type;
0235 typedef ICont intrusive_container;
0236 typedef typename ICont::value_type Node;
0237 typedef typename allocator_traits_type::template
0238 portable_rebind_alloc<Node>::type NodeAlloc;
0239 typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
0240 typedef dtl::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
0241 typedef Allocator ValAlloc;
0242 typedef typename node_allocator_traits_type::pointer NodePtr;
0243 typedef dtl::scoped_deallocator<NodeAlloc> Deallocator;
0244 typedef typename node_allocator_traits_type::size_type size_type;
0245 typedef typename node_allocator_traits_type::difference_type difference_type;
0246 typedef dtl::integral_constant<unsigned,
0247 boost::container::dtl::
0248 version<NodeAlloc>::value> alloc_version;
0249 typedef typename ICont::iterator icont_iterator;
0250 typedef typename ICont::const_iterator icont_citerator;
0251 typedef allocator_node_destroyer<NodeAlloc> Destroyer;
0252 typedef allocator_traits<NodeAlloc> NodeAllocTraits;
0253 typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
0254
0255 private:
0256 BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
0257
0258 public:
0259
0260
0261 inline node_alloc_holder()
0262 {}
0263
0264 explicit node_alloc_holder(const intrusive_bucket_traits& bt)
0265 : m_icont(bt)
0266 {}
0267
0268 explicit node_alloc_holder(const ValAlloc &a)
0269 : NodeAlloc(a)
0270 {}
0271
0272 node_alloc_holder(const intrusive_bucket_traits& bt, const ValAlloc& a)
0273 : NodeAlloc(a)
0274 , m_icont(bt)
0275 {}
0276
0277
0278 node_alloc_holder(const intrusive_key_compare &c, const ValAlloc &a)
0279 : NodeAlloc(a), m_icont(c)
0280 {}
0281
0282 node_alloc_holder(const intrusive_bucket_traits & bt, const val_hasher &hf, const val_equal &eql, const ValAlloc &a)
0283 : NodeAlloc(a)
0284 , m_icont(bt
0285 , typename ICont::hasher(hf)
0286 , typename ICont::key_equal(eql))
0287 {}
0288
0289 node_alloc_holder(const intrusive_bucket_traits& bt, const val_hasher &hf, const ValAlloc &a)
0290 : NodeAlloc(a)
0291 , m_icont(bt
0292 , typename ICont::hasher(hf)
0293 , typename ICont::key_equal())
0294 {}
0295
0296 node_alloc_holder(const intrusive_bucket_traits& bt, const val_hasher &hf)
0297 : m_icont(bt
0298 , typename ICont::hasher(hf)
0299 , typename ICont::key_equal())
0300 {}
0301
0302 explicit node_alloc_holder(const node_alloc_holder &x)
0303 : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
0304 {}
0305
0306 node_alloc_holder(const node_alloc_holder &x, const intrusive_key_compare &c)
0307 : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
0308 , m_icont(c)
0309 {}
0310
0311 node_alloc_holder(const node_alloc_holder &x, const intrusive_bucket_traits& bt, const val_hasher &hf, const val_equal &eql)
0312 : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
0313 , m_icont( bt
0314 , typename ICont::hasher(hf)
0315 , typename ICont::key_equal(eql))
0316 {}
0317
0318 node_alloc_holder(const val_hasher &hf, const intrusive_bucket_traits& bt, const val_equal &eql)
0319 : m_icont(bt
0320 , typename ICont::hasher(hf)
0321 , typename ICont::key_equal(eql))
0322 {}
0323
0324 explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
0325 : NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc()))
0326 { this->icont().swap(x.icont()); }
0327
0328 explicit node_alloc_holder(const intrusive_key_compare &c)
0329 : m_icont(c)
0330 {}
0331
0332
0333 explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const intrusive_key_compare &c)
0334 : NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc())), m_icont(c)
0335 { this->icont().swap(x.icont()); }
0336
0337 explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const intrusive_bucket_traits& bt, const val_hasher &hf, const val_equal &eql)
0338 : NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc()))
0339 , m_icont( bt
0340 , typename ICont::hasher(hf)
0341 , typename ICont::key_equal(eql))
0342 { this->icont().swap(BOOST_MOVE_TO_LV(x).icont()); }
0343
0344 inline void copy_assign_alloc(const node_alloc_holder &x)
0345 {
0346 dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag;
0347 dtl::assign_alloc( static_cast<NodeAlloc &>(*this)
0348 , static_cast<const NodeAlloc &>(x), flag);
0349 }
0350
0351 inline void move_assign_alloc( node_alloc_holder &x)
0352 {
0353 dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
0354 dtl::move_alloc( static_cast<NodeAlloc &>(*this)
0355 , static_cast<NodeAlloc &>(x), flag);
0356 }
0357
0358 inline ~node_alloc_holder()
0359 { this->clear(alloc_version()); }
0360
0361 inline size_type max_size() const
0362 { return allocator_traits_type::max_size(this->node_alloc()); }
0363
0364 inline NodePtr allocate_one()
0365 { return AllocVersionTraits::allocate_one(this->node_alloc()); }
0366
0367 inline void deallocate_one(const NodePtr &p)
0368 { AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
0369
0370 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0371
0372 template<class ...Args>
0373 NodePtr create_node(Args &&...args)
0374 {
0375 NodePtr p = this->allocate_one();
0376 NodeAlloc &nalloc = this->node_alloc();
0377 Deallocator node_deallocator(p, nalloc);
0378 ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t())
0379 Node(nalloc, boost::forward<Args>(args)...);
0380 node_deallocator.release();
0381 return (p);
0382 }
0383
0384 #else
0385
0386 #define BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL(N) \
0387 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0388 NodePtr create_node(BOOST_MOVE_UREF##N)\
0389 {\
0390 NodePtr p = this->allocate_one();\
0391 NodeAlloc &nalloc = this->node_alloc();\
0392 Deallocator node_deallocator(p, nalloc);\
0393 ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t())\
0394 Node(nalloc BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
0395 node_deallocator.release();\
0396 return (p);\
0397 }\
0398
0399 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL)
0400 #undef BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL
0401
0402 #endif
0403
0404 template<class It>
0405 NodePtr create_node_from_it(const It &it)
0406 {
0407 NodePtr p = this->allocate_one();
0408 NodeAlloc &nalloc = this->node_alloc();
0409 Deallocator node_deallocator(p, nalloc);
0410 ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t())
0411 Node(iterator_arg_t(), nalloc, it);
0412 node_deallocator.release();
0413 return (p);
0414 }
0415
0416 template<class KeyConvertible>
0417 NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key)
0418 {
0419 NodePtr p = this->allocate_one();
0420 BOOST_CONTAINER_TRY{
0421 ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;
0422 NodeAlloc &na = this->node_alloc();
0423 node_allocator_traits_type::construct
0424 (na, dtl::addressof(p->get_real_data().first), boost::forward<KeyConvertible>(key));
0425 BOOST_CONTAINER_TRY{
0426 node_allocator_traits_type::construct(na, dtl::addressof(p->get_real_data().second));
0427 }
0428 BOOST_CONTAINER_CATCH(...){
0429 node_allocator_traits_type::destroy(na, dtl::addressof(p->get_real_data().first));
0430 BOOST_CONTAINER_RETHROW;
0431 }
0432 BOOST_CONTAINER_CATCH_END
0433 }
0434 BOOST_CONTAINER_CATCH(...) {
0435 p->destroy_header();
0436 this->node_alloc().deallocate(p, 1);
0437 BOOST_CONTAINER_RETHROW
0438 }
0439 BOOST_CONTAINER_CATCH_END
0440 return (p);
0441 }
0442
0443 void destroy_node(const NodePtr &nodep)
0444 {
0445 boost::movelib::to_raw_pointer(nodep)->destructor(this->node_alloc());
0446 this->deallocate_one(nodep);
0447 }
0448
0449 void swap(node_alloc_holder &x)
0450 {
0451 this->icont().swap(x.icont());
0452 dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
0453 dtl::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
0454 }
0455
0456 template<class FwdIterator, class Inserter>
0457 void allocate_many_and_construct
0458 (FwdIterator beg, size_type n, Inserter inserter)
0459 {
0460 if(n){
0461 typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain_t;
0462
0463
0464 typedef typename multiallocation_chain_t::iterator multialloc_iterator_t;
0465 multiallocation_chain_t chain;
0466 NodeAlloc &nalloc = this->node_alloc();
0467 node_allocator_version_traits_type::allocate_individual(nalloc, n, chain);
0468 multialloc_iterator_t itbeg = chain.begin();
0469 multialloc_iterator_t itlast = chain.last();
0470 chain.clear();
0471
0472 Node *p = 0;
0473 BOOST_CONTAINER_TRY{
0474 Deallocator node_deallocator(NodePtr(), nalloc);
0475 dtl::scoped_node_destructor<NodeAlloc> sdestructor(nalloc, 0);
0476 while(n){
0477 --n;
0478 p = boost::movelib::iterator_to_raw_pointer(itbeg);
0479 ++itbeg;
0480
0481 ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t())
0482 Node(iterator_arg_t(), nalloc, beg);
0483 sdestructor.set(p);
0484 ++beg;
0485
0486
0487 inserter(*p);
0488 sdestructor.release();
0489 }
0490 sdestructor.release();
0491 node_deallocator.release();
0492 }
0493 BOOST_CONTAINER_CATCH(...){
0494 chain.incorporate_after(chain.last(), &*itbeg, &*itlast, n);
0495 node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), chain);
0496 BOOST_CONTAINER_RETHROW
0497 }
0498 BOOST_CONTAINER_CATCH_END
0499 }
0500 }
0501
0502 inline void clear(version_1)
0503 { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
0504
0505 void clear(version_2)
0506 {
0507 typename NodeAlloc::multiallocation_chain chain;
0508 allocator_node_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
0509 this->icont().clear_and_dispose(builder);
0510
0511 if(!chain.empty())
0512 this->node_alloc().deallocate_individual(chain);
0513 }
0514
0515 icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
0516 { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
0517
0518 icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
0519 {
0520 NodeAlloc & nalloc = this->node_alloc();
0521 typename NodeAlloc::multiallocation_chain chain;
0522 allocator_node_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain);
0523 icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder);
0524 nalloc.deallocate_individual(chain);
0525 return ret_it;
0526 }
0527
0528 template<class Key>
0529 inline size_type erase_key(const Key& k, version_1)
0530 { return this->icont().erase_and_dispose(k, Destroyer(this->node_alloc())); }
0531
0532 template<class Key>
0533 inline size_type erase_key(const Key& k, version_2)
0534 {
0535 allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
0536 return this->icont().erase_and_dispose(k, chain_holder.get_chain_builder());
0537 }
0538
0539 template<class Key, class KeyCompare>
0540 inline size_type erase_key(const Key& k, KeyCompare cmp, version_1)
0541 {
0542 return this->icont().erase_and_dispose(k, cmp, Destroyer(this->node_alloc()));
0543 }
0544
0545 template<class Key, class KeyCompare>
0546 inline size_type erase_key(const Key& k, KeyCompare cmp, version_2)
0547 {
0548 allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
0549 return this->icont().erase_and_dispose(k, cmp, chain_holder.get_chain_builder());
0550 }
0551
0552 protected:
0553 struct cloner
0554 {
0555 inline explicit cloner(node_alloc_holder &holder)
0556 : m_holder(holder)
0557 {}
0558
0559 inline NodePtr operator()(const Node &other) const
0560 { return m_holder.create_node(other.get_real_data()); }
0561
0562 node_alloc_holder &m_holder;
0563 };
0564
0565 struct move_cloner
0566 {
0567 inline move_cloner(node_alloc_holder &holder)
0568 : m_holder(holder)
0569 {}
0570
0571 inline NodePtr operator()(Node &other)
0572 {
0573 return m_holder.create_node(::boost::move(other.get_real_data()));
0574 }
0575
0576 node_alloc_holder &m_holder;
0577 };
0578
0579 inline ICont &non_const_icont() const
0580 { return const_cast<ICont&>(this->m_icont); }
0581
0582 inline NodeAlloc &node_alloc()
0583 { return static_cast<NodeAlloc &>(*this); }
0584
0585 inline const NodeAlloc &node_alloc() const
0586 { return static_cast<const NodeAlloc &>(*this); }
0587
0588 public:
0589 inline ICont &icont()
0590 { return this->m_icont; }
0591
0592 inline const ICont &icont() const
0593 { return this->m_icont; }
0594
0595 protected:
0596
0597 ICont m_icont;
0598 };
0599
0600 template<class Node, class KeyOfValue>
0601 struct key_of_node : KeyOfValue
0602 {
0603 typedef typename KeyOfValue::type type;
0604
0605 inline key_of_node()
0606 {}
0607
0608 inline const type& operator()(const Node& x) const
0609 { return this->KeyOfValue::operator()(x.get_data()); }
0610 };
0611
0612
0613 }
0614 }
0615 }
0616
0617 #include <boost/container/detail/config_end.hpp>
0618
0619 #endif