diff --git a/boost_1_62_0/libs/functional/factory/doc/html/index.html b/boost_1_62_0/libs/functional/factory/doc/html/index.html new file mode 100644 index 0000000..7069238 --- /dev/null +++ b/boost_1_62_0/libs/functional/factory/doc/html/index.html @@ -0,0 +1,640 @@ + +
+ +![]() |
+Home | +Libraries | +People | +FAQ | +More | +
Copyright © 2007, 2008 Tobias Schwinger
+ Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +
+Table of Contents
+ +
+ The template boost::factory lets you encapsulate a new expression as a function object, boost::value_factory
+ encapsulates a constructor invocation without new.
+
+boost::factory<T*>()(arg1,arg2,arg3) +// same as new T(arg1,arg2,arg3) + +boost::value_factory<T>()(arg1,arg2,arg3) +// same as T(arg1,arg2,arg3) +
+ For technical reasons the arguments to the function objects have to be LValues.
+ A factory that also accepts RValues can be composed using the boost::forward_adapter
+ or boost::bind.
+
+ In traditional Object Oriented Programming a Factory is an object implementing + an interface of one or more methods that construct objects conforming to known + interfaces. +
+// assuming a_concrete_class and another_concrete_class are derived +// from an_abstract_class + +class a_factory +{ + public: + virtual an_abstract_class* create() const = 0; + virtual ~a_factory() { } +}; + +class a_concrete_factory : public a_factory +{ + public: + virtual an_abstract_class* create() const + { + return new a_concrete_class(); + } +}; + +class another_concrete_factory : public a_factory +{ + public: + virtual an_abstract_class* create() const + { + return new another_concrete_class(); + } +}; + +// [...] + +int main() +{ ++boost::ptr_map<std::string,a_factory> factories; + + // [...] + + factories.insert("a_name",std::auto_ptr<a_factory>( + new a_concrete_factory)); + factories.insert("another_name",std::auto_ptr<a_factory>( + new another_concrete_factory)); + + // [...] + + std::auto_ptr<an_abstract_class> x(factories.at(some_name).create()); + + // [...] +} +
+ This approach has several drawbacks. The most obvious one is that there is + lots of boilerplate code. In other words there is too much code to express + a rather simple intention. We could use templates to get rid of some of it + but the approach remains inflexible: +
+new
+ to create an object on the stack, and
+ + Experience has shown that using function objects and generic Boost components + for their composition, Design Patterns that describe callback mechanisms (typically + requiring a high percentage of boilerplate code with pure Object Oriented methodology) + become implementable with just few code lines and without extra classes. +
+
+ Factories are callback mechanisms for constructors, so we provide two class
+ templates, boost::value_factory and boost::factory,
+ that encapsulate object construction via direct application of the constructor
+ and the new operator, respectively.
+
+ We let the function objects forward their arguments to the construction expressions
+ they encapsulate. Over this boost::factory
+ optionally allows the use of smart pointers and Allocators.
+
+ Compile-time polymorphism can be used where appropriate, +
+template< class T > +void do_something() +{ + // [...] + T x = T(a,b); + + // for conceptually similar objects x we neither need virtual + // functions nor a common base class in this context. + // [...] +} ++
+ Now, to allow inhomogeneous signatures for the constructors of the types passed
+ in for T we can use value_factory and boost::bind
+ to normalize between them.
+
template< class ValueFactory > +void do_something(ValueFactory make_obj = ValueFactory()) +{ + // [...] + typename ValueFactory::result_type x = make_obj(a,b); + + // for conceptually similar objects x we neither need virtual + // functions nor a common base class in this context. + // [...] +} + +int main() +{ + // [...] + + do_something(+boost::value_factory<X>()); + do_something(boost::bind(boost::value_factory<Y>(),_1,5,_2)); + // construct X(a,b) and Y(a,5,b), respectively. + + // [...] +} +
+ Maybe we want our objects to outlive the function's scope, in this case we + have to use dynamic allocation; +
+template< class Factory > +whatever do_something(Factory new_obj = Factory()) +{ + typename Factory::result_type ptr = new_obj(a,b); + + // again, no common base class or virtual functions needed, + // we could enforce a polymorphic base by writing e.g. + // boost::shared_ptr<base> + // instead of + // typename Factory::result_type + // above. + // Note that we are also free to have the type erasure happen + // somewhere else (e.g. in the constructor of this function's + // result type). + + // [...] +} + +// [... call do_something like above but with __factory__ instead +// of __value_factory__] ++
+ Although we might have created polymorphic objects in the previous example, + we have used compile time polymorphism for the factory. If we want to erase + the type of the factory and thus allow polymorphism at run time, we can use + Boost.Function + to do so. The first example can be rewritten as follows. +
+typedef boost::function< an_abstract_class*() > a_factory; + +// [...] + +int main() +{ ++std::map<std::string,a_factory> factories; + + // [...] + + factories["a_name"] =boost::factory<a_concrete_class*>(); + factories["another_name"] = +boost::factory<another_concrete_class*>(); + + // [...] +} +
+ Of course we can just as easy create factories that take arguments and/or return + Smart Pointers. +
+
+ Function object template that invokes the constructor of the type T.
+
#include <boost/functional/value_factory.hpp> ++
namespace boost +{ + template< typename T > + class value_factory; +} ++
Notation
+T+ an arbitrary type with at least one public constructor +
a0...aN
+ argument LValues to a constructor of T
+
F
+ the type value_factory<F>
+
f
+ an instance object of F
+
|
+ + Expression + + |
+
+ + Semantics + + |
+
|---|---|
|
+
+ |
+
+
+ creates an object of type |
+
|
+
+ |
+
+
+ creates an object of type |
+
|
+
+ |
+
+
+ returns |
+
|
+
+ |
+
+
+ is the type |
+
+ The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set + the maximum arity. It defaults to 10. +
+
+ Function object template that dynamically constructs a pointee object for
+ the type of pointer given as template argument. Smart pointers may be used
+ for the template argument, given that boost::pointee<Pointer>::type
+ yields the pointee type.
+
+ If an Allocator
+ is given, it is used for memory allocation and the placement form of the
+ new operator is used to construct
+ the object. A function object that calls the destructor and deallocates the
+ memory with a copy of the Allocator is used for the second constructor argument
+ of Pointer (thus it must
+ be a Smart Pointer
+ that provides a suitable constructor, such as boost::shared_ptr).
+
+ If a third template argument is factory_passes_alloc_to_smart_pointer,
+ the allocator itself is used for the third constructor argument of Pointer (boost::shared_ptr then uses the allocator
+ to manage the memory of its separately allocated reference counter).
+
#include <boost/functional/factory.hpp> ++
namespace boost +{ + enum factory_alloc_propagation + { + factory_alloc_for_pointee_and_deleter, + factory_passes_alloc_to_smart_pointer + }; + + template< typename Pointer, + class Allocator = void, + factory_alloc_propagation AllocProp = + factory_alloc_for_pointee_and_deleter > + class factory; +} ++
Notation
+T+ an arbitrary type with at least one public constructor +
P
+ pointer or smart pointer to T
+
a0...aN
+ argument LValues to a constructor of T
+
F
+ the type factory<P>
+
f
+ an instance object of F
+
|
+ + Expression + + |
+
+ + Semantics + + |
+
|---|---|
|
+
+ |
+
+
+ creates an object of type |
+
|
+
+ |
+
+
+ creates an object of type |
+
|
+
+ |
+
+
+ dynamically creates an object of type |
+
|
+
+ |
+
+
+ is the type |
+
+ The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the maximum + arity. It defaults to 10. +
+
+ In order to remove the dependency on Boost.Optional, the default parameter
+ for allocators has been changed from boost::none_t
+ to void. If you have code that
+ has stopped working because it uses boost::none_t,
+ a quick fix is to define BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T,
+ which will restore support, but this will be removed in a future release. It
+ should be be relatively easy to fix this properly.
+
+ Eric Niebler requested a function to invoke a type's constructor (with the + arguments supplied as a Tuple) as a Fusion feature. These Factory utilities + are a factored-out generalization of this idea. +
++ Dave Abrahams suggested Smart Pointer support for exception safety, providing + useful hints for the implementation. +
++ Joel de Guzman's documentation style was copied from Fusion. +
++ Further, I want to thank Peter Dimov for sharing his insights on language details + and their evolution. +
+Last revised: November 01, 2008 at 21:44:52 GMT |
++ |
![]() |
+Home | +Libraries | +People | +FAQ | +More | +
Copyright © 2007, 2008 Tobias Schwinger
+ Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +
+Table of Contents
+ +
+ boost::forward_adapter provides a reusable adapter
+ template for function objects. It forwards RValues as references to const,
+ while leaving LValues as-is.
+
struct g // function object that only accept LValues +{ + template< typename T0, typename T1, typename T2 > + void operator()(T0 & t0, T1 & t1, T2 & t2) const; + + typedef void result_type; +}; + +// Adapted version also accepts RValues and forwards +// them as references to const, LValues as-is +typedef boost::forward_adapter<g> f; ++
+ Another adapter, boost::lighweight_forward_adapter allows forwarding
+ with some help from the user accepting and unwrapping reference wrappers (see
+ Boost.Ref) for
+ reference arguments, const qualifying all other arguments.
+
+ The target functions must be compatible with Boost.ResultOf, + and so are the adapters. +
+
+ Let's suppose we have some function f
+ that we can call like this:
+
f(123,a_variable); ++
+ Now we want to write another, generic function g
+ that can be called the same way and returns some object that calls f with the same arguments.
+
f(123,a_variable) == g(f,123,a_variable).call_f() ++
+ Maybe we want to run f several
+ times. Or maybe we want to run it within another thread. Maybe we just want
+ to encapsulate the call expression for now, and then use it with other code
+ that allows to compose more complex expressions in order to decompose it with
+ C++ templates and have the compiler generate some machinery that eventually
+ calls f at runtime (in other
+ words; apply a technique that is commonly referred to as Expression Templates).
+
+ The bad news is: It's impossible. +
++ That is so because there is a slight difference between a variable and an expression + that evaluates to its value: Given +
+int y; +int const z = 0; ++
+ and +
+template< typename T > void func1(T & x); ++
+ we can call +
+func1(y); // x is a reference to a non-const object +func1(z); // x is a reference to a const object ++
+ where +
+func1(1); // fails to compile. ++
+ This way we can safely have func1
+ store its reference argument and the compiler keeps us from storing a reference
+ to an object with temporary lifetime.
+
+ It is important to realize that non-constness and whether an object binds to + a non-const reference parameter are two different properties. The latter is + the distinction between LValues and RValues. The names stem from the left hand + side and the right hand side of assignment expressions, thus LValues are typically + the ones you can assign to, and RValues the temporary results from the right + hand side expression. +
+y = 1+2; // a is LValue, 1+2 is the expression producing the RValue, +// 1+2 = a; // usually makes no sense. + +func1(y); // works, because y is an LValue +// func1(1+2); // fails to compile, because we only got an RValue. ++
+ If we add const qualification on the parameter, our function also accepts RValues: +
+template< typename T > void func2(T const & x); + +// [...] function scope: +func2(1); // x is a reference to a const temporary, object, +func2(y); // x is a reference to a const object, while y is not const, and +func2(z); // x is a reference to a const object, just like z. ++
+ In all cases, the argument x
+ in func2 is a const-qualified
+ LValue. We can use function overloading to identify non-const LValues:
+
template< typename T > void func3(T const & x); // #1 +template< typename T > void func3(T & x); // #2 + +// [...] function scope: +func3(1); // x is a reference to a const, temporary object in #1, +func3(y); // x is a reference to a non-const object in #2, and +func3(z); // x is a reference to a const object in #1. ++
+ Note that all arguments x in
+ the overloaded function func3
+ are LValues. In fact, there is no way to transport RValues into a function
+ as-is in C++98. Also note that we can't distinguish between what used to be
+ a const qualified LValue and an RValue.
+
+ That's as close as we can get to a generic forwarding function g as described above by the means of C++
+ 98. See The
+ Forwarding Problem for a very detailed discussion including solutions
+ that require language changes.
+
+ Now, for actually implementing it, we need 2^N overloads for N parameters (each + with and without const qualifier) for each number of arguments (that is 2^(Nmax+1) + - 2^Nmin). Right, that means the compile-time complexity is O(2^N), however + the factor is low so it works quite well for a reasonable number (< 10) + of arguments. +
++ Function object adapter template whose instances are callable with LValue + and RValue arguments. RValue arguments are forwarded as reference-to-const + typed LValues. +
++ An arity can be given as second, numeric non-type template argument to restrict + forwarding to a specific arity. If a third, numeric non-type template argument + is present, the second and third template argument are treated as minimum + and maximum arity, respectively. Specifying an arity can be helpful to improve + the readability of diagnostic messages and compile time performance. +
++ Boost.ResultOf + can be used to determine the result types of specific call expressions. +
+#include <boost/functional/forward_adapter.hpp> ++
namespace boost +{ + template< class Function, + int Arity_Or_MinArity = unspecified, int MaxArity = unspecified > + class forward_adapter; +} ++
Notation
+F+ a possibly const qualified function object type or reference type thereof +
f
+ an object convertible to F
+
FA
+ the type forward_adapter<F>
+
fa
+ an instance object of FA,
+ initialized with f
+
a0...aN
+ arguments to fa
+
+ The result type of a target function invocation must be +
+boost::result_of<F*(TA0 [const]&...TAN [const]&])>::type
+
+
+ where TA0...TAN denote the argument types of a0...aN.
+
|
+ + Expression + + |
+
+ + Semantics + + |
+
|---|---|
|
+
+ |
+
+
+ creates an adapter, initializes the target function with |
+
|
+
+ |
+
+
+ creates an adapter, attempts to use |
+
|
+
+ |
+
+
+ calls |
+
+ The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set + the maximum call arity. It defaults to 6. +
++ Preprocessing time: O(2^N), where N is the arity limit. Compile time: O(2^N), + where N depends on the arity range. Run time: O(0) if the compiler inlines, + O(1) otherwise. +
++ Function object adapter template whose instances are callable with LValue + and RValue arguments. All arguments are forwarded as reference-to-const typed + LValues, except for reference wrappers which are unwrapped and may yield + non-const LValues. +
++ An arity can be given as second, numeric non-type template argument to restrict + forwarding to a specific arity. If a third, numeric non-type template argument + is present, the second and third template argument are treated as minimum + and maximum arity, respectively. Specifying an arity can be helpful to improve + the readability of diagnostic messages and compile time performance. +
++ Boost.ResultOf + can be used to determine the result types of specific call expressions. +
+#include <boost/functional/lightweight_forward_adapter.hpp> ++
namespace boost +{ + template< class Function, + int Arity_Or_MinArity = unspecified, int MaxArity = unspecified > + struct lightweight_forward_adapter; +} ++
Notation
+F+ a possibly const qualified function object type or reference type thereof +
f
+ an object convertible to F
+
FA
+ the type lightweight_forward_adapter<F>
+
fa
+ an instance of FA,
+ initialized with f
+
a0...aN
+ arguments to fa
+
+ The result type of a target function invocation must be +
+boost::result_of<F*(TA0 [const]&...TAN [const]&])>::type
+
+
+ where TA0...TAN denote the argument types of a0...aN.
+
|
+ + Expression + + |
+
+ + Semantics + + |
+
|---|---|
|
+
+ |
+
+
+ creates an adapter, initializes the target function with |
+
|
+
+ |
+
+
+ creates an adapter, attempts to use |
+
|
+
+ |
+
+
+ calls |
+
+ The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined + to set the maximum call arity. It defaults to 10. +
++ Preprocessing time: O(N), where N is the arity limit. Compile time: O(N), + where N is the effective arity of a call. Run time: O(0) if the compiler + inlines, O(1) otherwise. +
++ As these utilities are factored out of the Boost.Fusion + functional module, I want to thank Dan Marsden and Joel de Guzman for letting + me participate in the development of that great library in the first place. +
++ Further, I want to credit the authors of the references below, for their in-depth + investigation of the problem and the solution implemented here. +
++ Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the + Boost Preprocessor library. Without it, I would have ended up with an external + code generator for this one. +
+Last revised: November 01, 2008 at 19:58:50 GMT |
++ |