Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / functional / factory / doc / factory.qbk
1 [/
2 Copyright 2007,2008 Tobias Schwinger
3
4 Copyright 2019 Glen Joseph Fernandes
5 (glenjofe@gmail.com)
6
7 Distributed under the Boost Software License, Version 1.0.
8 (http://www.boost.org/LICENSE_1_0.txt)
9 ]
10
11 [library Boost.Functional/Factory
12 [quickbook 1.5]
13 [version 1.0]
14 [authors [Schwinger, Tobias], [Fernandes, Glen]]
15 [copyright 2007 2008 Tobias Schwinger]
16 [copyright 2019 Glen Joseph Fernandes]
17 [license Distributed under the Boost Software License, Version 1.0.]
18 [purpose Function object templates for object creation.]
19 [category higher-order]
20 [category generic]]
21
22 [def __boost__bind__
23 [@http://www.boost.org/libs/bind/bind.html `boost::bind`]]
24
25 [def __boost__forward_adapter__
26 [@http://www.boost.org/libs/functional/forward/doc/index.html
27 `boost::forward_adapter`]]
28
29 [def __boost_function__
30 [@http://www.boost.org/doc/html/function.html Boost.Function]]
31
32 [def __smart_pointer__
33 [@http://www.boost.org/libs/smart_ptr/index.html Smart Pointer]]
34
35 [def __smart_pointers__
36 [@http://www.boost.org/libs/smart_ptr/index.html Smart Pointers]]
37
38 [def __boost__shared_ptr__
39 [@http://www.boost.org/libs/smart_ptr/shared_ptr.htm `boost::shared_ptr`]]
40
41 [def __allocator__ [@https://www.boost.org/sgi/stl/Allocators.html Allocator]]
42
43 [def __std_allocators__
44 [@https://www.boost.org/sgi/stl/Allocators.html Allocators]]
45
46 [def __boost__factory__ `boost::factory`]
47
48 [def __boost__value_factory__ `boost::value_factory`]
49
50 [def __value_factory__ `value_factory`]
51
52 [section Brief Description]
53
54 The template __boost__factory__ lets you encapsulate a `new` expression as a
55 function object, __boost__value_factory__ encapsulates a constructor invocation
56 without `new`.
57
58 ```
59 __boost__factory__<T*>()(arg1,arg2,arg3)
60 // same as new T(arg1,arg2,arg3)
61
62 __boost__value_factory__<T>()(arg1,arg2,arg3)
63 // same as T(arg1,arg2,arg3)
64 ```
65
66 Before C++11 the arguments to the function objects have to be LValues. A
67 factory that also accepts RValues can be composed using the
68 __boost__forward_adapter__ or __boost__bind__. In C++11 or higher the
69 arguments can be LValues or RValues.
70
71 [endsect]
72
73 [section Background]
74
75 In traditional Object Oriented Programming a Factory is an object implementing
76 an interface of one or more methods that construct objects conforming to known
77 interfaces.
78
79 ```
80 // assuming a_concrete_class and another_concrete_class are derived
81 // from an_abstract_class
82
83 struct a_factory {
84     virtual an_abstract_class* create() const = 0;
85     virtual ~a_factory() { }
86 };
87
88 struct a_concrete_factory
89     : a_factory {
90     an_abstract_class* create() const {
91         return new a_concrete_class();
92     }
93 };
94
95 struct another_concrete_factory
96     : a_factory {
97     an_abstract_class* create() const {
98         return new another_concrete_class();
99     }
100 };
101
102 // [...]
103
104 int main()
105 {
106     boost::ptr_map<std::string, a_factory> factories;
107
108     // [...]
109
110     factories.insert("a_name",
111         std::unique_ptr<a_factory>(new a_concrete_factory));
112     factories.insert("another_name",
113         std::unique_ptr<a_factory>(new another_concrete_factory));
114
115     // [...]
116
117     std::unique_ptr<an_abstract_class> x(factories.at(some_name).create());
118
119     // [...]
120 }
121 ```
122
123 This approach has several drawbacks. The most obvious one is that there is lots
124 of boilerplate code. In other words there is too much code to express a rather
125 simple intention. We could use templates to get rid of some of it but the
126 approach remains inflexible:
127
128 * We may want a factory that takes some arguments that are forwarded to the
129 constructor,
130 * we will probably want to use smart pointers,
131 * we may want several member functions to create different kinds of objects,
132 * we might not necessarily need a polymorphic base class for the objects,
133 * as we will see, we do not need a factory base class at all,
134 * we might want to just call the constructor - without `new` to create an
135 object on the stack, and
136 * finally we might want to use customized memory management.
137
138 Experience has shown that using function objects and generic Boost components
139 for their composition, Design Patterns that describe callback mechanisms
140 (typically requiring a high percentage of boilerplate code with pure Object
141 Oriented methodology) become implementable with just few code lines and without
142 extra classes.
143
144 Factories are callback mechanisms for constructors, so we provide two class
145 templates, __boost__value_factory__ and __boost__factory__, that encapsulate
146 object construction via direct application of the constructor and the `new`
147 operator, respectively.
148
149 We let the function objects forward their arguments to the construction
150 expressions they encapsulate. Over this __boost__factory__ optionally allows
151 the use of smart pointers and __std_allocators__.
152
153 Compile-time polymorphism can be used where appropriate,
154
155 ```
156 template<class T>
157 void do_something()
158 {
159     // [...]
160     T x = T(a, b);
161
162     // for conceptually similar objects x we neither need virtual
163     // functions nor a common base class in this context.
164     // [...]
165 }
166 ```
167
168 Now, to allow inhomogeneous signatures for the constructors of the types passed
169 in for `T` we can use __value_factory__ and __boost__bind__ to normalize
170 between them.
171
172 ```
173 template<class ValueFactory>
174 void do_something(ValueFactory make_obj = ValueFactory())
175 {
176     // [...]
177     typename ValueFactory::result_type x = make_obj(a, b);
178
179     // for conceptually similar objects x we neither need virtual
180     // functions nor a common base class in this context.
181     // [...]
182 }
183
184 int main()
185 {
186     // [...]
187
188     do_something(boost::value_factory<X>());
189     do_something(boost::bind(boost::value_factory<Y>(), _1, 5, _2));
190     // construct X(a, b) and Y(a, 5, b), respectively.
191
192     // [...]
193 }
194 ```
195
196 Maybe we want our objects to outlive the function's scope, in this case we have
197 to use dynamic allocation;
198
199 ```
200 template<class Factory>
201 whatever do_something(Factory new_obj = Factory())
202 {
203     typename Factory::result_type ptr = new_obj(a, b);
204
205     // again, no common base class or virtual functions needed,
206     // we could enforce a polymorphic base by writing e.g.
207     //     boost::shared_ptr<base>
208     // instead of
209     //     typename Factory::result_type
210     // above.
211     // Note that we are also free to have the type erasure happen
212     // somewhere else (e.g. in the constructor of this function's
213     // result type).
214
215     // [...]
216 }
217
218 // [... call do_something like above but with boost::factory instead
219 // of boost::value_factory]
220 ```
221
222 Although we might have created polymorphic objects in the previous example, we
223 have used compile time polymorphism for the factory. If we want to erase the
224 type of the factory and thus allow polymorphism at run time, we can use
225 __boost_function__ to do so. The first example can be rewritten as follows.
226
227 ```
228 typedef boost::function<an_abstract_class*()> a_factory;
229
230 // [...]
231
232 int main()
233 {
234     std::map<std::string, a_factory> factories;
235
236     // [...]
237
238     factories["a_name"] = boost::factory<a_concrete_class*>();
239     factories["another_name"] = boost::factory<another_concrete_class*>();
240
241     // [...]
242 }
243 ```
244
245 Of course we can just as easy create factories that take arguments and/or
246 return __smart_pointers__.
247
248 [endsect]
249
250 [section:reference Reference]
251
252 [section value_factory]
253
254 [heading Description]
255
256 Function object template that invokes the constructor of the type `T`.
257
258 [heading Header]
259
260 ```
261 #include <boost/functional/value_factory.hpp>
262 ```
263
264 [heading Synopsis]
265
266 ```
267 namespace boost {
268
269 template<class T>
270 class value_factory;
271
272 } // boost
273 ```
274
275 [variablelist Notation
276 [[`T`][an arbitrary type with at least one public constructor]]
277 [[`a0`...`aN`][argument values to a constructor of `T`]]
278 [[`F`][the type `value_factory<F>`]]
279 [[`f`][an instance object of `F`]]]
280
281 [heading Expression Semantics]
282
283 [table
284 [[Expression][Semantics]]
285 [[`F()`][creates an object of type `F`.]]
286 [[`F(f)`][creates an object of type `F`.]]
287 [[`f(a0`...`aN)`][returns `T(a0`...`aN)`.]]
288 [[`F::result_type`][is the type `T`.]]]
289
290 [heading Limits]
291
292 Before C++11, the maximum number of arguments supported is 10. Since C++11 an
293 arbitrary number of arguments is supported.
294
295 [endsect]
296
297 [section factory]
298
299 [heading Description]
300
301 Function object template that dynamically constructs a pointee object for the
302 type of pointer given as template argument. Smart pointers may be used for the
303 template argument, given that `pointer_traits<Pointer>::element_type` yields
304 the pointee type.
305
306 If an __allocator__ is given, it is used for memory allocation and the
307 placement form of the `new` operator is used to construct the object. A
308 function object that calls the destructor and deallocates the memory with a
309 copy of the Allocator is used for the second constructor argument of `Pointer`
310 (thus it must be a __smart_pointer__ that provides a suitable constructor,
311 such as __boost__shared_ptr__).
312
313 If a third template argument is `factory_passes_alloc_to_smart_pointer`, the
314 allocator itself is used for the third constructor argument of `Pointer`
315 (__boost__shared_ptr__ then uses the allocator to manage the memory of its
316 separately allocated reference counter).
317
318 [heading Header]
319
320 ```
321 #include <boost/functional/factory.hpp>
322 ```
323
324 [heading Synopsis]
325
326 ```
327 namespace boost {
328
329 enum factory_alloc_propagation {
330     factory_alloc_for_pointee_and_deleter,
331     factory_passes_alloc_to_smart_pointer
332 };
333
334 template<class Pointer,
335     class Allocator = void,
336     factory_alloc_propagation Policy = factory_alloc_for_pointee_and_deleter>
337 class factory;
338
339 } // boost
340 ```
341
342 [variablelist Notation
343 [[`T`][an arbitrary type with at least one public constructor]]
344 [[`P`][pointer or smart pointer to `T`]]
345 [[`a0`...`aN`][argument values to a constructor of `T`]]
346 [[`F`][the type `factory<P>`]]
347 [[`f`][an instance object of `F`]]]
348
349 [heading Expression Semantics]
350
351 [table
352 [[Expression][Semantics]]
353 [[`F()`][creates an object of type `F`.]]
354 [[`F(f)`][creates an object of type `F`.]]
355 [[`f(a0`...`aN)`]
356 [dynamically creates an object of type `T` using `a0`...`aN` as arguments for
357 the constructor invocation.]]
358 [[`F::result_type`][is the type `P` with top-level cv-qualifiers removed.]]]
359
360 [heading Limits]
361
362 Before C++11, the maximum number of arguments supported is 10. Since C++11 an
363 arbitrary number of arguments is supported.
364
365 [endsect]
366
367 [endsect]
368
369 [section Changes]
370
371 [heading Boost 1.72.0]
372
373 Glen Fernandes rewrote the implementations of `factory` and `value_factory` to
374 provide the following features:
375
376 * Support r-value arguments when available
377 * Support arbitrary number of arguments via variadic templates when available
378 * Support allocators that are final
379 * Support allocators that use fancy pointers
380 * Support for disabled exceptions (`BOOST_NO_EXCEPTIONS`)
381 * Improved compilation times
382
383 The following features have been removed:
384
385 * Increasing limits for C++03 compilers through
386   `BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY`
387 * Using `boost::none_t` in place of `void` through
388   `BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T`
389
390 [heading Boost 1.58.0]
391
392 In order to remove the dependency on Boost.Optional, the default parameter for
393 allocators has been changed from `boost::none_t` to `void`. If you have code
394 that has stopped working because it uses `boost::none_t`, a quick fix is to
395 define `BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T`, which will restore support,
396 but this will be removed in a future release. It should be be relatively easy
397 to fix this properly.
398
399 [endsect]
400
401 [section Acknowledgements]
402
403 Tobias Schwinger for creating this library.
404
405 Eric Niebler requested a function to invoke a type's constructor (with the
406 arguments supplied as a Tuple) as a Fusion feature. These Factory utilities are
407 a factored-out generalization of this idea.
408
409 Dave Abrahams suggested Smart Pointer support for exception safety, providing
410 useful hints for the implementation.
411
412 Joel de Guzman's documentation style was copied from Fusion.
413
414 Peter Dimov for sharing his insights on language details and their evolution.
415
416 [endsect]
417
418 [section References]
419
420 # [@http://en.wikipedia.org/wiki/Design_Patterns Design Patterns],
421 Gamma et al. - Addison Wesley Publishing, 1995
422
423 # [@https://boost.org/sgi/stl/ Standard Template Library Programmer's Guide],
424 Hewlett-Packard Company, 1994
425
426 # [@http://www.boost.org/libs/bind/bind.html Boost.Bind],
427 Peter Dimov, 2001-2005
428
429 # [@http://www.boost.org/doc/html/function.html Boost.Function],
430 Douglas Gregor, 2001-2004
431
432 [endsect]