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
12#ifndef BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
13#define BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
14
15#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16# pragma once
17#endif
18
19#include <boost/array.hpp>
20#include <boost/static_assert.hpp>
21#include <boost/ptr_container/ptr_sequence_adapter.hpp>
22#include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
23
24#if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
25#pragma GCC diagnostic push
26#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
27#endif
28
29namespace boost
30{
31
32 namespace ptr_container_detail
33 {
34 template
35 <
36 class T,
37 size_t N,
38 class Allocator = int // dummy
39 >
40 class ptr_array_impl : public boost::array<T,N>
41 {
42 public:
43 typedef Allocator allocator_type;
44
45 ptr_array_impl( Allocator /*a*/ = Allocator() )
46 {
47 this->assign( 0 );
48 }
49
50 ptr_array_impl( size_t, T*, Allocator /*a*/ = Allocator() )
51 {
52 this->assign( 0 );
53 }
54 };
55 }
56
57 template
58 <
59 class T,
60 size_t N,
61 class CloneAllocator = heap_clone_allocator
62 >
63 class ptr_array : public
64 ptr_sequence_adapter< T,
65 ptr_container_detail::ptr_array_impl<
66 typename ptr_container_detail::void_ptr<T>::type,N>,
67 CloneAllocator >
68 {
69 private:
70 typedef ptr_sequence_adapter< T,
71 ptr_container_detail::ptr_array_impl<
72 typename ptr_container_detail::void_ptr<T>::type,N>,
73 CloneAllocator >
74 base_class;
75
76 typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type U;
77
78 typedef ptr_array<T,N,CloneAllocator>
79 this_type;
80
81 public:
82 typedef std::size_t size_type;
83 typedef U* value_type;
84 typedef U* pointer;
85 typedef U& reference;
86 typedef const U& const_reference;
87 typedef BOOST_DEDUCED_TYPENAME base_class::auto_type
88 auto_type;
89
90 public: // constructors
91 ptr_array() : base_class()
92 { }
93
94 ptr_array( const ptr_array& r )
95 {
96 size_t i = 0;
97 for( ; i != N; ++i )
98 this->base()[i] = this->null_policy_allocate_clone(
99 static_cast<const U*>( &r[i] ) );
100 }
101
102 template< class U >
103 ptr_array( const ptr_array<U,N>& r )
104 {
105 size_t i = 0;
106 for( ; i != N; ++i )
107 this->base()[i] = this->null_policy_allocate_clone(
108 static_cast<const T*>( &r[i] ) );
109 }
110
111#ifndef BOOST_NO_AUTO_PTR
112 explicit ptr_array( std::auto_ptr<this_type> r )
113 : base_class( r ) { }
114#endif
115#ifndef BOOST_NO_CXX11_SMART_PTR
116 explicit ptr_array( std::unique_ptr<this_type> r )
117 : base_class( std::move( r ) ) { }
118#endif
119
120 ptr_array& operator=( ptr_array r )
121 {
122 this->swap( r );
123 return *this;
124 }
125
126#ifndef BOOST_NO_AUTO_PTR
127 ptr_array& operator=( std::auto_ptr<this_type> r )
128 {
129 base_class::operator=(r);
130 return *this;
131 }
132#endif
133#ifndef BOOST_NO_CXX11_SMART_PTR
134 ptr_array& operator=( std::unique_ptr<this_type> r )
135 {
136 base_class::operator=(std::move(r));
137 return *this;
138 }
139#endif
140
141#ifndef BOOST_NO_AUTO_PTR
142 std::auto_ptr<this_type> release()
143 {
144 std::auto_ptr<this_type> ptr( new this_type );
145 this->swap( *ptr );
146 return ptr;
147 }
148
149 std::auto_ptr<this_type> clone() const
150 {
151 std::auto_ptr<this_type> pa( new this_type );
152 clone_array_elements( pa&: *pa );
153 return pa;
154 }
155#else
156 std::unique_ptr<this_type> release()
157 {
158 std::unique_ptr<this_type> ptr( new this_type );
159 this->swap( *ptr );
160 return ptr;
161 }
162
163 std::unique_ptr<this_type> clone() const
164 {
165 std::unique_ptr<this_type> pa( new this_type );
166 clone_array_elements( *pa );
167 return pa;
168 }
169#endif
170 private:
171 void clone_array_elements( this_type &pa ) const
172 {
173 for( size_t i = 0; i != N; ++i )
174 {
175 if( !this->is_null(i) )
176 pa.replace( i, pa.null_policy_allocate_clone( &(*this)[i] ) );
177 }
178 }
179
180 private: // hide some members
181 using base_class::insert;
182 using base_class::erase;
183 using base_class::push_back;
184 using base_class::push_front;
185 using base_class::pop_front;
186 using base_class::pop_back;
187 using base_class::transfer;
188 using base_class::get_allocator;
189
190 public: // compile-time interface
191
192 template< size_t idx >
193 auto_type replace( U* r ) // strong
194 {
195 BOOST_STATIC_ASSERT( idx < N );
196
197 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
198 auto_type res( static_cast<U*>(this->base()[idx]), *this ); // nothrow
199 this->base()[idx] = r; // nothrow
200 return boost::ptr_container::move(res); // nothrow
201 }
202
203#ifndef BOOST_NO_AUTO_PTR
204 template< size_t idx, class V >
205 auto_type replace( std::auto_ptr<V> r )
206 {
207 return replace<idx>( r.release() );
208 }
209#endif
210#ifndef BOOST_NO_CXX11_SMART_PTR
211 template< size_t idx, class V >
212 auto_type replace( std::unique_ptr<V> r )
213 {
214 return replace<idx>( r.release() );
215 }
216#endif
217
218 auto_type replace( size_t idx, U* r ) // strong
219 {
220 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
221
222 auto_type ptr( r, *this );
223 BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= N, bad_index,
224 "'replace()' aout of bounds" );
225
226 auto_type res( static_cast<U*>(this->base()[idx]), *this ); // nothrow
227 this->base()[idx] = ptr.release(); // nothrow
228 return boost::ptr_container::move(res); // nothrow
229 }
230
231#ifndef BOOST_NO_AUTO_PTR
232 template< class V >
233 auto_type replace( size_t idx, std::auto_ptr<V> r )
234 {
235 return replace( idx, r.release() );
236 }
237#endif
238#ifndef BOOST_NO_CXX11_SMART_PTR
239 template< class V >
240 auto_type replace( size_t idx, std::unique_ptr<V> r )
241 {
242 return replace( idx, r.release() );
243 }
244#endif
245
246 using base_class::at;
247
248 template< size_t idx >
249 T& at()
250 {
251 BOOST_STATIC_ASSERT( idx < N );
252 return (*this)[idx];
253 }
254
255 template< size_t idx >
256 const T& at() const
257 {
258 BOOST_STATIC_ASSERT( idx < N );
259 return (*this)[idx];
260 }
261
262 bool is_null( size_t idx ) const
263 {
264 return base_class::is_null(idx);
265 }
266
267 template< size_t idx >
268 bool is_null() const
269 {
270 BOOST_STATIC_ASSERT( idx < N );
271 return this->base()[idx] == 0;
272 }
273 };
274
275 //////////////////////////////////////////////////////////////////////////////
276 // clonability
277
278 template< typename T, size_t size, typename CA >
279 inline ptr_array<T,size,CA>* new_clone( const ptr_array<T,size,CA>& r )
280 {
281 return r.clone().release();
282 }
283
284 /////////////////////////////////////////////////////////////////////////
285 // swap
286
287 template< typename T, size_t size, typename CA >
288 inline void swap( ptr_array<T,size,CA>& l, ptr_array<T,size,CA>& r )
289 {
290 l.swap(r);
291 }
292}
293
294#if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
295#pragma GCC diagnostic pop
296#endif
297
298#endif
299

source code of boost/libs/ptr_container/include/boost/ptr_container/ptr_array.hpp