|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r49957 - in trunk/libs/functional: factory factory/doc factory/doc/html factory/test forward forward/doc forward/doc/html forward/test
From: tschwinger_at_[hidden]
Date: 2008-11-27 10:15:48
Author: t_schwinger
Date: 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
New Revision: 49957
URL: http://svn.boost.org/trac/boost/changeset/49957
Log:
introduces functional / factory & forward
Added:
trunk/libs/functional/factory/
trunk/libs/functional/factory/doc/
trunk/libs/functional/factory/doc/Jamfile (contents, props changed)
trunk/libs/functional/factory/doc/factory.qbk (contents, props changed)
trunk/libs/functional/factory/doc/html/
trunk/libs/functional/factory/doc/html/boostbook.css (contents, props changed)
trunk/libs/functional/factory/doc/html/index.html (contents, props changed)
trunk/libs/functional/factory/test/
trunk/libs/functional/factory/test/Jamfile (contents, props changed)
trunk/libs/functional/factory/test/factory.cpp (contents, props changed)
trunk/libs/functional/factory/test/factory_with_allocator.cpp (contents, props changed)
trunk/libs/functional/factory/test/value_factory.cpp (contents, props changed)
trunk/libs/functional/forward/
trunk/libs/functional/forward/doc/
trunk/libs/functional/forward/doc/Jamfile (contents, props changed)
trunk/libs/functional/forward/doc/forward.qbk (contents, props changed)
trunk/libs/functional/forward/doc/html/
trunk/libs/functional/forward/doc/html/boostbook.css (contents, props changed)
trunk/libs/functional/forward/doc/html/index.html (contents, props changed)
trunk/libs/functional/forward/test/
trunk/libs/functional/forward/test/Jamfile (contents, props changed)
trunk/libs/functional/forward/test/forward_adapter.cpp (contents, props changed)
trunk/libs/functional/forward/test/lightweight_forward_adapter.cpp (contents, props changed)
Added: trunk/libs/functional/factory/doc/Jamfile
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/doc/Jamfile 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,20 @@
+
+# (C) Copyright Tobias Schwinger
+#
+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
+
+using quickbook ;
+
+xml factory : factory.qbk ;
+boostbook standalone : factory
+ :
+ <xsl:param>boost.root=../../../../..
+ <xsl:param>boost.libraries=../../../../libraries.htm
+ <xsl:param>chunk.section.depth=0
+ <xsl:param>chunk.first.sections=0
+ <xsl:param>generate.section.toc.level=2
+ <xsl:param>toc.max.depth=1
+ ;
+
+
Added: trunk/libs/functional/factory/doc/factory.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/doc/factory.qbk 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,384 @@
+[library Boost.Functional/Factory
+ [quickbook 1.3]
+ [version 1.0]
+ [authors [Schwinger, Tobias]]
+ [copyright 2007 2008 Tobias Schwinger]
+ [license
+ 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])
+ ]
+ [purpose Function object templates for object creation.]
+ [category higher-order]
+ [category generic]
+ [last-revision $Date: 2008/11/01 21:44:52 $]
+]
+
+[def __boost_bind__ [@http://www.boost.org/libs/bind/bind.html Boost.Bind]]
+[def __boost__bind__ [@http://www.boost.org/libs/bind/bind.html `boost::bind`]]
+
+[def __boost__forward_adapter__ [@http://www.boost.org/libs/functional/forward/doc/index.html `boost::forward_adapter`]]
+[def __fusion_functional_adapters__ [@http://www.boost.org/libs/fusion/doc/html/functional.html Fusion Functional Adapters]]
+
+[def __boost_function__ [@http://www.boost.org/doc/html/function.html Boost.Function]]
+[def __boost__function__ [@http://www.boost.org/doc/html/function.html `boost::function`]]
+
+[def __smart_pointers__ [@http://www.boost.org/libs/smart_ptr/index.html Smart Pointers]]
+[def __boost__shared_ptr__ [@http://www.boost.org/libs/smart_ptr/shared_ptr.htm `boost::shared_ptr`]]
+
+[def __std__map__ [@http://www.sgi.com/tech/stl/map.html `std::map`]]
+[def __std__string__ [@http://www.sgi.com/tech/stl/string.html `std::string`]]
+[def __std_allocator__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocator]]
+[def __std_allocators__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocators]]
+
+[def __boost__ptr_map__ [@http://www.boost.org/libs/ptr_container/doc/ptr_map.html `__boost__ptr_map__`]]
+
+[def __boost__factory__ `boost::factory`]
+[def __boost__value_factory__ `boost::value_factory`]
+
+[def __factory__ `factory`]
+[def __value_factory__ `value_factory`]
+
+
+[section Brief Description]
+
+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__.
+
+[endsect]
+
+[section Background]
+
+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_factory> x = factories[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:
+
+ o We may want a factory that takes some arguments that are forwarded to
+ the constructor,
+ o we will probably want to use smart pointers,
+ o we may want several member functions to create different kinds of
+ objects,
+ o we might not necessarily need a polymorphic base class for the objects,
+ o as we will see, we do not need a factory base class at all,
+ o we might want to just call the constructor - without `new` to create
+ an object on the stack, and
+ o finally we might want to use customized memory management.
+
+Experience has shown that using function objects and generic Boost components
+for their composition, Design Patterns that describe callback mechasisms
+(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 encasulate
+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. Overthis __boost__factory__ optionally allows
+the use of smart pointers and __std_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 inhomogenous signaturs 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__.
+
+[endsect]
+
+
+[section:reference Reference]
+
+
+[section value_factory]
+
+[heading Description]
+
+Function object template that invokes the constructor of the type `T`.
+
+[heading Header]
+ #include <boost/functional/value_factory.hpp>
+
+[heading Synopsis]
+
+ namespace boost
+ {
+ template< typename T >
+ class value_factory;
+ }
+
+[variablelist 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`]]
+]
+
+[heading Expression Semantics]
+
+[table
+ [[Expression] [Semantics]]
+ [[`F()`] [creates an object of type `F`.]]
+ [[`F(f)`] [creates an object of type `F`.]]
+ [[`f(a0`...`aN)`] [returns `T(a0`...`aN)`.]]
+ [[`F::result_type`] [is the type `T`.]]
+]
+
+[heading Limits]
+
+The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set the
+maximum arity. It defaults to 10.
+
+[endsect]
+
+
+[section factory]
+
+[heading Description]
+
+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
+seperately allocated reference counter).
+
+[heading Header]
+ #include <boost/functional/factory.hpp>
+
+[heading Synopsis]
+
+ namespace boost
+ {
+ enum factory_alloc_propagation
+ {
+ factory_alloc_for_pointee_and_deleter,
+ factory_passes_alloc_to_smart_pointer
+ };
+
+ template< typename Pointer,
+ class Allocator = boost::none_t,
+ factory_alloc_propagation AllocProp =
+ factory_alloc_for_pointee_and_deleter >
+ class factory;
+ }
+
+[variablelist 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`]]
+]
+
+[heading Expression Semantics]
+
+[table
+ [[Expression] [Semantics]]
+ [[`F()`] [creates an object of type `F`.]]
+ [[`F(f)`] [creates an object of type `F`.]]
+ [[`f(a0`...`aN)`] [dynamically creates an object of type `T` using
+ `a0`...`aN` as arguments for the constructor invocation.]]
+ [[`F::result_type`] [is the type `P` with top-level cv-qualifiers removed.]]
+]
+
+[heading Limits]
+
+The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the
+maximum arity. It defaults to 10.
+
+[endsect]
+
+[endsect]
+
+[section Acknowledgements]
+
+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.
+
+[endsect]
+
+[section References]
+
+# [@http://en.wikipedia.org/wiki/Design_Patterns Design Patterns],
+ Gamma et al. - Addison Wesley Publishing, 1995
+
+# [@http://www.sgi.com/tech/stl/ Standard Template Library Programmer's Guide],
+ Hewlett-Packard Company, 1994
+
+# [@http://www.boost.org/libs/bind/bind.html Boost.Bind],
+ Peter Dimov, 2001-2005
+
+# [@http://www.boost.org/doc/html/function.html Boost.Function],
+ Douglas Gregor, 2001-2004
+
+[endsect]
+
+
Added: trunk/libs/functional/factory/doc/html/boostbook.css
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/doc/html/boostbook.css 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,528 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+/*=============================================================================
+ Body defaults
+=============================================================================*/
+
+ body
+ {
+ margin: 1em;
+ font-family: sans-serif;
+ }
+
+/*=============================================================================
+ Paragraphs
+=============================================================================*/
+
+ p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.15;
+ }
+
+/*=============================================================================
+ Program listings
+=============================================================================*/
+
+ /* Code on paragraphs */
+ p tt.computeroutput
+ {
+ font-size: 9pt;
+ }
+
+ pre.synopsis
+ {
+ font-size: 90%;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ .programlisting,
+ .screen
+ {
+ font-size: 9pt;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ /* Program listings in tables don't get borders */
+ td .programlisting,
+ td .screen
+ {
+ margin: 0pc 0pc 0pc 0pc;
+ padding: 0pc 0pc 0pc 0pc;
+ }
+
+/*=============================================================================
+ Headings
+=============================================================================*/
+
+ h1, h2, h3, h4, h5, h6
+ {
+ text-align: left;
+ margin: 1em 0em 0.5em 0em;
+ font-weight: bold;
+ }
+
+ h1 { font: 140% }
+ h2 { font: bold 140% }
+ h3 { font: bold 130% }
+ h4 { font: bold 120% }
+ h5 { font: italic 110% }
+ h6 { font: italic 100% }
+
+ /* Top page titles */
+ title,
+ h1.title,
+ h2.title
+ h3.title,
+ h4.title,
+ h5.title,
+ h6.title,
+ .refentrytitle
+ {
+ font-weight: bold;
+ margin-bottom: 1pc;
+ }
+
+ h1.title { font-size: 140% }
+ h2.title { font-size: 140% }
+ h3.title { font-size: 130% }
+ h4.title { font-size: 120% }
+ h5.title { font-size: 110% }
+ h6.title { font-size: 100% }
+
+ .section h1
+ {
+ margin: 0em 0em 0.5em 0em;
+ font-size: 140%;
+ }
+
+ .section h2 { font-size: 140% }
+ .section h3 { font-size: 130% }
+ .section h4 { font-size: 120% }
+ .section h5 { font-size: 110% }
+ .section h6 { font-size: 100% }
+
+ /* Code on titles */
+ h1 tt.computeroutput { font-size: 140% }
+ h2 tt.computeroutput { font-size: 140% }
+ h3 tt.computeroutput { font-size: 130% }
+ h4 tt.computeroutput { font-size: 120% }
+ h5 tt.computeroutput { font-size: 110% }
+ h6 tt.computeroutput { font-size: 100% }
+
+/*=============================================================================
+ Author
+=============================================================================*/
+
+ h3.author
+ {
+ font-size: 100%
+ }
+
+/*=============================================================================
+ Lists
+=============================================================================*/
+
+ li
+ {
+ font-size: 10pt;
+ line-height: 1.3;
+ }
+
+ /* Unordered lists */
+ ul
+ {
+ text-align: left;
+ }
+
+ /* Ordered lists */
+ ol
+ {
+ text-align: left;
+ }
+
+/*=============================================================================
+ Links
+=============================================================================*/
+
+ a
+ {
+ text-decoration: none; /* no underline */
+ }
+
+ a:hover
+ {
+ text-decoration: underline;
+ }
+
+/*=============================================================================
+ Spirit style navigation
+=============================================================================*/
+
+ .spirit-nav
+ {
+ text-align: right;
+ }
+
+ .spirit-nav a
+ {
+ color: white;
+ padding-left: 0.5em;
+ }
+
+ .spirit-nav img
+ {
+ border-width: 0px;
+ }
+
+/*=============================================================================
+ Table of contents
+=============================================================================*/
+
+ .toc
+ {
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.1pc 1pc 0.1pc 1pc;
+ font-size: 80%;
+ line-height: 1.15;
+ }
+
+ .boost-toc
+ {
+ float: right;
+ padding: 0.5pc;
+ }
+
+/*=============================================================================
+ Tables
+=============================================================================*/
+
+ .table-title,
+ div.table p.title
+ {
+ margin-left: 4%;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+ }
+
+ div.informaltable table,
+ div.table table
+ {
+ padding: 4px;
+ }
+
+ /* Table Cells */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ padding: 0.5em;
+ text-align: left;
+ font-size: 9pt;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ padding: 0.5em 0.5em 0.5em 0.5em;
+ border: 1pt solid white;
+ font-size: 80%;
+ }
+
+/*=============================================================================
+ Blurbs
+=============================================================================*/
+
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ div.sidebar
+ {
+ font-size: 9pt; /* A little bit smaller than the main text */
+ line-height: 1.2;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.0pc 0.5pc;
+ }
+
+ div.sidebar img
+ {
+ padding: 1pt;
+ }
+
+/*=============================================================================
+ Callouts
+=============================================================================*/
+ .line_callout_bug img
+ {
+ float: left;
+ position:relative;
+ left: 4px;
+ top: -12px;
+ clear: left;
+ margin-left:-22px;
+ }
+
+ .callout_bug img
+ {
+ }
+
+/*=============================================================================
+ Variable Lists
+=============================================================================*/
+
+ /* Make the terms in definition lists bold */
+ div.variablelist dl dt,
+ span.term
+ {
+ font-weight: bold;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td
+ {
+ text-align: left;
+ vertical-align: top;
+ padding: 0em 2em 0em 0em;
+ font-size: 10pt;
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+ div.variablelist dl dt
+ {
+ margin-bottom: 0.2em;
+ }
+
+ div.variablelist dl dd
+ {
+ margin: 0em 0em 0.5em 2em;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td p,
+ div.variablelist dl dd p
+ {
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+/*=============================================================================
+ Misc
+=============================================================================*/
+
+ /* Title of books and articles in bibliographies */
+ span.title
+ {
+ font-style: italic;
+ }
+
+ span.underline
+ {
+ text-decoration: underline;
+ }
+
+ span.strikethrough
+ {
+ text-decoration: line-through;
+ }
+
+ /* Copyright, Legal Notice */
+ div div.legalnotice p
+ {
+ text-align: left
+ }
+
+/*=============================================================================
+ Colors
+=============================================================================*/
+
+ @media screen
+ {
+ /* Links */
+ a
+ {
+ color: #005a9c;
+ }
+
+ a:visited
+ {
+ color: #9c5a9c;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ {
+ text-decoration: none; /* no underline */
+ color: #000000;
+ }
+
+ /* Syntax Highlighting */
+ .keyword { color: #0000AA; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #402080; }
+ .char { color: teal; }
+ .comment { color: #800000; }
+ .string { color: teal; }
+ .number { color: teal; }
+ .white_bkd { background-color: #FFFFFF; }
+ .dk_grey_bkd { background-color: #999999; }
+
+ /* Copyright, Legal Notice */
+ .copyright
+ {
+ color: #666666;
+ font-size: small;
+ }
+
+ div div.legalnotice p
+ {
+ color: #666666;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Blurbs */
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ div.sidebar
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ background-color: #F0F0F0;
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ color: #00A000;
+ }
+ }
+
+ @media print
+ {
+ /* Links */
+ a
+ {
+ color: black;
+ }
+
+ a:visited
+ {
+ color: black;
+ }
+
+ .spirit-nav
+ {
+ display: none;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid gray;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid gray;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid gray;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ border: 1px solid gray;
+ border-collapse: collapse;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid gray;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ border: 1px solid gray;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ font-weight: bold;
+ }
+ }
Added: trunk/libs/functional/factory/doc/html/index.html
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/doc/html/index.html 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,598 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 1. Boost.Functional/Factory 1.0</title>
+<link rel="stylesheet" href="boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
+<link rel="start" href="index.html" title="Chapter 1. Boost.Functional/Factory 1.0">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav"></div>
+<div class="chapter" lang="en">
+<div class="titlepage"><div>
+<div><h2 class="title">
+<a name="boost_functional_factory"></a>Chapter 1. Boost.Functional/Factory 1.0</h2></div>
+<div><div class="author"><h3 class="author">
+<span class="firstname">Tobias</span> <span class="surname">Schwinger</span>
+</h3></div></div>
+<div><p class="copyright">Copyright © 2007, 2008 Tobias Schwinger</p></div>
+<div><div class="legalnotice">
+<a name="id934161"></a><p>
+ 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)
+ </p>
+</div></div>
+</div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="section">Brief Description</span></dt>
+<dt><span class="section">Background</span></dt>
+<dt><span class="section"> Reference</span></dt>
+<dt><span class="section">Acknowledgements</span></dt>
+<dt><span class="section">References</span></dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_factory.brief_description"></a>Brief Description</h2></div></div></div>
+<p>
+ The template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code> lets you encapsulate a <code class="computeroutput"><span class="keyword">new</span></code> expression as a function object, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code>
+ encapsulates a constructor invocation without <code class="computeroutput"><span class="keyword">new</span></code>.
+ </p>
+<pre class="programlisting"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code><span class="special"><</span><span class="identifier">T</span><span class="special">*>()(</span><span class="identifier">arg1</span><span class="special">,</span><span class="identifier">arg2</span><span class="special">,</span><span class="identifier">arg3</span><span class="special">)</span>
+<span class="comment">// same as new T(arg1,arg2,arg3)
+</span>
+<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code><span class="special"><</span><span class="identifier">T</span><span class="special">>()(</span><span class="identifier">arg1</span><span class="special">,</span><span class="identifier">arg2</span><span class="special">,</span><span class="identifier">arg3</span><span class="special">)</span>
+<span class="comment">// same as T(arg1,arg2,arg3)
+</span></pre>
+<p>
+ 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
.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_factory.background"></a>Background</h2></div></div></div>
+<p>
+ 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.
+ </p>
+<pre class="programlisting"><span class="comment">// assuming a_concrete_class and another_concrete_class are derived
+</span><span class="comment">// from an_abstract_class
+</span>
+<span class="keyword">class</span> <span class="identifier">a_factory</span>
+<span class="special">{</span>
+ <span class="keyword">public</span><span class="special">:</span>
+ <span class="keyword">virtual</span> <span class="identifier">an_abstract_class</span><span class="special">*</span> <span class="identifier">create</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
+ <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">a_factory</span><span class="special">()</span> <span class="special">{</span> <span class="special">}</span>
+<span class="special">};</span>
+
+<span class="keyword">class</span> <span class="identifier">a_concrete_factory</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">a_factory</span>
+<span class="special">{</span>
+ <span class="keyword">public</span><span class="special">:</span>
+ <span class="keyword">virtual</span> <span class="identifier">an_abstract_class</span><span class="special">*</span> <span class="identifier">create</span><span class="special">()</span> <span class="keyword">const</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">a_concrete_class</span><span class="special">();</span>
+ <span class="special">}</span>
+<span class="special">};</span>
+
+<span class="keyword">class</span> <span class="identifier">another_concrete_factory</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">a_factory</span>
+<span class="special">{</span>
+ <span class="keyword">public</span><span class="special">:</span>
+ <span class="keyword">virtual</span> <span class="identifier">an_abstract_class</span><span class="special">*</span> <span class="identifier">create</span><span class="special">()</span> <span class="keyword">const</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">another_concrete_class</span><span class="special">();</span>
+ <span class="special">}</span>
+<span class="special">};</span>
+
+<span class="comment">// [...]
+</span>
+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>
+ __boost__ptr_map__
<span class="special"><</span>std::string
<span class="special">,</span><span class="identifier">a_factory</span><span class="special">></span> <span class="identifier">factories</span><span class="special">;</span>
+
+ <span class="comment">// [...]
+</span>
+ <span class="identifier">factories</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="string">"a_name"</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special"><</span><span class="identifier">a_factory</span><span class="special">>(</span>
+ <span class="keyword">new</span> <span class="identifier">a_concrete_factory</span><span class="special">));</span>
+ <span class="identifier">factories</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="string">"another_name"</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special"><</span><span class="identifier">a_factory</span><span class="special">>(</span>
+ <span class="keyword">new</span> <span class="identifier">another_concrete_factory</span><span class="special">));</span>
+
+ <span class="comment">// [...]
+</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special"><</span><span class="identifier">an_abstract_factory</span><span class="special">></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">factories</span><span class="special">[</span><span class="identifier">some_name</span><span class="special">]-></span><span class="identifier">create</span><span class="special">();</span>
+
+ <span class="comment">// [...]
+</span><span class="special">}</span>
+</pre>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="identifier">o</span> <span class="identifier">We</span> <span class="identifier">may</span> <span class="identifier">want</span> <span class="identifier">a</span> <span class="identifier">factory</span> <span class="identifier">that</span> <span class="identifier">takes</span> <span class="identifier">some</span> <span class="identifier">arguments</span> <span class="identifier">that</span> <span class="identifier">are</span> <span class="identifier">forwarded</span> <span class="identifier">to</span>
+ <span class="identifier">the</span> <span class="identifier">constructor</span><span class="special">,</span>
+<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">will</span> <span class="identifier">probably</span> <span class="identifier">want</span> <span class="identifier">to</span> <span class="identifier">use</span> <span class="identifier">smart</span> <span class="identifier">pointers</span><span class="special">,</span>
+<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">may</span> <span class="identifier">want</span> <span class="identifier">several</span> <span class="identifier">member</span> <span class="identifier">functions</span> <span class="identifier">to</span> <span class="identifier">create</span> <span class="identifier">different</span> <span class="identifier">kinds</span> <span class="identifier">of</span>
+ <span class="identifier">objects</span><span class="special">,</span>
+<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">might</span> <span class="keyword">not</span> <span class="identifier">necessarily</span> <span class="identifier">need</span> <span class="identifier">a</span> <span class="identifier">polymorphic</span> <span class="identifier">base</span> <span class="keyword">class</span> <span class="keyword">for</span> <span class="identifier">the</span> <span class="identifier">objects</span><span class="special">,</span>
+<span class="identifier">o</span> <span class="identifier">as</span> <span class="identifier">we</span> <span class="identifier">will</span> <span class="identifier">see</span><span class="special">,</span> <span class="identifier">we</span> <span class="keyword">do</span> <span class="keyword">not</span> <span class="identifier">need</span> <span class="identifier">a</span> <span class="identifier">factory</span> <span class="identifier">base</span> <span class="keyword">class</span> <span class="identifier">at</span> <span class="identifier">all</span><span class="special">,</span>
+<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">might</span> <span class="identifier">want</span> <span class="identifier">to</span> <span class="identifier">just</span> <span class="identifier">call</span> <span class="identifier">the</span> <span class="identifier">constructor</span> <span class="special">-</span> <span class="identifier">without</span> #<span class="keyword">new</span># <span class="identifier">to</span> <span class="identifier">create</span>
+ <span class="identifier">an</span> <span class="identifier">object</span> <span class="identifier">on</span> <span class="identifier">the</span> <span class="identifier">stack</span><span class="special">,</span> <span class="keyword">and</span>
+<span class="identifier">o</span> <span class="identifier">finally</span> <span class="identifier">we</span> <span class="identifier">might</span> <span class="identifier">want</span> <span class="identifier">to</span> <span class="identifier">use</span> <span class="identifier">customized</span> <span class="identifier">memory</span> <span class="identifier">management</span><span class="special">.</span>
+</pre>
+<p>
+ Experience has shown that using function objects and generic Boost components
+ for their composition, Design Patterns that describe callback mechasisms (typically
+ requiring a high percentage of boilerplate code with pure Object Oriented methodology)
+ become implementable with just few code lines and without extra classes.
+ </p>
+<p>
+ Factories are callback mechanisms for constructors, so we provide two class
+ templates, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code> and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code>,
+ that encasulate object construction via direct application of the constructor
+ and the <code class="computeroutput"><span class="keyword">new</span></code> operator, respectively.
+ </p>
+<p>
+ We let the function objects forward their arguments to the construction expressions
+ they encapsulate. Overthis <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code>
+ optionally allows the use of smart pointers and Allocators.
+ </p>
+<p>
+ Compile-time polymorphism can be used where appropriate,
+ </p>
+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">></span>
+<span class="keyword">void</span> <span class="identifier">do_something</span><span class="special">()</span>
+<span class="special">{</span>
+ <span class="comment">// [...]
+</span> <span class="identifier">T</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">T</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>
+
+ <span class="comment">// for conceptually similar objects x we neither need virtual
+</span> <span class="comment">// functions nor a common base class in this context.
+</span> <span class="comment">// [...]
+</span><span class="special">}</span>
+</pre>
+<p>
+ Now, to allow inhomogenous signaturs for the constructors of the types passed
+ in for <code class="computeroutput"><span class="identifier">T</span></code> we can use <code class="computeroutput"><span class="identifier">value_factory</span></code> and boost::bind
+ to normalize between them.
+ </p>
+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">ValueFactory</span> <span class="special">></span>
+<span class="keyword">void</span> <span class="identifier">do_something</span><span class="special">(</span><span class="identifier">ValueFactory</span> <span class="identifier">make_obj</span> <span class="special">=</span> <span class="identifier">ValueFactory</span><span class="special">())</span>
+<span class="special">{</span>
+ <span class="comment">// [...]
+</span> <span class="keyword">typename</span> <span class="identifier">ValueFactory</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">make_obj</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>
+
+ <span class="comment">// for conceptually similar objects x we neither need virtual
+</span> <span class="comment">// functions nor a common base class in this context.
+</span> <span class="comment">// [...]
+</span><span class="special">}</span>
+
+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>
+ <span class="comment">// [...]
+</span>
+ <span class="identifier">do_something</span><span class="special">(</span><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code><span class="special"><</span><span class="identifier">X</span><span class="special">>());</span>
+ <span class="identifier">do_something</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code><span class="special"><</span><span class="identifier">Y</span><span class="special">>(),</span><span class="identifier">_1</span><span class="special">,</span><span class="number">5</span><span class="special">,</span><span class="identifier">_2</span><span class="special">));</span>
+ <span class="comment">// construct X(a,b) and Y(a,5,b), respectively.
+</span>
+ <span class="comment">// [...]
+</span><span class="special">}</span>
+</pre>
+<p>
+ Maybe we want our objects to outlive the function's scope, in this case we
+ have to use dynamic allocation;
+ </p>
+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Factory</span> <span class="special">></span>
+<span class="identifier">whatever</span> <span class="identifier">do_something</span><span class="special">(</span><span class="identifier">Factory</span> <span class="identifier">new_obj</span> <span class="special">=</span> <span class="identifier">Factory</span><span class="special">())</span>
+<span class="special">{</span>
+ <span class="keyword">typename</span> <span class="identifier">Factory</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">ptr</span> <span class="special">=</span> <span class="identifier">new_obj</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>
+
+ <span class="comment">// again, no common base class or virtual functions needed,
+</span> <span class="comment">// we could enforce a polymorphic base by writing e.g.
+</span> <span class="comment">// boost::shared_ptr<base>
+</span> <span class="comment">// instead of
+</span> <span class="comment">// typename Factory::result_type
+</span> <span class="comment">// above.
+</span> <span class="comment">// Note that we are also free to have the type erasure happen
+</span> <span class="comment">// somewhere else (e.g. in the constructor of this function's
+</span> <span class="comment">// result type).
+</span>
+ <span class="comment">// [...]
+</span><span class="special">}</span>
+
+<span class="comment">// [... call do_something like above but with __factory__ instead
+</span><span class="comment">// of __value_factory__]
+</span></pre>
+<p>
+ 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.
+ </p>
+<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> <span class="identifier">an_abstract_class</span><span class="special">*()</span> <span class="special">></span> <span class="identifier">a_factory</span><span class="special">;</span>
+
+<span class="comment">// [...]
+</span>
+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>
+ std::map
<span class="special"><</span>std::string
<span class="special">,</span><span class="identifier">a_factory</span><span class="special">></span> <span class="identifier">factories</span><span class="special">;</span>
+
+ <span class="comment">// [...]
+</span>
+ <span class="identifier">factories</span><span class="special">[</span><span class="string">"a_name"</span><span class="special">]</span> <span class="special">=</span> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code><span class="special"><</span><span class="identifier">a_concrete_class</span><span class="special">*>();</span>
+ <span class="identifier">factories</span><span class="special">[</span><span class="string">"another_name"</span><span class="special">]</span> <span class="special">=</span>
+ <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code><span class="special"><</span><span class="identifier">another_concrete_class</span><span class="special">*>();</span>
+
+ <span class="comment">// [...]
+</span><span class="special">}</span>
+</pre>
+<p>
+ Of course we can just as easy create factories that take arguments and/or return
+ Smart Pointers.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_factory.reference"></a> Reference</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section">value_factory</span></dt>
+<dt><span class="section">factory</span></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="boost_functional_factory.reference.value_factory"></a>value_factory</h3></div></div></div>
+<a name="boost_functional_factory.reference.value_factory.description"></a><h4>
+<a name="id936876"></a>
+ Description
+ </h4>
+<p>
+ Function object template that invokes the constructor of the type <code class="computeroutput"><span class="identifier">T</span></code>.
+ </p>
+<a name="boost_functional_factory.reference.value_factory.header"></a><h4>
+<a name="id936914"></a>
+ Header
+ </h4>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">value_factory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>
+<a name="boost_functional_factory.reference.value_factory.synopsis"></a><h4>
+<a name="id936989"></a>
+ Synopsis
+ </h4>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>
+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span>
+ <span class="keyword">class</span> <span class="identifier">value_factory</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<div class="variablelist">
+<p class="title"><b>Notation</b></p>
+<dl>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span></code></span></dt>
+<dd><p>
+ an arbitrary type with at least one public constructor
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>
+ argument LValues to a constructor of <code class="computeroutput"><span class="identifier">T</span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>
+ the type <code class="computeroutput"><span class="identifier">value_factory</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>
+ an instance object of <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd>
+</dl>
+</div>
+<a name="boost_functional_factory.reference.value_factory.expression_semantics"></a><h4>
+<a name="id937226"></a>
+ <a href="index.html#boost_functional_factory.reference.value_factory.expression_semantics">Expression
+ Semantics</a>
+ </h4>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Expression
+ </p>
+ </th>
+<th>
+ <p>
+ Semantics
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">F</span><span class="special">()</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">F</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ returns <code class="computeroutput"><span class="identifier">T</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">result_type</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ is the type <code class="computeroutput"><span class="identifier">T</span></code>.
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+<a name="boost_functional_factory.reference.value_factory.limits"></a><h4>
+<a name="id937498"></a>
+ Limits
+ </h4>
+<p>
+ The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set
+ the maximum arity. It defaults to 10.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="boost_functional_factory.reference.factory"></a>factory</h3></div></div></div>
+<a name="boost_functional_factory.reference.factory.description"></a><h4>
+<a name="id937545"></a>
+ Description
+ </h4>
+<p>
+ 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 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">pointee</span><span class="special"><</span><span class="identifier">Pointer</span><span class="special">>::</span><span class="identifier">type</span></code>
+ yields the pointee type.
+ </p>
+<p>
+ If an <span class="underline">_allocator</span>_ is given, it is used
+ for memory allocation and the placement form of the <code class="computeroutput"><span class="keyword">new</span></code>
+ 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 <code class="computeroutput"><span class="identifier">Pointer</span></code>
+ (thus it must be a __smart<span class="underline">pointer</span>_
+ that provides a suitable constructor, such as boost::shared_ptr
).
+ </p>
+<p>
+ If a third template argument is <code class="computeroutput"><span class="identifier">factory_passes_alloc_to_smart_pointer</span></code>,
+ the allocator itself is used for the third constructor argument of <code class="computeroutput"><span class="identifier">Pointer</span></code> (boost::shared_ptr
then uses the allocator
+ to manage the memory of its seperately allocated reference counter).
+ </p>
+<a name="boost_functional_factory.reference.factory.header"></a><h4>
+<a name="id937729"></a>
+ Header
+ </h4>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">factory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>
+<a name="boost_functional_factory.reference.factory.synopsis"></a><h4>
+<a name="id937804"></a>
+ Synopsis
+ </h4>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>
+ <span class="keyword">enum</span> <span class="identifier">factory_alloc_propagation</span>
+ <span class="special">{</span>
+ <span class="identifier">factory_alloc_for_pointee_and_deleter</span><span class="special">,</span>
+ <span class="identifier">factory_passes_alloc_to_smart_pointer</span>
+ <span class="special">};</span>
+
+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Pointer</span><span class="special">,</span>
+ <span class="keyword">class</span> <span class="identifier">Allocator</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">none_t</span><span class="special">,</span>
+ <span class="identifier">factory_alloc_propagation</span> <span class="identifier">AllocProp</span> <span class="special">=</span>
+ <span class="identifier">factory_alloc_for_pointee_and_deleter</span> <span class="special">></span>
+ <span class="keyword">class</span> <span class="identifier">factory</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<div class="variablelist">
+<p class="title"><b>Notation</b></p>
+<dl>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span></code></span></dt>
+<dd><p>
+ an arbitrary type with at least one public constructor
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">P</span></code></span></dt>
+<dd><p>
+ pointer or smart pointer to <code class="computeroutput"><span class="identifier">T</span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>
+ argument LValues to a constructor of <code class="computeroutput"><span class="identifier">T</span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>
+ the type <code class="computeroutput"><span class="identifier">factory</span><span class="special"><</span><span class="identifier">P</span><span class="special">></span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>
+ an instance object of <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd>
+</dl>
+</div>
+<a name="boost_functional_factory.reference.factory.expression_semantics"></a><h4>
+<a name="id938169"></a>
+ <a href="index.html#boost_functional_factory.reference.factory.expression_semantics">Expression
+ Semantics</a>
+ </h4>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Expression
+ </p>
+ </th>
+<th>
+ <p>
+ Semantics
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">F</span><span class="special">()</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">F</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ dynamically creates an object of type <code class="computeroutput"><span class="identifier">T</span></code>
+ using <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code> as arguments for the constructor
+ invocation.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">result_type</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ is the type <code class="computeroutput"><span class="identifier">P</span></code> with
+ top-level cv-qualifiers removed.
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+<a name="boost_functional_factory.reference.factory.limits"></a><h4>
+<a name="id938440"></a>
+ Limits
+ </h4>
+<p>
+ The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the maximum
+ arity. It defaults to 10.
+ </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_factory.acknowledgements"></a>Acknowledgements</h2></div></div></div>
+<p>
+ 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.
+ </p>
+<p>
+ Dave Abrahams suggested Smart Pointer support for exception safety, providing
+ useful hints for the implementation.
+ </p>
+<p>
+ Joel de Guzman's documentation style was copied from Fusion.
+ </p>
+<p>
+ Further, I want to thank Peter Dimov for sharing his insights on language details
+ and their evolution.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_factory.references"></a>References</h2></div></div></div>
+<div class="orderedlist"><ol type="1">
+<li>
+Design Patterns,
+ Gamma et al. - Addison Wesley Publishing, 1995
+ </li>
+<li>
+<a href="http://www.sgi.com/tech/stl/" target="_top">Standard Template Library Programmer's
+ Guide</a>, Hewlett-Packard Company, 1994
+ </li>
+<li>
+Boost.Bind,
+ Peter Dimov, 2001-2005
+ </li>
+<li>
+Boost.Function,
+ Douglas Gregor, 2001-2004
+ </li>
+</ol></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"><p><small>Last revised: November 01, 2008 at 21:44:52 GMT</small></p></td>
+<td align="right"><div class="copyright-footer"></div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"></div>
+</body>
+</html>
Added: trunk/libs/functional/factory/test/Jamfile
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/test/Jamfile 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,21 @@
+
+# (C) Copyright Tobias Schwinger
+#
+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
+
+import testing ;
+
+project factory-tests
+ : requirements
+ <include>/Users/tosh/Lab/boost
+ <include>/Users/tosh/Lab/deploy/x_files/factory
+ ;
+
+test-suite functional/factory
+ :
+ [ run value_factory.cpp ]
+ [ run factory.cpp ]
+ [ run factory_with_allocator.cpp ]
+ ;
+
Added: trunk/libs/functional/factory/test/factory.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/test/factory.cpp 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,36 @@
+/*=============================================================================
+ Copyright (c) 2007 Tobias Schwinger
+
+ Use modification and distribution are subject to 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).
+==============================================================================*/
+
+#include <boost/functional/factory.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <memory>
+
+class sum
+{
+ int val_sum;
+ public:
+ sum(int a, int b) : val_sum(a + b) { }
+
+ operator int() const { return this->val_sum; }
+};
+
+int main()
+{
+ int one = 1, two = 2;
+ {
+ sum* instance( boost::factory< sum* >()(one,two) );
+ BOOST_TEST(*instance == 3);
+ }
+ {
+ std::auto_ptr<sum> instance( boost::factory< std::auto_ptr<sum> >()(one,two) );
+ BOOST_TEST(*instance == 3);
+ }
+ return boost::report_errors();
+}
+
Added: trunk/libs/functional/factory/test/factory_with_allocator.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/test/factory_with_allocator.cpp 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,79 @@
+/*=============================================================================
+ Copyright (c) 2007 Tobias Schwinger
+
+ Use modification and distribution are subject to 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).
+==============================================================================*/
+
+#include <boost/functional/factory.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <cstddef>
+#include <memory>
+#include <boost/shared_ptr.hpp>
+
+using std::size_t;
+
+class sum
+{
+ int val_sum;
+ public:
+ sum(int a, int b) : val_sum(a + b) { }
+
+ operator int() const { return this->val_sum; }
+};
+
+template< typename T >
+class counting_allocator : public std::allocator<T>
+{
+ public:
+ counting_allocator()
+ { }
+
+ template< typename OtherT >
+ struct rebind { typedef counting_allocator<OtherT> other; };
+
+ template< typename OtherT >
+ counting_allocator(counting_allocator<OtherT> const& that)
+ { }
+
+ static size_t n_allocated;
+ T* allocate(size_t n, void const* hint = 0l)
+ {
+ n_allocated += 1;
+ return std::allocator<T>::allocate(n,hint);
+ }
+
+ static size_t n_deallocated;
+ void deallocate(T* ptr, size_t n)
+ {
+ n_deallocated += 1;
+ return std::allocator<T>::deallocate(ptr,n);
+ }
+};
+template< typename T > size_t counting_allocator<T>::n_allocated = 0;
+template< typename T > size_t counting_allocator<T>::n_deallocated = 0;
+
+int main()
+{
+ int one = 1, two = 2;
+ {
+ boost::shared_ptr<sum> instance(
+ boost::factory< boost::shared_ptr<sum>, counting_allocator<void>,
+ boost::factory_alloc_for_pointee_and_deleter >()(one,two) );
+ BOOST_TEST(*instance == 3);
+ }
+ BOOST_TEST(counting_allocator<sum>::n_allocated == 1);
+ BOOST_TEST(counting_allocator<sum>::n_deallocated == 1);
+ {
+ boost::shared_ptr<sum> instance(
+ boost::factory< boost::shared_ptr<sum>, counting_allocator<void>,
+ boost::factory_passes_alloc_to_smart_pointer >()(one,two) );
+ BOOST_TEST(*instance == 3);
+ }
+ BOOST_TEST(counting_allocator<sum>::n_allocated == 2);
+ BOOST_TEST(counting_allocator<sum>::n_deallocated == 2);
+ return boost::report_errors();
+}
+
Added: trunk/libs/functional/factory/test/value_factory.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/functional/factory/test/value_factory.cpp 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,29 @@
+/*=============================================================================
+ Copyright (c) 2007 Tobias Schwinger
+
+ Use modification and distribution are subject to 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).
+==============================================================================*/
+
+#include <boost/functional/value_factory.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class sum
+{
+ int val_sum;
+ public:
+ sum(int a, int b) : val_sum(a + b) { }
+ operator int() const { return this->val_sum; }
+};
+
+int main()
+{
+ int one = 1, two = 2;
+ {
+ sum instance( boost::value_factory< sum >()(one,two) );
+ BOOST_TEST(instance == 3);
+ }
+ return boost::report_errors();
+}
+
Added: trunk/libs/functional/forward/doc/Jamfile
==============================================================================
--- (empty file)
+++ trunk/libs/functional/forward/doc/Jamfile 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,19 @@
+
+# (C) Copyright Tobias Schwinger
+#
+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
+
+using quickbook ;
+
+xml forward : forward.qbk ;
+boostbook standalone : forward
+ :
+ <xsl:param>boost.root=../../../../..
+ <xsl:param>boost.libraries=../../../../libraries.htm
+ <xsl:param>chunk.section.depth=0
+ <xsl:param>chunk.first.sections=0
+ <xsl:param>generate.section.toc.level=2
+ <xsl:param>toc.max.depth=1
+ ;
+
Added: trunk/libs/functional/forward/doc/forward.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/functional/forward/doc/forward.qbk 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,316 @@
+[library Boost.Functional/Forward
+ [quickbook 1.3]
+ [version 1.0]
+ [authors [Schwinger, Tobias]]
+ [copyright 2007 2008 Tobias Schwinger]
+ [license
+ 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])
+ ]
+ [purpose Function object adapters for generic argument forwarding.]
+ [category higher-order]
+ [category generic]
+ [last-revision $Date: 2008/11/01 19:58:50 $]
+]
+
+[def __unspecified__ /unspecified/]
+[def __boost_ref__ [@http://www.boost.org/doc/html/ref.html Boost.Ref]]
+[def __boost_result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf]]
+[def __boost__result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of `boost::result_of`]]
+[def __the_forwarding_problem__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem]]
+[def __boost_fusion__ [@http://www.boost.org/libs/fusion/doc/html/index.html Boost.Fusion]]
+
+[section Brief Description]
+
+`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_result_of__, and so are
+the adapters.
+
+[endsect]
+
+[section Background]
+
+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()
+
+[heading Why would we want to do it, anyway?]
+
+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).
+
+[heading Now, how do we do it?]
+
+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.
+
+[endsect]
+
+[section:reference Reference]
+
+[section forward_adapter]
+
+[heading Description]
+
+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_result_of__ can be used to determine the result types of specific call
+expressions.
+
+[heading Header]
+ #include <boost/functional/forward_adapter.hpp>
+
+[heading Synopsis]
+
+ namespace boost
+ {
+ template< class Function,
+ int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
+ class forward_adapter;
+ }
+
+[variablelist 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`.
+
+[heading Expression Semantics]
+
+[table
+ [[Expression] [Semantics]]
+ [[`FA(f)`] [creates an adapter, initializes the target function with `f`.]]
+ [[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]]
+ [[`fa(a0`...`aN)`] [calls `f` with with arguments `a0`...`aN`.]]
+]
+
+[heading Limits]
+
+The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set the
+maximum call arity. It defaults to 6.
+
+[heading Complexity]
+
+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.
+
+[endsect]
+
+
+[section lightweight_forward_adapter]
+
+[heading Description]
+
+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_result_of__ can be used to determine the result types of specific call
+expressions.
+
+[heading Header]
+ #include <boost/functional/lightweight_forward_adapter.hpp>
+
+[heading Synopsis]
+
+ namespace boost
+ {
+ template< class Function,
+ int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
+ struct lightweight_forward_adapter;
+ }
+
+[variablelist 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`.
+
+[heading Expression Semantics]
+
+[table
+ [[Expression] [Semantics]]
+ [[`FA(f)`] [creates an adapter, initializes the target function with `f`.]]
+ [[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]]
+ [[`fa(a0`...`aN)`] [calls `f` with with const arguments `a0`...`aN`. If `aI` is a
+ reference wrapper it is unwrapped.]]
+]
+
+[heading Limits]
+
+The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined
+to set the maximum call arity. It defaults to 10.
+
+[heading Complexity]
+
+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.
+
+[endsect]
+
+[endsect]
+
+
+[section Acknowledgements]
+
+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.
+
+[endsect]
+
+
+[section References]
+
+# [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem],
+ Peter Dimov, Howard E. Hinnant, David Abrahams, 2002
+
+# [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf],
+ Douglas Gregor, 2004
+
+# [@http://www.boost.org/doc/html/ref.html Boost.Ref],
+ Jaakko Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002
+
+[endsect]
+
Added: trunk/libs/functional/forward/doc/html/boostbook.css
==============================================================================
--- (empty file)
+++ trunk/libs/functional/forward/doc/html/boostbook.css 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,528 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+/*=============================================================================
+ Body defaults
+=============================================================================*/
+
+ body
+ {
+ margin: 1em;
+ font-family: sans-serif;
+ }
+
+/*=============================================================================
+ Paragraphs
+=============================================================================*/
+
+ p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.15;
+ }
+
+/*=============================================================================
+ Program listings
+=============================================================================*/
+
+ /* Code on paragraphs */
+ p tt.computeroutput
+ {
+ font-size: 9pt;
+ }
+
+ pre.synopsis
+ {
+ font-size: 90%;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ .programlisting,
+ .screen
+ {
+ font-size: 9pt;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ /* Program listings in tables don't get borders */
+ td .programlisting,
+ td .screen
+ {
+ margin: 0pc 0pc 0pc 0pc;
+ padding: 0pc 0pc 0pc 0pc;
+ }
+
+/*=============================================================================
+ Headings
+=============================================================================*/
+
+ h1, h2, h3, h4, h5, h6
+ {
+ text-align: left;
+ margin: 1em 0em 0.5em 0em;
+ font-weight: bold;
+ }
+
+ h1 { font: 140% }
+ h2 { font: bold 140% }
+ h3 { font: bold 130% }
+ h4 { font: bold 120% }
+ h5 { font: italic 110% }
+ h6 { font: italic 100% }
+
+ /* Top page titles */
+ title,
+ h1.title,
+ h2.title
+ h3.title,
+ h4.title,
+ h5.title,
+ h6.title,
+ .refentrytitle
+ {
+ font-weight: bold;
+ margin-bottom: 1pc;
+ }
+
+ h1.title { font-size: 140% }
+ h2.title { font-size: 140% }
+ h3.title { font-size: 130% }
+ h4.title { font-size: 120% }
+ h5.title { font-size: 110% }
+ h6.title { font-size: 100% }
+
+ .section h1
+ {
+ margin: 0em 0em 0.5em 0em;
+ font-size: 140%;
+ }
+
+ .section h2 { font-size: 140% }
+ .section h3 { font-size: 130% }
+ .section h4 { font-size: 120% }
+ .section h5 { font-size: 110% }
+ .section h6 { font-size: 100% }
+
+ /* Code on titles */
+ h1 tt.computeroutput { font-size: 140% }
+ h2 tt.computeroutput { font-size: 140% }
+ h3 tt.computeroutput { font-size: 130% }
+ h4 tt.computeroutput { font-size: 120% }
+ h5 tt.computeroutput { font-size: 110% }
+ h6 tt.computeroutput { font-size: 100% }
+
+/*=============================================================================
+ Author
+=============================================================================*/
+
+ h3.author
+ {
+ font-size: 100%
+ }
+
+/*=============================================================================
+ Lists
+=============================================================================*/
+
+ li
+ {
+ font-size: 10pt;
+ line-height: 1.3;
+ }
+
+ /* Unordered lists */
+ ul
+ {
+ text-align: left;
+ }
+
+ /* Ordered lists */
+ ol
+ {
+ text-align: left;
+ }
+
+/*=============================================================================
+ Links
+=============================================================================*/
+
+ a
+ {
+ text-decoration: none; /* no underline */
+ }
+
+ a:hover
+ {
+ text-decoration: underline;
+ }
+
+/*=============================================================================
+ Spirit style navigation
+=============================================================================*/
+
+ .spirit-nav
+ {
+ text-align: right;
+ }
+
+ .spirit-nav a
+ {
+ color: white;
+ padding-left: 0.5em;
+ }
+
+ .spirit-nav img
+ {
+ border-width: 0px;
+ }
+
+/*=============================================================================
+ Table of contents
+=============================================================================*/
+
+ .toc
+ {
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.1pc 1pc 0.1pc 1pc;
+ font-size: 80%;
+ line-height: 1.15;
+ }
+
+ .boost-toc
+ {
+ float: right;
+ padding: 0.5pc;
+ }
+
+/*=============================================================================
+ Tables
+=============================================================================*/
+
+ .table-title,
+ div.table p.title
+ {
+ margin-left: 4%;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+ }
+
+ div.informaltable table,
+ div.table table
+ {
+ padding: 4px;
+ }
+
+ /* Table Cells */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ padding: 0.5em;
+ text-align: left;
+ font-size: 9pt;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ padding: 0.5em 0.5em 0.5em 0.5em;
+ border: 1pt solid white;
+ font-size: 80%;
+ }
+
+/*=============================================================================
+ Blurbs
+=============================================================================*/
+
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ div.sidebar
+ {
+ font-size: 9pt; /* A little bit smaller than the main text */
+ line-height: 1.2;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.0pc 0.5pc;
+ }
+
+ div.sidebar img
+ {
+ padding: 1pt;
+ }
+
+/*=============================================================================
+ Callouts
+=============================================================================*/
+ .line_callout_bug img
+ {
+ float: left;
+ position:relative;
+ left: 4px;
+ top: -12px;
+ clear: left;
+ margin-left:-22px;
+ }
+
+ .callout_bug img
+ {
+ }
+
+/*=============================================================================
+ Variable Lists
+=============================================================================*/
+
+ /* Make the terms in definition lists bold */
+ div.variablelist dl dt,
+ span.term
+ {
+ font-weight: bold;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td
+ {
+ text-align: left;
+ vertical-align: top;
+ padding: 0em 2em 0em 0em;
+ font-size: 10pt;
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+ div.variablelist dl dt
+ {
+ margin-bottom: 0.2em;
+ }
+
+ div.variablelist dl dd
+ {
+ margin: 0em 0em 0.5em 2em;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td p,
+ div.variablelist dl dd p
+ {
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+/*=============================================================================
+ Misc
+=============================================================================*/
+
+ /* Title of books and articles in bibliographies */
+ span.title
+ {
+ font-style: italic;
+ }
+
+ span.underline
+ {
+ text-decoration: underline;
+ }
+
+ span.strikethrough
+ {
+ text-decoration: line-through;
+ }
+
+ /* Copyright, Legal Notice */
+ div div.legalnotice p
+ {
+ text-align: left
+ }
+
+/*=============================================================================
+ Colors
+=============================================================================*/
+
+ @media screen
+ {
+ /* Links */
+ a
+ {
+ color: #005a9c;
+ }
+
+ a:visited
+ {
+ color: #9c5a9c;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ {
+ text-decoration: none; /* no underline */
+ color: #000000;
+ }
+
+ /* Syntax Highlighting */
+ .keyword { color: #0000AA; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #402080; }
+ .char { color: teal; }
+ .comment { color: #800000; }
+ .string { color: teal; }
+ .number { color: teal; }
+ .white_bkd { background-color: #FFFFFF; }
+ .dk_grey_bkd { background-color: #999999; }
+
+ /* Copyright, Legal Notice */
+ .copyright
+ {
+ color: #666666;
+ font-size: small;
+ }
+
+ div div.legalnotice p
+ {
+ color: #666666;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Blurbs */
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ div.sidebar
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ background-color: #F0F0F0;
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ color: #00A000;
+ }
+ }
+
+ @media print
+ {
+ /* Links */
+ a
+ {
+ color: black;
+ }
+
+ a:visited
+ {
+ color: black;
+ }
+
+ .spirit-nav
+ {
+ display: none;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid gray;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid gray;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid gray;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ border: 1px solid gray;
+ border-collapse: collapse;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid gray;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ border: 1px solid gray;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ font-weight: bold;
+ }
+ }
Added: trunk/libs/functional/forward/doc/html/index.html
==============================================================================
--- (empty file)
+++ trunk/libs/functional/forward/doc/html/index.html 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,564 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 1. Boost.Functional/Forward 1.0</title>
+<link rel="stylesheet" href="boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
+<link rel="start" href="index.html" title="Chapter 1. Boost.Functional/Forward 1.0">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav"></div>
+<div class="chapter" lang="en">
+<div class="titlepage"><div>
+<div><h2 class="title">
+<a name="boost_functional_forward"></a>Chapter 1. Boost.Functional/Forward 1.0</h2></div>
+<div><div class="author"><h3 class="author">
+<span class="firstname">Tobias</span> <span class="surname">Schwinger</span>
+</h3></div></div>
+<div><p class="copyright">Copyright © 2007, 2008 Tobias Schwinger</p></div>
+<div><div class="legalnotice">
+<a name="id934161"></a><p>
+ 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)
+ </p>
+</div></div>
+</div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="section">Brief Description</span></dt>
+<dt><span class="section">Background</span></dt>
+<dt><span class="section"> Reference</span></dt>
+<dt><span class="section">Acknowledgements</span></dt>
+<dt><span class="section">References</span></dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_forward.brief_description"></a>Brief Description</h2></div></div></div>
+<p>
+ <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span></code> provides a reusable adapter
+ template for function objects. It forwards RValues as references to const,
+ while leaving LValues as-is.
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">g</span> <span class="comment">// function object that only accept LValues
+</span><span class="special">{</span>
+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span> <span class="special">></span>
+ <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T0</span> <span class="special">&</span> <span class="identifier">t0</span><span class="special">,</span> <span class="identifier">T1</span> <span class="special">&</span> <span class="identifier">t1</span><span class="special">,</span> <span class="identifier">T2</span> <span class="special">&</span> <span class="identifier">t2</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>
+<span class="special">};</span>
+
+<span class="comment">// Adapted version also accepts RValues and forwards
+</span><span class="comment">// them as references to const, LValues as-is
+</span><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span><span class="special"><</span><span class="identifier">g</span><span class="special">></span> <span class="identifier">f</span><span class="special">;</span>
+</pre>
+<p>
+ Another adapter, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lighweight_forward_adapter</span></code> allows forwarding
+ with some help from the user accepting and unwrapping reference wrappers (see
+ Boost.Ref) for
+ reference arguments, const qualifying all other arguments.
+ </p>
+<p>
+ The target functions must be compatible with Boost.ResultOf,
+ and so are the adapters.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_forward.background"></a>Background</h2></div></div></div>
+<p>
+ Let's suppose we have some function <code class="computeroutput"><span class="identifier">f</span></code>
+ that we can call like this:
+ </p>
+<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">);</span>
+</pre>
+<p>
+ Now we want to write another, generic function <code class="computeroutput"><span class="identifier">g</span></code>
+ that can be called the same way and returns some object that calls <code class="computeroutput"><span class="identifier">f</span></code> with the same arguments.
+ </p>
+<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">g</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">).</span><span class="identifier">call_f</span><span class="special">()</span>
+</pre>
+<a name="boost_functional_forward.background.why_would_we_want_to_do_it__anyway_"></a><h3>
+<a name="id934701"></a>
+ <a href="index.html#boost_functional_forward.background.why_would_we_want_to_do_it__anyway_">Why
+ would we want to do it, anyway?</a>
+ </h3>
+<p>
+ Maybe we want to run <code class="computeroutput"><span class="identifier">f</span></code> 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 <code class="computeroutput"><span class="identifier">f</span></code> at runtime (in other
+ words; apply a technique that is commonly referred to as Expression Templates).
+ </p>
+<a name="boost_functional_forward.background.now__how_do_we_do_it_"></a><h3>
+<a name="id934755"></a>
+ <a href="index.html#boost_functional_forward.background.now__how_do_we_do_it_">Now,
+ how do we do it?</a>
+ </h3>
+<p>
+ The bad news is: It's impossible.
+ </p>
+<p>
+ That is so because there is a slight difference between a variable and an expression
+ that evaluates to its value: Given
+ </p>
+<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">y</span><span class="special">;</span>
+<span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">z</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
+</pre>
+<p>
+ and
+ </p>
+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func1</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<p>
+ we can call
+ </p>
+<pre class="programlisting"><span class="identifier">func1</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a non-const object
+</span><span class="identifier">func1</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object
+</span></pre>
+<p>
+ where
+ </p>
+<pre class="programlisting"><span class="identifier">func1</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// fails to compile.
+</span></pre>
+<p>
+ This way we can safely have <code class="computeroutput"><span class="identifier">func1</span></code>
+ store its reference argument and the compiler keeps us from storing a reference
+ to an object with temporary lifetime.
+ </p>
+<p>
+ 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.
+ </p>
+<pre class="programlisting"><span class="identifier">y</span> <span class="special">=</span> <span class="number">1</span><span class="special">+</span><span class="number">2</span><span class="special">;</span> <span class="comment">// a is LValue, 1+2 is the expression producing the RValue,
+</span><span class="comment">// 1+2 = a; // usually makes no sense.
+</span>
+<span class="identifier">func1</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// works, because y is an LValue
+</span><span class="comment">// func1(1+2); // fails to compile, because we only got an RValue.
+</span></pre>
+<p>
+ If we add const qualification on the parameter, our function also accepts RValues:
+ </p>
+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func2</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span>
+
+<span class="comment">// [...] function scope:
+</span><span class="identifier">func2</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// x is a reference to a const temporary, object,
+</span><span class="identifier">func2</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a const object, while y is not const, and
+</span><span class="identifier">func2</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object, just like z.
+</span></pre>
+<p>
+ In all cases, the argument <code class="computeroutput"><span class="identifier">x</span></code>
+ in <code class="computeroutput"><span class="identifier">func2</span></code> is a const-qualified
+ LValue. We can use function overloading to identify non-const LValues:
+ </p>
+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func3</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span> <span class="comment">// #1
+</span><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func3</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span> <span class="comment">// #2
+</span>
+<span class="comment">// [...] function scope:
+</span><span class="identifier">func3</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// x is a reference to a const, temporary object in #1,
+</span><span class="identifier">func3</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a non-const object in #2, and
+</span><span class="identifier">func3</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object in #1.
+</span></pre>
+<p>
+ Note that all arguments <code class="computeroutput"><span class="identifier">x</span></code> in
+ the overloaded function <code class="computeroutput"><span class="identifier">func3</span></code>
+ 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.
+ </p>
+<p>
+ That's as close as we can get to a generic forwarding function <code class="computeroutput"><span class="identifier">g</span></code> as described above by the means of C++
+ 98. See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_top">The
+ Forwarding Problem</a> for a very detailed discussion including solutions
+ that require language changes.
+ </p>
+<p>
+ 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.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_forward.reference"></a> Reference</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section">forward_adapter</span></dt>
+<dt><span class="section">lightweight_forward_adapter</span></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="boost_functional_forward.reference.forward_adapter"></a>forward_adapter</h3></div></div></div>
+<a name="boost_functional_forward.reference.forward_adapter.description"></a><h4>
+<a name="id935594"></a>
+ Description
+ </h4>
+<p>
+ Function object adapter template whose instances are callable with LValue
+ and RValue arguments. RValue arguments are forwarded as reference-to-const
+ typed LValues.
+ </p>
+<p>
+ 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.
+ </p>
+<p>
+ Boost.ResultOf
+ can be used to determine the result types of specific call expressions.
+ </p>
+<a name="boost_functional_forward.reference.forward_adapter.header"></a><h4>
+<a name="id935646"></a>
+ Header
+ </h4>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">forward_adapter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>
+<a name="boost_functional_forward.reference.forward_adapter.synopsis"></a><h4>
+<a name="id935721"></a>
+ Synopsis
+ </h4>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>
+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span>
+ <span class="keyword">int</span> <span class="identifier">Arity_Or_MinArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">MaxArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span> <span class="special">></span>
+ <span class="keyword">class</span> <span class="identifier">forward_adapter</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<div class="variablelist">
+<p class="title"><b>Notation</b></p>
+<dl>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>
+ a possibly const qualified function object type or reference type thereof
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>
+ an object convertible to <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">FA</span></code></span></dt>
+<dd><p>
+ the type <code class="computeroutput"><span class="identifier">forward_adapter</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">fa</span></code></span></dt>
+<dd><p>
+ an instance object of <code class="computeroutput"><span class="identifier">FA</span></code>,
+ initialized with <code class="computeroutput"><span class="identifier">f</span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>
+ arguments to <code class="computeroutput"><span class="identifier">fa</span></code>
+ </p></dd>
+</dl>
+</div>
+<p>
+ The result type of a target function invocation must be
+ </p>
+<pre class="programlisting">boost::result_of
<span class="special"><</span><span class="identifier">F</span><span class="special">*(</span><span class="identifier">TA0</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&...</span><span class="identifier">TAN</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&])>::</span><span class="identifier">type</span>
+</pre>
+<p>
+ where <code class="computeroutput"><span class="identifier">TA0</span></code>...<code class="computeroutput"><span class="identifier">TAN</span></code> denote the argument types of <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
+ </p>
+<a name="boost_functional_forward.reference.forward_adapter.expression_semantics"></a><h4>
+<a name="id936177"></a>
+ <a href="index.html#boost_functional_forward.reference.forward_adapter.expression_semantics">Expression
+ Semantics</a>
+ </h4>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Expression
+ </p>
+ </th>
+<th>
+ <p>
+ Semantics
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an adapter, initializes the target function with <code class="computeroutput"><span class="identifier">f</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">()</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an adapter, attempts to use <code class="computeroutput"><span class="identifier">F</span></code>'s
+ default constructor.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">fa</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ calls <code class="computeroutput"><span class="identifier">f</span></code> with with
+ arguments <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+<a name="boost_functional_forward.reference.forward_adapter.limits"></a><h4>
+<a name="id936405"></a>
+ Limits
+ </h4>
+<p>
+ The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set
+ the maximum call arity. It defaults to 6.
+ </p>
+<a name="boost_functional_forward.reference.forward_adapter.complexity"></a><h4>
+<a name="id936434"></a>
+ Complexity
+ </h4>
+<p>
+ 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.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="boost_functional_forward.reference.lightweight_forward_adapter"></a>lightweight_forward_adapter</h3></div></div></div>
+<a name="boost_functional_forward.reference.lightweight_forward_adapter.description"></a><h4>
+<a name="id936485"></a>
+ Description
+ </h4>
+<p>
+ 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.
+ </p>
+<p>
+ 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.
+ </p>
+<p>
+ Boost.ResultOf
+ can be used to determine the result types of specific call expressions.
+ </p>
+<a name="boost_functional_forward.reference.lightweight_forward_adapter.header"></a><h4>
+<a name="id936540"></a>
+ Header
+ </h4>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">lightweight_forward_adapter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>
+<a name="boost_functional_forward.reference.lightweight_forward_adapter.synopsis"></a><h4>
+<a name="id936616"></a>
+ Synopsis
+ </h4>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>
+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span>
+ <span class="keyword">int</span> <span class="identifier">Arity_Or_MinArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">MaxArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span> <span class="special">></span>
+ <span class="keyword">struct</span> <span class="identifier">lightweight_forward_adapter</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<div class="variablelist">
+<p class="title"><b>Notation</b></p>
+<dl>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>
+ a possibly const qualified function object type or reference type thereof
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>
+ an object convertible to <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">FA</span></code></span></dt>
+<dd><p>
+ the type <code class="computeroutput"><span class="identifier">lightweight_forward_adapter</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">fa</span></code></span></dt>
+<dd><p>
+ an instance of <code class="computeroutput"><span class="identifier">FA</span></code>, initialized
+ with <code class="computeroutput"><span class="identifier">f</span></code>
+ </p></dd>
+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>
+ arguments to <code class="computeroutput"><span class="identifier">fa</span></code>
+ </p></dd>
+</dl>
+</div>
+<p>
+ The result type of a target function invocation must be
+ </p>
+<pre class="programlisting">boost::result_of
<span class="special"><</span><span class="identifier">F</span><span class="special">*(</span><span class="identifier">TA0</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&...</span><span class="identifier">TAN</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&])>::</span><span class="identifier">type</span>
+</pre>
+<p>
+ where <code class="computeroutput"><span class="identifier">TA0</span></code>...<code class="computeroutput"><span class="identifier">TAN</span></code> denote the argument types of <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
+ </p>
+<a name="boost_functional_forward.reference.lightweight_forward_adapter.expression_semantics"></a><h4>
+<a name="id937073"></a>
+ <a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.expression_semantics">Expression
+ Semantics</a>
+ </h4>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Expression
+ </p>
+ </th>
+<th>
+ <p>
+ Semantics
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an adapter, initializes the target function with <code class="computeroutput"><span class="identifier">f</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">()</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ creates an adapter, attempts to use <code class="computeroutput"><span class="identifier">F</span></code>'s
+ default constructor.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">fa</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ calls <code class="computeroutput"><span class="identifier">f</span></code> with with
+ const arguments <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>. If <code class="computeroutput"><span class="identifier">aI</span></code>
+ is a reference wrapper it is unwrapped.
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+<a name="boost_functional_forward.reference.lightweight_forward_adapter.limits"></a><h4>
+<a name="id937311"></a>
+ Limits
+ </h4>
+<p>
+ The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined
+ to set the maximum call arity. It defaults to 10.
+ </p>
+<a name="boost_functional_forward.reference.lightweight_forward_adapter.complexity"></a><h4>
+<a name="id937342"></a>
+ Complexity
+ </h4>
+<p>
+ 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.
+ </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_forward.acknowledgements"></a>Acknowledgements</h2></div></div></div>
+<p>
+ 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.
+ </p>
+<p>
+ Further, I want to credit the authors of the references below, for their in-depth
+ investigation of the problem and the solution implemented here.
+ </p>
+<p>
+ 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.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="boost_functional_forward.references"></a>References</h2></div></div></div>
+<div class="orderedlist"><ol type="1">
+<li>
+<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_top">The
+ Forwarding Problem</a>, Peter Dimov, Howard E. Hinnant, David Abrahams,
+ 2002
+ </li>
+<li>
+Boost.ResultOf,
+ Douglas Gregor, 2004
+ </li>
+<li>
+Boost.Ref, Jaakko
+ Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002
+ </li>
+</ol></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"><p><small>Last revised: November 01, 2008 at 19:58:50 GMT</small></p></td>
+<td align="right"><div class="copyright-footer"></div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"></div>
+</body>
+</html>
Added: trunk/libs/functional/forward/test/Jamfile
==============================================================================
--- (empty file)
+++ trunk/libs/functional/forward/test/Jamfile 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,20 @@
+
+# (C) Copyright Tobias Schwinger
+#
+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
+
+import testing ;
+
+project forward-tests
+ : requirements
+ <include>/Users/tosh/Lab/boost
+ <include>/Users/tosh/Lab/deploy/x_files/forward
+ ;
+
+test-suite functional/forward
+ :
+ [ run forward_adapter.cpp ]
+ [ run lightweight_forward_adapter.cpp ]
+ ;
+
Added: trunk/libs/functional/forward/test/forward_adapter.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/functional/forward/test/forward_adapter.cpp 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,127 @@
+/*=============================================================================
+ Copyright (c) 2007 Tobias Schwinger
+
+ Use modification and distribution are subject to 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).
+==============================================================================*/
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(disable: 4244) // no conversion warnings, please
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/functional/forward_adapter.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/blank.hpp>
+#include <boost/noncopyable.hpp>
+
+#include <memory>
+
+template <class Base = boost::blank>
+class test_func : public Base
+{
+ int val;
+public:
+ test_func(int v) : val(v) { }
+
+ template<class B>
+ test_func(test_func<B> const & that)
+ : val(that.val)
+ { }
+
+ template<class B> friend class test_func;
+
+ int operator()(int & l, int const & r) const
+ {
+ return l=r+val;
+ }
+ long operator()(int & l, int const & r)
+ {
+ return -(l=r+val);
+ }
+
+ template <typename Sig>
+ struct result
+ {
+ typedef void type;
+ };
+
+ // ensure result_of argument types are what's expected
+ // note: this is *not* how client code should look like
+ template <class Self>
+ struct result< Self const(int&,int const&) > { typedef int type; };
+
+ template <class Self>
+ struct result< Self(int&,int const&) > { typedef long type; };
+
+ template <class Self>
+ struct result< Self(int&,int&) > { typedef char type; };
+};
+
+enum { int_, long_, char_ };
+
+int type_of(int) { return int_; }
+int type_of(long) { return long_; }
+int type_of(char) { return char_; }
+
+int main()
+{
+ {
+ using boost::is_same;
+ using boost::result_of;
+ typedef boost::forward_adapter< test_func<> > f;
+
+ // lvalue,rvalue
+ BOOST_TEST(( is_same<
+ result_of< f(int&, int) >::type, long >::value ));
+ BOOST_TEST(( is_same<
+ result_of< f const (int&, int) >::type, int >::value ));
+ // lvalue,const lvalue
+ BOOST_TEST(( is_same<
+ result_of< f(int&, int const &) >::type, long >::value ));
+ BOOST_TEST(( is_same<
+ result_of< f const (int&, int const &) >::type, int >::value ));
+ // lvalue,lvalue
+ BOOST_TEST(( is_same<
+ result_of< f(int&, int&) >::type, char >::value ));
+ BOOST_TEST(( is_same<
+ result_of< f const (int&, int&) >::type, char >::value ));
+ }
+ {
+ using boost::noncopyable;
+ using boost::forward_adapter;
+
+ int x = 0;
+ test_func<noncopyable> f(7);
+ forward_adapter< test_func<> > func(f);
+ forward_adapter< test_func<noncopyable> & > func_ref(f);
+ forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
+ forward_adapter< test_func<> const > func_c(f);
+ forward_adapter< test_func<> > const func_c2(f);
+ forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
+
+ BOOST_TEST( type_of( func(x,1) ) == long_ );
+ BOOST_TEST( type_of( func_ref(x,1) ) == long_ );
+ BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ );
+ BOOST_TEST( type_of( func_c(x,1) ) == int_ );
+ BOOST_TEST( type_of( func_c2(x,1) ) == int_ );
+ BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ );
+ BOOST_TEST( type_of( func(x,x) ) == char_ );
+
+ BOOST_TEST( func(x,1) == -8 );
+ BOOST_TEST( func_ref(x,1) == -8 );
+ BOOST_TEST( func_ref_c(x,1) == -8 );
+ BOOST_TEST( func_c(x,1) == 8 );
+ BOOST_TEST( func_c2(x,1) == 8 );
+ BOOST_TEST( func_c_ref(x,1) == 8 );
+ }
+
+ return boost::report_errors();
+}
+
+
Added: trunk/libs/functional/forward/test/lightweight_forward_adapter.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/functional/forward/test/lightweight_forward_adapter.cpp 2008-11-27 10:15:47 EST (Thu, 27 Nov 2008)
@@ -0,0 +1,128 @@
+/*=============================================================================
+ Copyright (c) 2007 Tobias Schwinger
+
+ Use modification and distribution are subject to 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).
+==============================================================================*/
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(disable: 4244) // no conversion warnings, please
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/functional/lightweight_forward_adapter.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/blank.hpp>
+#include <boost/noncopyable.hpp>
+
+#include <memory>
+
+template <class Base = boost::blank>
+class test_func : public Base
+{
+ int val;
+public:
+ test_func(int v) : val(v) { }
+
+ template<class B>
+ test_func(test_func<B> const & that)
+ : val(that.val)
+ { }
+
+ template<class B> friend class test_func;
+
+ int operator()(int & l, int const & r) const
+ {
+ return l=r+val;
+ }
+ long operator()(int & l, int const & r)
+ {
+ return -(l=r+val);
+ }
+
+ template <typename Sig>
+ struct result
+ {
+ typedef void type;
+ };
+
+ // ensure result_of argument types are what's expected
+ // note: this is *not* how client code should look like
+ template <class Self>
+ struct result< Self const(int&,int const&) > { typedef int type; };
+
+ template <class Self>
+ struct result< Self(int&,int const&) > { typedef long type; };
+
+ template <class Self>
+ struct result< Self(int&,int&) > { typedef char type; };
+};
+
+enum { int_, long_, char_ };
+
+int type_of(int) { return int_; }
+int type_of(long) { return long_; }
+int type_of(char) { return char_; }
+
+int main()
+{
+ {
+ using boost::is_same;
+ using boost::result_of;
+ typedef boost::lightweight_forward_adapter< test_func<> > f;
+ typedef boost::reference_wrapper<int> ref;
+ typedef boost::reference_wrapper<int const> cref;
+
+ // lvalue,rvalue
+ BOOST_TEST(( is_same<
+ result_of< f(ref, int) >::type, long >::value ));
+ BOOST_TEST(( is_same<
+ result_of< f const (ref, int) >::type, int >::value ));
+ // lvalue,const lvalue
+ BOOST_TEST(( is_same<
+ result_of< f(ref, cref) >::type, long >::value ));
+ BOOST_TEST(( is_same<
+ result_of< f const (ref, cref) >::type, int >::value ));
+ // lvalue,lvalue
+ BOOST_TEST(( is_same<
+ result_of< f(ref, ref) >::type, char >::value ));
+ BOOST_TEST(( is_same<
+ result_of< f const (ref, ref) >::type, char >::value ));
+ }
+ {
+ using boost::noncopyable;
+ using boost::lightweight_forward_adapter;
+
+ int v = 0; boost::reference_wrapper<int> x(v);
+ test_func<noncopyable> f(7);
+ lightweight_forward_adapter< test_func<> > func(f);
+ lightweight_forward_adapter< test_func<noncopyable> & > func_ref(f);
+ lightweight_forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
+ lightweight_forward_adapter< test_func<> const > func_c(f);
+ lightweight_forward_adapter< test_func<> > const func_c2(f);
+ lightweight_forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
+
+ BOOST_TEST( type_of( func(x,1) ) == long_ );
+ BOOST_TEST( type_of( func_ref(x,1) ) == long_ );
+ BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ );
+ BOOST_TEST( type_of( func_c(x,1) ) == int_ );
+ BOOST_TEST( type_of( func_c2(x,1) ) == int_ );
+ BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ );
+ BOOST_TEST( type_of( func(x,x) ) == char_ );
+
+ BOOST_TEST( func(x,1) == -8 );
+ BOOST_TEST( func_ref(x,1) == -8 );
+ BOOST_TEST( func_ref_c(x,1) == -8 );
+ BOOST_TEST( func_c(x,1) == 8 );
+ BOOST_TEST( func_c2(x,1) == 8 );
+ BOOST_TEST( func_c_ref(x,1) == 8 );
+ }
+
+ return boost::report_errors();
+}
+
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk