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