File indexing completed on 2025-01-18 09:30:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_CONTAINER_DESTROYERS_HPP
0014 #define BOOST_CONTAINER_DESTROYERS_HPP
0015
0016 #ifndef BOOST_CONFIG_HPP
0017 # include <boost/config.hpp>
0018 #endif
0019
0020 #if defined(BOOST_HAS_PRAGMA_ONCE)
0021 # pragma once
0022 #endif
0023
0024 #include <boost/container/detail/config_begin.hpp>
0025 #include <boost/container/detail/workaround.hpp>
0026
0027 #include <boost/container/allocator_traits.hpp>
0028 #include <boost/move/detail/to_raw_pointer.hpp>
0029 #include <boost/container/detail/version_type.hpp>
0030 #include <boost/move/detail/iterator_to_raw_pointer.hpp>
0031
0032 namespace boost {
0033 namespace container {
0034 namespace dtl {
0035
0036
0037
0038 template <class Allocator>
0039 struct scoped_deallocator
0040 {
0041 typedef allocator_traits<Allocator> allocator_traits_type;
0042 typedef typename allocator_traits_type::pointer pointer;
0043 typedef dtl::integral_constant<unsigned,
0044 boost::container::dtl::
0045 version<Allocator>::value> alloc_version;
0046
0047 private:
0048 void priv_deallocate(version_1)
0049 { m_alloc.deallocate(m_ptr, 1); }
0050
0051 void priv_deallocate(version_2)
0052 { m_alloc.deallocate_one(m_ptr); }
0053
0054 BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
0055
0056 public:
0057
0058 pointer m_ptr;
0059 Allocator& m_alloc;
0060
0061 scoped_deallocator(pointer p, Allocator& a)
0062 : m_ptr(p), m_alloc(a)
0063 {}
0064
0065 ~scoped_deallocator()
0066 { if (m_ptr)priv_deallocate(alloc_version()); }
0067
0068 scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
0069 : m_ptr(o.m_ptr), m_alloc(o.m_alloc)
0070 { o.release(); }
0071
0072 pointer get() const
0073 { return m_ptr; }
0074
0075 void set(const pointer &p)
0076 { m_ptr = p; }
0077
0078 void release()
0079 { m_ptr = 0; }
0080 };
0081
0082 template <class Allocator>
0083 struct null_scoped_deallocator
0084 {
0085 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0086 typedef typename AllocTraits::pointer pointer;
0087
0088 null_scoped_deallocator(pointer, Allocator&, std::size_t)
0089 {}
0090
0091 void release()
0092 {}
0093
0094 pointer get() const
0095 { return pointer(); }
0096
0097 void set(const pointer &)
0098 {}
0099 };
0100
0101
0102
0103 template <class Allocator>
0104 struct scoped_array_deallocator
0105 {
0106 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0107 typedef typename AllocTraits::pointer pointer;
0108 typedef typename AllocTraits::size_type size_type;
0109
0110 scoped_array_deallocator(pointer p, Allocator& a, std::size_t length)
0111 : m_ptr(p), m_alloc(a), m_length(length) {}
0112
0113 ~scoped_array_deallocator()
0114 { if (m_ptr) m_alloc.deallocate(m_ptr, size_type(m_length)); }
0115
0116 void release()
0117 { m_ptr = 0; }
0118
0119 private:
0120 pointer m_ptr;
0121 Allocator& m_alloc;
0122 std::size_t m_length;
0123 };
0124
0125 template <class Allocator>
0126 struct null_scoped_array_deallocator
0127 {
0128 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0129 typedef typename AllocTraits::pointer pointer;
0130
0131 null_scoped_array_deallocator(pointer, Allocator&, std::size_t)
0132 {}
0133
0134 void release()
0135 {}
0136 };
0137
0138 template <class Allocator>
0139 struct scoped_node_destroy_deallocator
0140 {
0141 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0142 typedef typename AllocTraits::pointer pointer;
0143 typedef dtl::integral_constant<unsigned,
0144 boost::container::dtl::
0145 version<Allocator>::value> alloc_version;
0146
0147 scoped_node_destroy_deallocator(pointer p, Allocator& a)
0148 : m_ptr(p), m_alloc(a) {}
0149
0150 ~scoped_node_destroy_deallocator()
0151 {
0152 if(m_ptr){
0153 boost::movelib::to_raw_pointer(m_ptr)->destructor(m_alloc);
0154 priv_deallocate(m_ptr, alloc_version());
0155 }
0156 }
0157
0158 void release()
0159 { m_ptr = 0; }
0160
0161 private:
0162
0163 void priv_deallocate(const pointer &p, version_1)
0164 { AllocTraits::deallocate(m_alloc, p, 1); }
0165
0166 void priv_deallocate(const pointer &p, version_2)
0167 { m_alloc.deallocate_one(p); }
0168
0169 pointer m_ptr;
0170 Allocator& m_alloc;
0171 };
0172
0173
0174
0175
0176 template <class Allocator, class Ptr = typename allocator_traits<Allocator>::pointer>
0177 struct scoped_destructor_n
0178 {
0179 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0180 typedef Ptr pointer;
0181 typedef typename AllocTraits::value_type value_type;
0182
0183 BOOST_CONTAINER_FORCEINLINE scoped_destructor_n(Ptr p, Allocator& a, std::size_t n)
0184 : m_p(p), m_n(n), m_a(a)
0185 {}
0186
0187 BOOST_CONTAINER_FORCEINLINE void release()
0188 { m_p = Ptr(); m_n = 0; }
0189
0190 BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t inc)
0191 { m_n += inc; }
0192
0193 BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t inc)
0194 { m_n += inc; m_p -= std::ptrdiff_t(inc); }
0195
0196 BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t inc)
0197 { m_n -= inc; m_p += std::ptrdiff_t(inc); }
0198
0199 BOOST_CONTAINER_FORCEINLINE void set_size(std::size_t sz)
0200 { m_n = sz; }
0201
0202 ~scoped_destructor_n()
0203 {
0204 if(m_n){
0205 value_type *raw_ptr = boost::movelib::iterator_to_raw_pointer(m_p);
0206 do {
0207 --m_n;
0208 AllocTraits::destroy(m_a, raw_ptr);
0209 ++raw_ptr;
0210 } while(m_n);
0211 }
0212 }
0213
0214 private:
0215 pointer m_p;
0216 std::size_t m_n;
0217 Allocator& m_a;
0218 };
0219
0220
0221
0222 template <class Allocator, class Ptr = typename allocator_traits<Allocator>::pointer>
0223 struct null_scoped_destructor_n
0224 {
0225 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0226 typedef Ptr pointer;
0227
0228 BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_n(Ptr, Allocator&, std::size_t)
0229 {}
0230
0231 BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t)
0232 {}
0233
0234 BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t)
0235 {}
0236
0237 BOOST_CONTAINER_FORCEINLINE void set_size(std::size_t )
0238 {}
0239
0240 BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t)
0241 {}
0242
0243 BOOST_CONTAINER_FORCEINLINE void release()
0244 {}
0245 };
0246
0247
0248
0249
0250 template <class Allocator>
0251 struct scoped_destructor_range
0252 {
0253 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0254 typedef typename AllocTraits::pointer pointer;
0255 typedef typename AllocTraits::value_type value_type;
0256
0257 BOOST_CONTAINER_FORCEINLINE scoped_destructor_range(pointer p, pointer e, Allocator& a)
0258 : m_p(p), m_e(e), m_a(a)
0259 {}
0260
0261 BOOST_CONTAINER_FORCEINLINE void release()
0262 { m_p = pointer(); m_e = pointer(); }
0263
0264 BOOST_CONTAINER_FORCEINLINE void set_end(pointer e)
0265 { m_e = e; }
0266
0267 BOOST_CONTAINER_FORCEINLINE void set_begin(pointer b)
0268 { m_p = b; }
0269
0270 BOOST_CONTAINER_FORCEINLINE void set_range(pointer b, pointer e)
0271 { m_p = b; m_e = e; }
0272
0273 ~scoped_destructor_range()
0274 {
0275 while(m_p != m_e){
0276 value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
0277 AllocTraits::destroy(m_a, raw_ptr);
0278 ++m_p;
0279 }
0280 }
0281
0282 private:
0283 pointer m_p;
0284 pointer m_e;
0285 Allocator & m_a;
0286 };
0287
0288
0289
0290 template <class Allocator>
0291 struct null_scoped_destructor_range
0292 {
0293 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0294 typedef typename AllocTraits::pointer pointer;
0295
0296 BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_range(pointer, pointer, Allocator&)
0297 {}
0298
0299 BOOST_CONTAINER_FORCEINLINE void release()
0300 {}
0301
0302 BOOST_CONTAINER_FORCEINLINE void set_end(pointer)
0303 {}
0304
0305 BOOST_CONTAINER_FORCEINLINE void set_begin(pointer)
0306 {}
0307
0308 BOOST_CONTAINER_FORCEINLINE void set_range(pointer, pointer)
0309 {}
0310 };
0311
0312
0313 template<class Allocator>
0314 class scoped_destructor
0315 {
0316 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0317 public:
0318 typedef typename Allocator::value_type value_type;
0319 BOOST_CONTAINER_FORCEINLINE scoped_destructor(Allocator &a, value_type *pv)
0320 : pv_(pv), a_(a)
0321 {}
0322
0323 BOOST_CONTAINER_FORCEINLINE ~scoped_destructor()
0324 {
0325 if(pv_){
0326 AllocTraits::destroy(a_, pv_);
0327 }
0328 }
0329
0330 BOOST_CONTAINER_FORCEINLINE void release()
0331 { pv_ = 0; }
0332
0333
0334 BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; }
0335
0336 BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; }
0337
0338 private:
0339 value_type *pv_;
0340 Allocator &a_;
0341 };
0342
0343 template<class Allocator>
0344 class null_scoped_destructor
0345 {
0346 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0347 public:
0348 typedef typename Allocator::value_type value_type;
0349 BOOST_CONTAINER_FORCEINLINE null_scoped_destructor(Allocator &, value_type *)
0350 {}
0351
0352 BOOST_CONTAINER_FORCEINLINE ~null_scoped_destructor()
0353 {}
0354
0355 BOOST_CONTAINER_FORCEINLINE void release()
0356 {}
0357
0358 BOOST_CONTAINER_FORCEINLINE void set(value_type *) { }
0359
0360 BOOST_CONTAINER_FORCEINLINE value_type *get() const { return 0; }
0361 };
0362
0363
0364
0365 template<class Allocator, class Value = typename Allocator::value_type>
0366 class value_destructor
0367 {
0368 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0369 public:
0370 typedef Value value_type;
0371 BOOST_CONTAINER_FORCEINLINE value_destructor(Allocator &a, value_type &rv)
0372 : rv_(rv), a_(a)
0373 {}
0374
0375 BOOST_CONTAINER_FORCEINLINE ~value_destructor()
0376 {
0377 AllocTraits::destroy(a_, &rv_);
0378 }
0379
0380 private:
0381 value_type &rv_;
0382 Allocator &a_;
0383 };
0384
0385 template <class Allocator>
0386 class allocator_node_destroyer
0387 {
0388 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0389 typedef typename AllocTraits::value_type value_type;
0390 typedef typename AllocTraits::pointer pointer;
0391 typedef dtl::integral_constant<unsigned,
0392 boost::container::dtl::
0393 version<Allocator>::value> alloc_version;
0394
0395 private:
0396 Allocator & a_;
0397
0398 private:
0399 BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_1)
0400 { AllocTraits::deallocate(a_,p, 1); }
0401
0402 BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_2)
0403 { a_.deallocate_one(p); }
0404
0405 public:
0406 BOOST_CONTAINER_FORCEINLINE explicit allocator_node_destroyer(Allocator &a)
0407 : a_(a)
0408 {}
0409
0410 BOOST_CONTAINER_FORCEINLINE void operator()(const pointer &p)
0411 {
0412 boost::movelib::to_raw_pointer(p)->destructor(a_);
0413 this->priv_deallocate(p, alloc_version());
0414 }
0415 };
0416
0417 template<class Allocator>
0418 class scoped_node_destructor
0419 {
0420 typedef boost::container::allocator_traits<Allocator> AllocTraits;
0421 public:
0422 typedef typename Allocator::value_type value_type;
0423 BOOST_CONTAINER_FORCEINLINE scoped_node_destructor(Allocator &a, value_type *pv)
0424 : pv_(pv), a_(a)
0425 {}
0426
0427 BOOST_CONTAINER_FORCEINLINE ~scoped_node_destructor()
0428 {
0429 if(pv_){
0430 pv_->destructor(a_);
0431 }
0432 }
0433
0434 BOOST_CONTAINER_FORCEINLINE void release()
0435 { pv_ = 0; }
0436
0437
0438 BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; }
0439
0440 BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; }
0441
0442 private:
0443 value_type *pv_;
0444 Allocator &a_;
0445 };
0446
0447
0448
0449 template <class Allocator>
0450 class allocator_node_destroyer_and_chain_builder
0451 {
0452 typedef allocator_traits<Allocator> allocator_traits_type;
0453 typedef typename allocator_traits_type::value_type value_type;
0454 typedef typename Allocator::multiallocation_chain multiallocation_chain;
0455
0456 Allocator & a_;
0457 multiallocation_chain &c_;
0458
0459 public:
0460 BOOST_CONTAINER_FORCEINLINE allocator_node_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
0461 : a_(a), c_(c)
0462 {}
0463
0464 BOOST_CONTAINER_FORCEINLINE void operator()(const typename Allocator::pointer &p)
0465 {
0466 boost::movelib::to_raw_pointer(p)->destructor(a_);
0467 c_.push_back(p);
0468 }
0469 };
0470
0471 template <class Allocator>
0472 class allocator_multialloc_chain_node_deallocator
0473 {
0474 typedef allocator_traits<Allocator> allocator_traits_type;
0475 typedef typename allocator_traits_type::value_type value_type;
0476 typedef typename Allocator::multiallocation_chain multiallocation_chain;
0477 typedef allocator_node_destroyer_and_chain_builder<Allocator> chain_builder;
0478
0479 Allocator & a_;
0480 multiallocation_chain c_;
0481
0482 public:
0483 BOOST_CONTAINER_FORCEINLINE allocator_multialloc_chain_node_deallocator(Allocator &a)
0484 : a_(a), c_()
0485 {}
0486
0487 BOOST_CONTAINER_FORCEINLINE chain_builder get_chain_builder()
0488 { return chain_builder(a_, c_); }
0489
0490 BOOST_CONTAINER_FORCEINLINE ~allocator_multialloc_chain_node_deallocator()
0491 {
0492 a_.deallocate_individual(c_);
0493 }
0494 };
0495
0496 }
0497 }
0498 }
0499
0500 #include <boost/container/detail/config_end.hpp>
0501
0502 #endif