Chris@16
|
1 //
|
Chris@16
|
2 // Boost.Pointer Container
|
Chris@16
|
3 //
|
Chris@16
|
4 // Copyright Thorsten Ottosen 2003-2005. Use, modification and
|
Chris@16
|
5 // distribution is subject to the Boost Software License, Version
|
Chris@16
|
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // For more information, see http://www.boost.org/libs/ptr_container/
|
Chris@16
|
10 //
|
Chris@16
|
11
|
Chris@16
|
12 #ifndef BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
|
Chris@16
|
13 #define BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
|
Chris@16
|
14
|
Chris@16
|
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
16 # pragma once
|
Chris@16
|
17 #endif
|
Chris@16
|
18
|
Chris@16
|
19 #include <boost/array.hpp>
|
Chris@16
|
20 #include <boost/static_assert.hpp>
|
Chris@16
|
21 #include <boost/ptr_container/ptr_sequence_adapter.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost
|
Chris@16
|
24 {
|
Chris@16
|
25
|
Chris@16
|
26 namespace ptr_container_detail
|
Chris@16
|
27 {
|
Chris@16
|
28 template
|
Chris@16
|
29 <
|
Chris@16
|
30 class T,
|
Chris@16
|
31 size_t N,
|
Chris@16
|
32 class Allocator = int // dummy
|
Chris@16
|
33 >
|
Chris@16
|
34 class ptr_array_impl : public boost::array<T,N>
|
Chris@16
|
35 {
|
Chris@16
|
36 public:
|
Chris@16
|
37 typedef Allocator allocator_type;
|
Chris@16
|
38
|
Chris@16
|
39 ptr_array_impl( Allocator /*a*/ = Allocator() )
|
Chris@16
|
40 {
|
Chris@16
|
41 this->assign( 0 );
|
Chris@16
|
42 }
|
Chris@16
|
43
|
Chris@16
|
44 ptr_array_impl( size_t, T*, Allocator /*a*/ = Allocator() )
|
Chris@16
|
45 {
|
Chris@16
|
46 this->assign( 0 );
|
Chris@16
|
47 }
|
Chris@16
|
48 };
|
Chris@16
|
49 }
|
Chris@16
|
50
|
Chris@16
|
51 template
|
Chris@16
|
52 <
|
Chris@16
|
53 class T,
|
Chris@16
|
54 size_t N,
|
Chris@16
|
55 class CloneAllocator = heap_clone_allocator
|
Chris@16
|
56 >
|
Chris@16
|
57 class ptr_array : public
|
Chris@16
|
58 ptr_sequence_adapter< T,
|
Chris@16
|
59 ptr_container_detail::ptr_array_impl<void*,N>,
|
Chris@16
|
60 CloneAllocator >
|
Chris@16
|
61 {
|
Chris@16
|
62 private:
|
Chris@16
|
63 typedef ptr_sequence_adapter< T,
|
Chris@16
|
64 ptr_container_detail::ptr_array_impl<void*,N>,
|
Chris@16
|
65 CloneAllocator >
|
Chris@16
|
66 base_class;
|
Chris@16
|
67
|
Chris@16
|
68 typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type U;
|
Chris@16
|
69
|
Chris@16
|
70 typedef ptr_array<T,N,CloneAllocator>
|
Chris@16
|
71 this_type;
|
Chris@16
|
72
|
Chris@16
|
73 public:
|
Chris@16
|
74 typedef std::size_t size_type;
|
Chris@16
|
75 typedef U* value_type;
|
Chris@16
|
76 typedef U* pointer;
|
Chris@16
|
77 typedef U& reference;
|
Chris@16
|
78 typedef const U& const_reference;
|
Chris@16
|
79 typedef BOOST_DEDUCED_TYPENAME base_class::auto_type
|
Chris@16
|
80 auto_type;
|
Chris@16
|
81
|
Chris@16
|
82 public: // constructors
|
Chris@16
|
83 ptr_array() : base_class()
|
Chris@16
|
84 { }
|
Chris@16
|
85
|
Chris@16
|
86 ptr_array( const ptr_array& r )
|
Chris@16
|
87 {
|
Chris@16
|
88 size_t i = 0;
|
Chris@16
|
89 for( ; i != N; ++i )
|
Chris@16
|
90 this->base()[i] = this->null_policy_allocate_clone(
|
Chris@16
|
91 static_cast<const T*>( &r[i] ) );
|
Chris@16
|
92 }
|
Chris@16
|
93
|
Chris@16
|
94 template< class U >
|
Chris@16
|
95 ptr_array( const ptr_array<U,N>& r )
|
Chris@16
|
96 {
|
Chris@16
|
97 size_t i = 0;
|
Chris@16
|
98 for( ; i != N; ++i )
|
Chris@16
|
99 this->base()[i] = this->null_policy_allocate_clone(
|
Chris@16
|
100 static_cast<const T*>( &r[i] ) );
|
Chris@16
|
101 }
|
Chris@16
|
102
|
Chris@16
|
103 explicit ptr_array( std::auto_ptr<this_type> r )
|
Chris@16
|
104 : base_class( r ) { }
|
Chris@16
|
105
|
Chris@16
|
106 ptr_array& operator=( ptr_array r )
|
Chris@16
|
107 {
|
Chris@16
|
108 this->swap( r );
|
Chris@16
|
109 return *this;
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 ptr_array& operator=( std::auto_ptr<this_type> r )
|
Chris@16
|
113 {
|
Chris@16
|
114 base_class::operator=(r);
|
Chris@16
|
115 return *this;
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@16
|
118 std::auto_ptr<this_type> release()
|
Chris@16
|
119 {
|
Chris@16
|
120 std::auto_ptr<this_type> ptr( new this_type );
|
Chris@16
|
121 this->swap( *ptr );
|
Chris@16
|
122 return ptr;
|
Chris@16
|
123 }
|
Chris@16
|
124
|
Chris@16
|
125 std::auto_ptr<this_type> clone() const
|
Chris@16
|
126 {
|
Chris@16
|
127 std::auto_ptr<this_type> pa( new this_type );
|
Chris@16
|
128 for( size_t i = 0; i != N; ++i )
|
Chris@16
|
129 {
|
Chris@16
|
130 if( ! is_null(i) )
|
Chris@16
|
131 pa->replace( i, this->null_policy_allocate_clone( &(*this)[i] ) );
|
Chris@16
|
132 }
|
Chris@16
|
133 return pa;
|
Chris@16
|
134 }
|
Chris@16
|
135
|
Chris@16
|
136 private: // hide some members
|
Chris@16
|
137 using base_class::insert;
|
Chris@16
|
138 using base_class::erase;
|
Chris@16
|
139 using base_class::push_back;
|
Chris@16
|
140 using base_class::push_front;
|
Chris@16
|
141 using base_class::pop_front;
|
Chris@16
|
142 using base_class::pop_back;
|
Chris@16
|
143 using base_class::transfer;
|
Chris@16
|
144 using base_class::get_allocator;
|
Chris@16
|
145
|
Chris@16
|
146 public: // compile-time interface
|
Chris@16
|
147
|
Chris@16
|
148 template< size_t idx >
|
Chris@16
|
149 auto_type replace( U* r ) // strong
|
Chris@16
|
150 {
|
Chris@16
|
151 BOOST_STATIC_ASSERT( idx < N );
|
Chris@16
|
152
|
Chris@16
|
153 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
|
Chris@16
|
154
|
Chris@16
|
155 auto_type res( static_cast<U*>( this->base()[idx] ) ); // nothrow
|
Chris@16
|
156 this->base()[idx] = r; // nothrow
|
Chris@16
|
157 return boost::ptr_container::move(res); // nothrow
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160 template< size_t idx, class V >
|
Chris@16
|
161 auto_type replace( std::auto_ptr<V> r )
|
Chris@16
|
162 {
|
Chris@16
|
163 return replace<idx>( r.release() );
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 auto_type replace( size_t idx, U* r ) // strong
|
Chris@16
|
167 {
|
Chris@16
|
168 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
|
Chris@16
|
169
|
Chris@16
|
170 auto_type ptr( r );
|
Chris@16
|
171
|
Chris@16
|
172 BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= N, bad_index,
|
Chris@16
|
173 "'replace()' aout of bounds" );
|
Chris@16
|
174
|
Chris@16
|
175 auto_type res( static_cast<U*>( this->base()[idx] ) ); // nothrow
|
Chris@16
|
176 this->base()[idx] = ptr.release(); // nothrow
|
Chris@16
|
177 return boost::ptr_container::move(res); // nothrow
|
Chris@16
|
178 }
|
Chris@16
|
179
|
Chris@16
|
180 template< class V >
|
Chris@16
|
181 auto_type replace( size_t idx, std::auto_ptr<V> r )
|
Chris@16
|
182 {
|
Chris@16
|
183 return replace( idx, r.release() );
|
Chris@16
|
184 }
|
Chris@16
|
185
|
Chris@16
|
186 using base_class::at;
|
Chris@16
|
187
|
Chris@16
|
188 template< size_t idx >
|
Chris@16
|
189 T& at()
|
Chris@16
|
190 {
|
Chris@16
|
191 BOOST_STATIC_ASSERT( idx < N );
|
Chris@16
|
192 return (*this)[idx];
|
Chris@16
|
193 }
|
Chris@16
|
194
|
Chris@16
|
195 template< size_t idx >
|
Chris@16
|
196 const T& at() const
|
Chris@16
|
197 {
|
Chris@16
|
198 BOOST_STATIC_ASSERT( idx < N );
|
Chris@16
|
199 return (*this)[idx];
|
Chris@16
|
200 }
|
Chris@16
|
201
|
Chris@16
|
202 bool is_null( size_t idx ) const
|
Chris@16
|
203 {
|
Chris@16
|
204 return base_class::is_null(idx);
|
Chris@16
|
205 }
|
Chris@16
|
206
|
Chris@16
|
207 template< size_t idx >
|
Chris@16
|
208 bool is_null() const
|
Chris@16
|
209 {
|
Chris@16
|
210 BOOST_STATIC_ASSERT( idx < N );
|
Chris@16
|
211 return this->base()[idx] == 0;
|
Chris@16
|
212 }
|
Chris@16
|
213 };
|
Chris@16
|
214
|
Chris@16
|
215 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
216 // clonability
|
Chris@16
|
217
|
Chris@16
|
218 template< typename T, size_t size, typename CA >
|
Chris@16
|
219 inline ptr_array<T,size,CA>* new_clone( const ptr_array<T,size,CA>& r )
|
Chris@16
|
220 {
|
Chris@16
|
221 return r.clone().release();
|
Chris@16
|
222 }
|
Chris@16
|
223
|
Chris@16
|
224 /////////////////////////////////////////////////////////////////////////
|
Chris@16
|
225 // swap
|
Chris@16
|
226
|
Chris@16
|
227 template< typename T, size_t size, typename CA >
|
Chris@16
|
228 inline void swap( ptr_array<T,size,CA>& l, ptr_array<T,size,CA>& r )
|
Chris@16
|
229 {
|
Chris@16
|
230 l.swap(r);
|
Chris@16
|
231 }
|
Chris@16
|
232 }
|
Chris@16
|
233
|
Chris@16
|
234 #endif
|