scoped_deleter.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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_SCOPED_DELETER_HPP
  12. #define BOOST_PTR_CONTAINER_SCOPED_DELETER_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif
  16. #include <iterator>
  17. #include <cstddef>
  18. #include <boost/scoped_array.hpp>
  19. namespace boost
  20. {
  21. namespace ptr_container_detail
  22. {
  23. template< class Container >
  24. class scoped_deleter
  25. {
  26. typedef BOOST_DEDUCED_TYPENAME Container::size_type size_type;
  27. typedef BOOST_DEDUCED_TYPENAME Container::object_type T;
  28. Container& cont_;
  29. scoped_array<T*> ptrs_;
  30. size_type stored_;
  31. bool released_;
  32. public:
  33. scoped_deleter( Container& cont, T** a, size_type size )
  34. : cont_(cont),
  35. ptrs_( a ),
  36. stored_( size ),
  37. released_( false )
  38. {
  39. BOOST_ASSERT( a );
  40. }
  41. scoped_deleter( Container& cont, size_type size )
  42. : cont_(cont),
  43. ptrs_( new T*[size] ),
  44. stored_( 0 ),
  45. released_( false )
  46. {
  47. BOOST_ASSERT( size > 0 );
  48. }
  49. scoped_deleter( Container& cont, size_type n, const T& x ) // strong
  50. : cont_(cont),
  51. ptrs_( new T*[n] ),
  52. stored_(0),
  53. released_( false )
  54. {
  55. for( size_type i = 0; i != n; i++ )
  56. add( cont_.null_policy_allocate_clone( &x ) );
  57. BOOST_ASSERT( stored_ > 0 );
  58. }
  59. template< class InputIterator >
  60. scoped_deleter ( Container& cont, InputIterator first, InputIterator last ) // strong
  61. : cont_(cont),
  62. ptrs_( new T*[ std::distance(first,last) ] ),
  63. stored_(0),
  64. released_( false )
  65. {
  66. for( ; first != last; ++first )
  67. add( cont_.null_policy_allocate_clone_from_iterator( first ) );
  68. BOOST_ASSERT( stored_ > 0 );
  69. }
  70. ~scoped_deleter()
  71. {
  72. if ( !released_ )
  73. {
  74. for( size_type i = 0u; i != stored_; ++i )
  75. cont_.null_policy_deallocate_clone( ptrs_[i] );
  76. }
  77. }
  78. void add( T* t )
  79. {
  80. BOOST_ASSERT( ptrs_.get() != 0 );
  81. ptrs_[stored_] = t;
  82. ++stored_;
  83. }
  84. void release()
  85. {
  86. released_ = true;
  87. }
  88. T** begin()
  89. {
  90. BOOST_ASSERT( ptrs_.get() != 0 );
  91. return &ptrs_[0];
  92. }
  93. T** end()
  94. {
  95. BOOST_ASSERT( ptrs_.get() != 0 );
  96. return &ptrs_[stored_];
  97. }
  98. }; // class 'scoped_deleter'
  99. }
  100. }
  101. #endif