ptr_array.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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_ARRAY_HPP
  12. #define BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif
  16. #include <boost/array.hpp>
  17. #include <boost/static_assert.hpp>
  18. #include <boost/ptr_container/ptr_sequence_adapter.hpp>
  19. namespace boost
  20. {
  21. namespace ptr_container_detail
  22. {
  23. template
  24. <
  25. class T,
  26. size_t N,
  27. class Allocator = int // dummy
  28. >
  29. class ptr_array_impl : public boost::array<T,N>
  30. {
  31. public:
  32. typedef Allocator allocator_type;
  33. ptr_array_impl( Allocator /*a*/ = Allocator() )
  34. {
  35. this->assign( 0 );
  36. }
  37. ptr_array_impl( size_t, T*, Allocator /*a*/ = Allocator() )
  38. {
  39. this->assign( 0 );
  40. }
  41. };
  42. }
  43. template
  44. <
  45. class T,
  46. size_t N,
  47. class CloneAllocator = heap_clone_allocator
  48. >
  49. class ptr_array : public
  50. ptr_sequence_adapter< T,
  51. ptr_container_detail::ptr_array_impl<void*,N>,
  52. CloneAllocator >
  53. {
  54. private:
  55. typedef ptr_sequence_adapter< T,
  56. ptr_container_detail::ptr_array_impl<void*,N>,
  57. CloneAllocator >
  58. base_class;
  59. typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type U;
  60. typedef ptr_array<T,N,CloneAllocator>
  61. this_type;
  62. public:
  63. typedef std::size_t size_type;
  64. typedef U* value_type;
  65. typedef U* pointer;
  66. typedef U& reference;
  67. typedef const U& const_reference;
  68. typedef BOOST_DEDUCED_TYPENAME base_class::auto_type
  69. auto_type;
  70. public: // constructors
  71. ptr_array() : base_class()
  72. { }
  73. ptr_array( const ptr_array& r )
  74. {
  75. size_t i = 0;
  76. for( ; i != N; ++i )
  77. this->base()[i] = this->null_policy_allocate_clone(
  78. static_cast<const T*>( &r[i] ) );
  79. }
  80. template< class U >
  81. ptr_array( const ptr_array<U,N>& r )
  82. {
  83. size_t i = 0;
  84. for( ; i != N; ++i )
  85. this->base()[i] = this->null_policy_allocate_clone(
  86. static_cast<const T*>( &r[i] ) );
  87. }
  88. explicit ptr_array( std::auto_ptr<this_type> r )
  89. : base_class( r ) { }
  90. ptr_array& operator=( ptr_array r )
  91. {
  92. this->swap( r );
  93. return *this;
  94. }
  95. ptr_array& operator=( std::auto_ptr<this_type> r )
  96. {
  97. base_class::operator=(r);
  98. return *this;
  99. }
  100. std::auto_ptr<this_type> release()
  101. {
  102. std::auto_ptr<this_type> ptr( new this_type );
  103. this->swap( *ptr );
  104. return ptr;
  105. }
  106. std::auto_ptr<this_type> clone() const
  107. {
  108. std::auto_ptr<this_type> pa( new this_type );
  109. for( size_t i = 0; i != N; ++i )
  110. {
  111. if( ! is_null(i) )
  112. pa->replace( i, this->null_policy_allocate_clone( &(*this)[i] ) );
  113. }
  114. return pa;
  115. }
  116. private: // hide some members
  117. using base_class::insert;
  118. using base_class::erase;
  119. using base_class::push_back;
  120. using base_class::push_front;
  121. using base_class::pop_front;
  122. using base_class::pop_back;
  123. using base_class::transfer;
  124. using base_class::get_allocator;
  125. public: // compile-time interface
  126. template< size_t idx >
  127. auto_type replace( U* r ) // strong
  128. {
  129. BOOST_STATIC_ASSERT( idx < N );
  130. this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
  131. auto_type res( static_cast<U*>( this->base()[idx] ) ); // nothrow
  132. this->base()[idx] = r; // nothrow
  133. return boost::ptr_container::move(res); // nothrow
  134. }
  135. template< size_t idx, class V >
  136. auto_type replace( std::auto_ptr<V> r )
  137. {
  138. return replace<idx>( r.release() );
  139. }
  140. auto_type replace( size_t idx, U* r ) // strong
  141. {
  142. this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
  143. auto_type ptr( r );
  144. BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= N, bad_index,
  145. "'replace()' aout of bounds" );
  146. auto_type res( static_cast<U*>( this->base()[idx] ) ); // nothrow
  147. this->base()[idx] = ptr.release(); // nothrow
  148. return boost::ptr_container::move(res); // nothrow
  149. }
  150. template< class V >
  151. auto_type replace( size_t idx, std::auto_ptr<V> r )
  152. {
  153. return replace( idx, r.release() );
  154. }
  155. using base_class::at;
  156. template< size_t idx >
  157. T& at()
  158. {
  159. BOOST_STATIC_ASSERT( idx < N );
  160. return (*this)[idx];
  161. }
  162. template< size_t idx >
  163. const T& at() const
  164. {
  165. BOOST_STATIC_ASSERT( idx < N );
  166. return (*this)[idx];
  167. }
  168. bool is_null( size_t idx ) const
  169. {
  170. return base_class::is_null(idx);
  171. }
  172. template< size_t idx >
  173. bool is_null() const
  174. {
  175. BOOST_STATIC_ASSERT( idx < N );
  176. return this->base()[idx] == 0;
  177. }
  178. };
  179. //////////////////////////////////////////////////////////////////////////////
  180. // clonability
  181. template< typename T, size_t size, typename CA >
  182. inline ptr_array<T,size,CA>* new_clone( const ptr_array<T,size,CA>& r )
  183. {
  184. return r.clone().release();
  185. }
  186. /////////////////////////////////////////////////////////////////////////
  187. // swap
  188. template< typename T, size_t size, typename CA >
  189. inline void swap( ptr_array<T,size,CA>& l, ptr_array<T,size,CA>& r )
  190. {
  191. l.swap(r);
  192. }
  193. }
  194. #endif