]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | ++++++++++++++++++++++++++++++++++ | |
3 | |Boost| Pointer Container Library | |
4 | ++++++++++++++++++++++++++++++++++ | |
5 | ||
6 | .. |Boost| image:: boost.png | |
7 | ||
8 | ||
9 | ||
10 | :Authors: Thorsten Ottosen | |
11 | :Contact: nesotto@cs.aau.dk or tottosen@dezide.com | |
12 | :Organizations: `Department of Computer Science`_, Aalborg University, and `Dezide Aps`_ | |
13 | :date: 27th of October 2007 | |
14 | :Copyright: Thorsten Ottosen 2004-2007. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt__). | |
15 | ||
16 | __ http://www.boost.org/LICENSE_1_0.txt | |
17 | ||
18 | .. _`Department of Computer Science`: http://www.cs.aau.dk | |
19 | .. _`Dezide Aps`: http://www.dezide.com | |
20 | ||
21 | ======== | |
22 | Overview | |
23 | ======== | |
24 | ||
25 | Boost.Pointer Container provides containers for holding heap-allocated | |
26 | objects in an exception-safe manner and with minimal overhead. | |
27 | The aim of the library is in particular to make OO programming | |
28 | easier in C++ by establishing a standard set of classes, methods | |
29 | and designs for dealing with OO specific problems | |
30 | ||
31 | * Motivation_ | |
32 | * Tutorial_ | |
33 | * Reference_ | |
34 | * `Usage guidelines`_ | |
35 | * Examples_ | |
36 | * `Library headers`_ | |
37 | * FAQ_ | |
38 | * `Upgrading from Boost v. 1.33.*`_ | |
39 | * `Upgrading from Boost v. 1.34.*`_ | |
40 | * `Upgrading from Boost v. 1.35.*`_ | |
41 | * `Future Developments`_ | |
42 | * Acknowledgements_ | |
43 | * References_ | |
44 | ||
45 | .. | |
46 | - `Conventions <conventions.html>`_ | |
47 | - `The Clonable Concept <reference.html#the-clonable-concept>`_ | |
48 | - `The Clone Allocator Concept <reference.html#the-clone-allocator-concept>`_ | |
49 | - `Pointer container adapters <reference.html#pointer-container-adapters>`_ | |
50 | - `Sequence container classes <reference.html#sequence-containers>`_ | |
51 | ||
52 | - `ptr_vector <ptr_vector.html>`_ | |
53 | - `ptr_deque <ptr_deque.html>`_ | |
54 | - `ptr_list <ptr_list.html>`_ | |
55 | - `ptr_array <ptr_array.html>`_ | |
56 | - `Associative container classes <reference.html#associative-containers>`_ | |
57 | ||
58 | - `ptr_set <ptr_set.html>`_ | |
59 | - `ptr_multiset <ptr_multiset.html>`_ | |
60 | - `ptr_map <ptr_map.html>`_ | |
61 | - `ptr_multimap <ptr_multimap.html>`_ | |
62 | - `Indirected functions <indirect_fun.html>`_ | |
63 | - `Class nullable <reference.html#class-nullable>`_ | |
64 | - `Exception classes <reference.html#exception-classes>`_ | |
65 | ||
66 | ||
67 | ||
68 | .. _Tutorial: tutorial.html | |
69 | ||
70 | ||
71 | .. _Reference: reference.html | |
72 | ||
73 | .. _`Usage guidelines`: guidelines.html | |
74 | ||
75 | .. _Examples: examples.html | |
76 | ||
77 | .. _`Library headers`: headers.html | |
78 | ||
79 | .. _FAQ: faq.html | |
80 | ||
81 | ||
82 | ========== | |
83 | Motivation | |
84 | ========== | |
85 | ||
86 | Whenever a programmer wants to have a container of pointers to | |
87 | heap-allocated objects, there is usually only one exception-safe way: | |
88 | to make a container of smart pointers like `boost::shared_ptr <../../smart_ptr/shared_ptr.htm>`_ | |
89 | This approach is suboptimal if | |
90 | ||
91 | 1. the stored objects are not shared, but owned exclusively, or | |
92 | ||
93 | .. | |
94 | ||
95 | 2. the overhead implied by smart pointers is inappropriate | |
96 | ||
97 | This library therefore provides standard-like containers that are for storing | |
98 | heap-allocated or `cloned <reference.html#the-clonable-concept>`_ objects (or in case of a map, the mapped object must be | |
99 | a heap-allocated or cloned object). For each of the standard | |
100 | containers there is a pointer container equivalent that takes ownership of | |
101 | the objects in an exception safe manner. In this respect the library is intended | |
102 | to solve the so-called | |
103 | `polymorphic class problem <faq.html#what-is-the-polymorphic-class-problem>`_. | |
104 | ||
105 | ||
106 | The advantages of pointer containers are | |
107 | ||
108 | 1. Exception-safe pointer storage and manipulation. | |
109 | ||
110 | .. | |
111 | ||
112 | 2. Notational convenience compared to the use of containers of pointers. | |
113 | ||
114 | .. | |
115 | ||
116 | 3. Can be used for types that are neither Assignable nor Copy Constructible. | |
117 | ||
118 | .. | |
119 | ||
120 | 4. No memory-overhead as containers of smart pointers can have (see [11]_ and [12]_). | |
121 | ||
122 | .. | |
123 | ||
124 | 5. Usually faster than using containers of smart pointers (see [11]_ and [12]_). | |
125 | ||
126 | .. | |
127 | ||
128 | 6. The interface is slightly changed towards the domain of pointers | |
129 | instead of relying on the normal value-based interface. For example, | |
130 | now it is possible for ``pop_back()`` to return the removed element. | |
131 | ||
132 | .. | |
133 | ||
134 | 7. Propagates constness such that one cannot modify the objects via a ``const_iterator``. | |
135 | ||
136 | .. | |
137 | ||
138 | 8. Built-in support for deep-copy semantics via the `the Clonable concept`__ | |
139 | ||
140 | .. __: reference.html#the-clonable-concept | |
141 | ||
142 | The disadvantages are | |
143 | ||
144 | 1. Less flexible than containers of smart pointers like `boost::shared_ptr <../../smart_ptr/shared_ptr.htm>`_ | |
145 | ||
146 | When you do need shared semantics, this library is not what you need. | |
147 | ||
148 | ==================================== | |
149 | Upgrading from Boost v. ``1.33.*`` | |
150 | ==================================== | |
151 | ||
152 | If you upgrade from one of these versions of Boost, then there has been one | |
153 | major interface change: map iterators now mimic iterators from ``std::map``. | |
154 | Previously you may have written :: | |
155 | ||
156 | for( boost::ptr_map<std::string,T>::iterator i = m.begin(), e = m.end(); | |
157 | i != e; ++i ) | |
158 | { | |
159 | std::cout << "key:" << i.key(); | |
160 | std::cout << "value:" << *i; | |
161 | i->foo(); // call T::foo() | |
162 | } | |
163 | ||
164 | and this now needs to be converted into :: | |
165 | ||
166 | for( boost::ptr_map<std::string,T>::iterator i = m.begin(), e = m.end(); | |
167 | i != e; ++i ) | |
168 | { | |
169 | std::cout << "key:" << i->first; | |
170 | std::cout << "value:" << *i->second; | |
171 | i->second->foo(); // call T::foo() | |
172 | } | |
173 | ||
174 | Apart from the above change, the library now also introduces | |
175 | ||
176 | - ``std::auto_ptr<T>`` overloads:: | |
177 | ||
178 | std::auto_ptr<T> p( new T ); | |
179 | container.push_back( p ); | |
180 | ||
181 | - Derived-to-Base conversion in ``transfer()``:: | |
182 | ||
183 | boost::ptr_vector<Base> vec; | |
184 | boost::ptr_list<Derived> list; | |
185 | ... | |
186 | vec.transfer( vec.begin(), list ); // now ok | |
187 | ||
188 | Also note that `Boost.Assign <../../assign/index.html>`_ introduces better support | |
189 | for pointer containers. | |
190 | ||
191 | ==================================== | |
192 | Upgrading from Boost v. ``1.34.*`` | |
193 | ==================================== | |
194 | ||
195 | Serialization has now been made optional thanks to Sebastian Ramacher. | |
196 | You simply include ``<boost/ptr_container/serialize.hpp>`` or perhaps | |
197 | just one of the more specialized headers. | |
198 | ||
199 | All containers are now copy-constructible and assignable. So you can e.g. now | |
200 | do:: | |
201 | ||
202 | boost::ptr_vector<Derived> derived = ...; | |
203 | boost::ptr_vector<Base> base( derived ); | |
204 | base = derived; | |
205 | ||
206 | As the example shows, derived-to-base class conversions are also allowed. | |
207 | ||
208 | A few general functions have been added:: | |
209 | ||
210 | VoidPtrContainer& base(); | |
211 | const VoidPtrContainer& base() const; | |
212 | ||
213 | These allow direct access to the wrapped container which is | |
214 | sometimes needed when you want to provide extra functionality. | |
215 | ||
216 | A few new functions have been added to sequences:: | |
217 | ||
218 | void resize( size_type size ); | |
219 | void resize( size_type size, T* to_clone ); | |
220 | ||
221 | ``ptr_vector<T>`` has a few new helper functions to integrate better with C-arrays:: | |
222 | ||
223 | void transfer( iterator before, T** from, size_type size, bool delete_from = true ); | |
224 | T** c_array(); | |
225 | ||
226 | Finally, you can now also "copy" and "assign" an ``auto_type`` ptr by calling ``move()``:: | |
227 | ||
228 | boost::ptr_vector<T>::auto_type move_ptr = ...; | |
229 | return boost::ptr_container::move( move_ptr ); | |
230 | ||
231 | ==================================== | |
232 | Upgrading from Boost v. ``1.35.*`` | |
233 | ==================================== | |
234 | ||
235 | The library has been fairly stable, but a few new containers have been supported: | |
236 | ||
237 | - ``boost::ptr_unordered_set<T>`` in ``<boost/ptr_container/ptr_unordered_set.hpp>`` | |
238 | ||
239 | - ``boost::ptr_unordered_map<Key,T>`` in ``<boost/ptr_container/ptr_unordered_map.hpp>`` | |
240 | ||
241 | - ``boost::ptr_circular_buffer<T>`` in ``<boost/ptr_container/ptr_circular_buffer.hpp>`` | |
242 | ||
243 | There are no docs for these classes yet, but they are almost identical to | |
244 | ``boost::ptr_set<T>``, ``boost::ptr_map<Key,T>`` and ``boost::ptr_array<T,N>``, respectively. | |
245 | The underlying containers stem from the two boost libraries | |
246 | ||
247 | - `Boost.Unordered <../../unordered/index.html>`_ | |
248 | ||
249 | - `Boost.Circular Buffer <../../circular_buffer/index.html>`_ | |
250 | ||
251 | Furthermore, `insert iterators <ptr_inserter.html>`_ have been added. | |
252 | ||
253 | ===================== | |
254 | Future Developments | |
255 | ===================== | |
256 | ||
257 | There are indications that the ``void*`` implementation has a slight | |
258 | performance overhead compared to a ``T*`` based implementation. Furthermore, a | |
259 | ``T*`` based implementation is so much easier to use type-safely | |
260 | with algorithms. Therefore I anticipate to move to a ``T*`` based implementation. | |
261 | ||
262 | Furthermore, the clone allocator might be allowed to have state. | |
263 | This design requires some thought, so if you have good ideas and use-cases' | |
264 | for this, please don't hesitate to contact me. | |
265 | ||
266 | Also, support for Boost.Interprocess is on the todo list. | |
267 | ||
268 | There has been a few request for ``boost::ptr_multi_index_container<T,...>``. | |
269 | I investigated how difficult it would be, and it did turn out to be difficult, albeit | |
270 | not impossible. But I don't have the resources to implement this beast | |
271 | for years to come, so if someone really needs this container, I suggest that they | |
272 | talk with me in private about how it can be done. | |
273 | ||
274 | ================ | |
275 | Acknowledgements | |
276 | ================ | |
277 | ||
278 | The following people have been very helpful: | |
279 | ||
280 |