2 Copyright 2007,2008 Tobias Schwinger
4 Copyright 2019 Glen Joseph Fernandes
7 Distributed under the Boost Software License, Version 1.0.
8 (http://www.boost.org/LICENSE_1_0.txt)
11 [library Boost.Functional/Factory
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]
23 [@http://www.boost.org/libs/bind/bind.html `boost::bind`]]
25 [def __boost__forward_adapter__
26 [@http://www.boost.org/libs/functional/forward/doc/index.html
27 `boost::forward_adapter`]]
29 [def __boost_function__
30 [@http://www.boost.org/doc/html/function.html Boost.Function]]
32 [def __smart_pointer__
33 [@http://www.boost.org/libs/smart_ptr/index.html Smart Pointer]]
35 [def __smart_pointers__
36 [@http://www.boost.org/libs/smart_ptr/index.html Smart Pointers]]
38 [def __boost__shared_ptr__
39 [@http://www.boost.org/libs/smart_ptr/shared_ptr.htm `boost::shared_ptr`]]
41 [def __allocator__ [@https://www.boost.org/sgi/stl/Allocators.html Allocator]]
43 [def __std_allocators__
44 [@https://www.boost.org/sgi/stl/Allocators.html Allocators]]
46 [def __boost__factory__ `boost::factory`]
48 [def __boost__value_factory__ `boost::value_factory`]
50 [def __value_factory__ `value_factory`]
52 [section Brief Description]
54 The template __boost__factory__ lets you encapsulate a `new` expression as a
55 function object, __boost__value_factory__ encapsulates a constructor invocation
59 __boost__factory__<T*>()(arg1,arg2,arg3)
60 // same as new T(arg1,arg2,arg3)
62 __boost__value_factory__<T>()(arg1,arg2,arg3)
63 // same as T(arg1,arg2,arg3)
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.
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
80 // assuming a_concrete_class and another_concrete_class are derived
81 // from an_abstract_class
84 virtual an_abstract_class* create() const = 0;
85 virtual ~a_factory() { }
88 struct a_concrete_factory
90 an_abstract_class* create() const {
91 return new a_concrete_class();
95 struct another_concrete_factory
97 an_abstract_class* create() const {
98 return new another_concrete_class();
106 boost::ptr_map<std::string, a_factory> factories;
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));
117 std::unique_ptr<an_abstract_class> x(factories.at(some_name).create());
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:
128 * We may want a factory that takes some arguments that are forwarded to the
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.
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
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.
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__.
153 Compile-time polymorphism can be used where appropriate,
162 // for conceptually similar objects x we neither need virtual
163 // functions nor a common base class in this context.
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
173 template<class ValueFactory>
174 void do_something(ValueFactory make_obj = ValueFactory())
177 typename ValueFactory::result_type x = make_obj(a, b);
179 // for conceptually similar objects x we neither need virtual
180 // functions nor a common base class in this context.
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.
196 Maybe we want our objects to outlive the function's scope, in this case we have
197 to use dynamic allocation;
200 template<class Factory>
201 whatever do_something(Factory new_obj = Factory())
203 typename Factory::result_type ptr = new_obj(a, b);
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>
209 // typename Factory::result_type
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
218 // [... call do_something like above but with boost::factory instead
219 // of boost::value_factory]
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.
228 typedef boost::function<an_abstract_class*()> a_factory;
234 std::map<std::string, a_factory> factories;
238 factories["a_name"] = boost::factory<a_concrete_class*>();
239 factories["another_name"] = boost::factory<another_concrete_class*>();
245 Of course we can just as easy create factories that take arguments and/or
246 return __smart_pointers__.
250 [section:reference Reference]
252 [section value_factory]
254 [heading Description]
256 Function object template that invokes the constructor of the type `T`.
261 #include <boost/functional/value_factory.hpp>
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`]]]
281 [heading Expression Semantics]
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`.]]]
292 Before C++11, the maximum number of arguments supported is 10. Since C++11 an
293 arbitrary number of arguments is supported.
299 [heading Description]
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
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__).
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).
321 #include <boost/functional/factory.hpp>
329 enum factory_alloc_propagation {
330 factory_alloc_for_pointee_and_deleter,
331 factory_passes_alloc_to_smart_pointer
334 template<class Pointer,
335 class Allocator = void,
336 factory_alloc_propagation Policy = factory_alloc_for_pointee_and_deleter>
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`]]]
349 [heading Expression Semantics]
352 [[Expression][Semantics]]
353 [[`F()`][creates an object of type `F`.]]
354 [[`F(f)`][creates an object of type `F`.]]
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.]]]
362 Before C++11, the maximum number of arguments supported is 10. Since C++11 an
363 arbitrary number of arguments is supported.
371 [heading Boost 1.72.0]
373 Glen Fernandes rewrote the implementations of `factory` and `value_factory` to
374 provide the following features:
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
383 The following features have been removed:
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`
390 [heading Boost 1.58.0]
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.
401 [section Acknowledgements]
403 Tobias Schwinger for creating this library.
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.
409 Dave Abrahams suggested Smart Pointer support for exception safety, providing
410 useful hints for the implementation.
412 Joel de Guzman's documentation style was copied from Fusion.
414 Peter Dimov for sharing his insights on language details and their evolution.
420 # [@http://en.wikipedia.org/wiki/Design_Patterns Design Patterns],
421 Gamma et al. - Addison Wesley Publishing, 1995
423 # [@https://boost.org/sgi/stl/ Standard Template Library Programmer's Guide],
424 Hewlett-Packard Company, 1994
426 # [@http://www.boost.org/libs/bind/bind.html Boost.Bind],
427 Peter Dimov, 2001-2005
429 # [@http://www.boost.org/doc/html/function.html Boost.Function],
430 Douglas Gregor, 2001-2004