• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 namespace 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 
ptr_array_impl(Allocator=Allocator ())45             ptr_array_impl( Allocator /*a*/ = Allocator() )
46             {
47                 this->assign( 0 );
48             }
49 
ptr_array_impl(size_t,T *,Allocator=Allocator ())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
ptr_array()91         ptr_array() : base_class()
92         { }
93 
ptr_array(const ptr_array & r)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 >
ptr_array(const ptr_array<U,N> & r)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
ptr_array(std::auto_ptr<this_type> r)112         explicit ptr_array( std::auto_ptr<this_type> r )
113         : base_class( r ) { }
114 #endif
115 #ifndef BOOST_NO_CXX11_SMART_PTR
ptr_array(std::unique_ptr<this_type> r)116         explicit ptr_array( std::unique_ptr<this_type> r )
117         : base_class( std::move( r ) ) { }
118 #endif
119 
operator =(ptr_array r)120         ptr_array& operator=( ptr_array r )
121         {
122             this->swap( r );
123             return *this;
124         }
125 
126 #ifndef BOOST_NO_AUTO_PTR
operator =(std::auto_ptr<this_type> r)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
operator =(std::unique_ptr<this_type> r)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
release()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 
clone() const149         std::auto_ptr<this_type> clone() const
150         {
151             std::auto_ptr<this_type> pa( new this_type );
152             clone_array_elements( *pa );
153             return pa;
154         }
155 #else
release()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 
clone() const163         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:
clone_array_elements(this_type & pa) const171         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 >
replace(U * r)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 >
replace(std::auto_ptr<V> r)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 >
replace(std::unique_ptr<V> r)212         auto_type replace( std::unique_ptr<V> r )
213         {
214             return replace<idx>( r.release() );
215         }
216 #endif
217 
replace(size_t idx,U * r)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 >
replace(size_t idx,std::auto_ptr<V> r)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 >
replace(size_t idx,std::unique_ptr<V> r)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 >
at()249         T& at()
250         {
251             BOOST_STATIC_ASSERT( idx < N );
252             return (*this)[idx];
253         }
254 
255         template< size_t idx >
at() const256         const T& at() const
257         {
258             BOOST_STATIC_ASSERT( idx < N );
259             return (*this)[idx];
260         }
261 
is_null(size_t idx) const262         bool is_null( size_t idx ) const
263         {
264             return base_class::is_null(idx);
265         }
266 
267         template< size_t idx >
is_null() const268         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 >
new_clone(const ptr_array<T,size,CA> & r)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 >
swap(ptr_array<T,size,CA> & l,ptr_array<T,size,CA> & r)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