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