Jeff Thompson | a28eed8 | 2013-08-22 16:21:10 -0700 | [diff] [blame] | 1 | <html> |
| 2 | <head> |
| 3 | <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> |
| 4 | <title>Chapter 1. Boost.Functional/Factory 1.0</title> |
| 5 | <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css"> |
| 6 | <meta name="generator" content="DocBook XSL Stylesheets V1.78.1"> |
| 7 | <link rel="home" href="index.html" title="Chapter 1. Boost.Functional/Factory 1.0"> |
| 8 | </head> |
| 9 | <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> |
| 10 | <table cellpadding="2" width="100%"><tr> |
| 11 | <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td> |
| 12 | <td align="center"><a href="../../../../../index.html">Home</a></td> |
| 13 | <td align="center"><a href="../../../../libraries.htm">Libraries</a></td> |
| 14 | <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> |
| 15 | <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> |
| 16 | <td align="center"><a href="../../../../../more/index.htm">More</a></td> |
| 17 | </tr></table> |
| 18 | <hr> |
| 19 | <div class="spirit-nav"></div> |
| 20 | <div class="chapter"> |
| 21 | <div class="titlepage"><div> |
| 22 | <div><h2 class="title"> |
| 23 | <a name="boost_functional_factory"></a>Chapter 1. Boost.Functional/Factory 1.0</h2></div> |
| 24 | <div><div class="author"><h3 class="author"> |
| 25 | <span class="firstname">Tobias</span> <span class="surname">Schwinger</span> |
| 26 | </h3></div></div> |
| 27 | <div><p class="copyright">Copyright © 2007, 2008 Tobias Schwinger</p></div> |
| 28 | <div><div class="legalnotice"> |
| 29 | <a name="boost_functional_factory.legal"></a><p> |
| 30 | Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 31 | file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) |
| 32 | </p> |
| 33 | </div></div> |
| 34 | </div></div> |
| 35 | <div class="toc"> |
| 36 | <p><b>Table of Contents</b></p> |
| 37 | <dl class="toc"> |
| 38 | <dt><span class="section"><a href="index.html#boost_functional_factory.brief_description">Brief Description</a></span></dt> |
| 39 | <dt><span class="section"><a href="index.html#boost_functional_factory.background">Background</a></span></dt> |
| 40 | <dt><span class="section"><a href="index.html#boost_functional_factory.reference">Reference</a></span></dt> |
| 41 | <dt><span class="section"><a href="index.html#boost_functional_factory.acknowledgements">Acknowledgements</a></span></dt> |
| 42 | <dt><span class="section"><a href="index.html#boost_functional_factory.references">References</a></span></dt> |
| 43 | </dl> |
| 44 | </div> |
| 45 | <div class="section"> |
| 46 | <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
| 47 | <a name="boost_functional_factory.brief_description"></a><a class="link" href="index.html#boost_functional_factory.brief_description" title="Brief Description">Brief Description</a> |
| 48 | </h2></div></div></div> |
| 49 | <p> |
| 50 | 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> |
| 51 | encapsulates a constructor invocation without <code class="computeroutput"><span class="keyword">new</span></code>. |
| 52 | </p> |
| 53 | <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> |
| 54 | <span class="comment">// same as new T(arg1,arg2,arg3)</span> |
| 55 | |
| 56 | <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> |
| 57 | <span class="comment">// same as T(arg1,arg2,arg3)</span> |
| 58 | </pre> |
| 59 | <p> |
| 60 | For technical reasons the arguments to the function objects have to be LValues. |
| 61 | A factory that also accepts RValues can be composed using the <a href="http://www.boost.org/libs/functional/forward/doc/index.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span></code></a> |
| 62 | or <a href="http://www.boost.org/libs/bind/bind.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span></code></a>. |
| 63 | </p> |
| 64 | </div> |
| 65 | <div class="section"> |
| 66 | <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
| 67 | <a name="boost_functional_factory.background"></a><a class="link" href="index.html#boost_functional_factory.background" title="Background">Background</a> |
| 68 | </h2></div></div></div> |
| 69 | <p> |
| 70 | In traditional Object Oriented Programming a Factory is an object implementing |
| 71 | an interface of one or more methods that construct objects conforming to known |
| 72 | interfaces. |
| 73 | </p> |
| 74 | <pre class="programlisting"><span class="comment">// assuming a_concrete_class and another_concrete_class are derived</span> |
| 75 | <span class="comment">// from an_abstract_class</span> |
| 76 | |
| 77 | <span class="keyword">class</span> <span class="identifier">a_factory</span> |
| 78 | <span class="special">{</span> |
| 79 | <span class="keyword">public</span><span class="special">:</span> |
| 80 | <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> |
| 81 | <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> |
| 82 | <span class="special">};</span> |
| 83 | |
| 84 | <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> |
| 85 | <span class="special">{</span> |
| 86 | <span class="keyword">public</span><span class="special">:</span> |
| 87 | <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> |
| 88 | <span class="special">{</span> |
| 89 | <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">a_concrete_class</span><span class="special">();</span> |
| 90 | <span class="special">}</span> |
| 91 | <span class="special">};</span> |
| 92 | |
| 93 | <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> |
| 94 | <span class="special">{</span> |
| 95 | <span class="keyword">public</span><span class="special">:</span> |
| 96 | <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> |
| 97 | <span class="special">{</span> |
| 98 | <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">another_concrete_class</span><span class="special">();</span> |
| 99 | <span class="special">}</span> |
| 100 | <span class="special">};</span> |
| 101 | |
| 102 | <span class="comment">// [...]</span> |
| 103 | |
| 104 | <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> |
| 105 | <span class="special">{</span> |
| 106 | <a href="http://www.boost.org/libs/ptr_container/doc/ptr_map.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">ptr_map</span></code></a><span class="special"><</span><a href="http://www.sgi.com/tech/stl/string.html" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code></a><span class="special">,</span><span class="identifier">a_factory</span><span class="special">></span> <span class="identifier">factories</span><span class="special">;</span> |
| 107 | |
| 108 | <span class="comment">// [...]</span> |
| 109 | |
| 110 | <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> |
| 111 | <span class="keyword">new</span> <span class="identifier">a_concrete_factory</span><span class="special">));</span> |
| 112 | <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> |
| 113 | <span class="keyword">new</span> <span class="identifier">another_concrete_factory</span><span class="special">));</span> |
| 114 | |
| 115 | <span class="comment">// [...]</span> |
| 116 | |
| 117 | <span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special"><</span><span class="identifier">an_abstract_class</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">at</span><span class="special">(</span><span class="identifier">some_name</span><span class="special">).</span><span class="identifier">create</span><span class="special">());</span> |
| 118 | |
| 119 | <span class="comment">// [...]</span> |
| 120 | <span class="special">}</span> |
| 121 | </pre> |
| 122 | <p> |
| 123 | This approach has several drawbacks. The most obvious one is that there is |
| 124 | lots of boilerplate code. In other words there is too much code to express |
| 125 | a rather simple intention. We could use templates to get rid of some of it |
| 126 | but the approach remains inflexible: |
| 127 | </p> |
| 128 | <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| 129 | <li class="listitem"> |
| 130 | We may want a factory that takes some arguments that are forwarded to the |
| 131 | constructor, |
| 132 | </li> |
| 133 | <li class="listitem"> |
| 134 | we will probably want to use smart pointers, |
| 135 | </li> |
| 136 | <li class="listitem"> |
| 137 | we may want several member functions to create different kinds of objects, |
| 138 | </li> |
| 139 | <li class="listitem"> |
| 140 | we might not necessarily need a polymorphic base class for the objects, |
| 141 | </li> |
| 142 | <li class="listitem"> |
| 143 | as we will see, we do not need a factory base class at all, |
| 144 | </li> |
| 145 | <li class="listitem"> |
| 146 | we might want to just call the constructor - without <code class="computeroutput"><span class="keyword">new</span></code> |
| 147 | to create an object on the stack, and |
| 148 | </li> |
| 149 | <li class="listitem"> |
| 150 | finally we might want to use customized memory management. |
| 151 | </li> |
| 152 | </ul></div> |
| 153 | <p> |
| 154 | Experience has shown that using function objects and generic Boost components |
| 155 | for their composition, Design Patterns that describe callback mechanisms (typically |
| 156 | requiring a high percentage of boilerplate code with pure Object Oriented methodology) |
| 157 | become implementable with just few code lines and without extra classes. |
| 158 | </p> |
| 159 | <p> |
| 160 | Factories are callback mechanisms for constructors, so we provide two class |
| 161 | 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>, |
| 162 | that encapsulate object construction via direct application of the constructor |
| 163 | and the <code class="computeroutput"><span class="keyword">new</span></code> operator, respectively. |
| 164 | </p> |
| 165 | <p> |
| 166 | We let the function objects forward their arguments to the construction expressions |
| 167 | they encapsulate. Over this <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code> |
| 168 | optionally allows the use of smart pointers and <a href="http://www.sgi.com/tech/stl/concepts/allocator.html" target="_top">Allocators</a>. |
| 169 | </p> |
| 170 | <p> |
| 171 | Compile-time polymorphism can be used where appropriate, |
| 172 | </p> |
| 173 | <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> |
| 174 | <span class="keyword">void</span> <span class="identifier">do_something</span><span class="special">()</span> |
| 175 | <span class="special">{</span> |
| 176 | <span class="comment">// [...]</span> |
| 177 | <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> |
| 178 | |
| 179 | <span class="comment">// for conceptually similar objects x we neither need virtual</span> |
| 180 | <span class="comment">// functions nor a common base class in this context.</span> |
| 181 | <span class="comment">// [...]</span> |
| 182 | <span class="special">}</span> |
| 183 | </pre> |
| 184 | <p> |
| 185 | Now, to allow inhomogeneous signatures for the constructors of the types passed |
| 186 | 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 <a href="http://www.boost.org/libs/bind/bind.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span></code></a> |
| 187 | to normalize between them. |
| 188 | </p> |
| 189 | <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> |
| 190 | <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> |
| 191 | <span class="special">{</span> |
| 192 | <span class="comment">// [...]</span> |
| 193 | <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> |
| 194 | |
| 195 | <span class="comment">// for conceptually similar objects x we neither need virtual</span> |
| 196 | <span class="comment">// functions nor a common base class in this context.</span> |
| 197 | <span class="comment">// [...]</span> |
| 198 | <span class="special">}</span> |
| 199 | |
| 200 | <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> |
| 201 | <span class="special">{</span> |
| 202 | <span class="comment">// [...]</span> |
| 203 | |
| 204 | <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> |
| 205 | <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> |
| 206 | <span class="comment">// construct X(a,b) and Y(a,5,b), respectively.</span> |
| 207 | |
| 208 | <span class="comment">// [...]</span> |
| 209 | <span class="special">}</span> |
| 210 | </pre> |
| 211 | <p> |
| 212 | Maybe we want our objects to outlive the function's scope, in this case we |
| 213 | have to use dynamic allocation; |
| 214 | </p> |
| 215 | <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> |
| 216 | <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> |
| 217 | <span class="special">{</span> |
| 218 | <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> |
| 219 | |
| 220 | <span class="comment">// again, no common base class or virtual functions needed,</span> |
| 221 | <span class="comment">// we could enforce a polymorphic base by writing e.g.</span> |
| 222 | <span class="comment">// boost::shared_ptr<base></span> |
| 223 | <span class="comment">// instead of</span> |
| 224 | <span class="comment">// typename Factory::result_type</span> |
| 225 | <span class="comment">// above.</span> |
| 226 | <span class="comment">// Note that we are also free to have the type erasure happen </span> |
| 227 | <span class="comment">// somewhere else (e.g. in the constructor of this function's</span> |
| 228 | <span class="comment">// result type).</span> |
| 229 | |
| 230 | <span class="comment">// [...]</span> |
| 231 | <span class="special">}</span> |
| 232 | |
| 233 | <span class="comment">// [... call do_something like above but with __factory__ instead</span> |
| 234 | <span class="comment">// of __value_factory__]</span> |
| 235 | </pre> |
| 236 | <p> |
| 237 | Although we might have created polymorphic objects in the previous example, |
| 238 | we have used compile time polymorphism for the factory. If we want to erase |
| 239 | the type of the factory and thus allow polymorphism at run time, we can use |
| 240 | <a href="http://www.boost.org/doc/html/function.html" target="_top">Boost.Function</a> |
| 241 | to do so. The first example can be rewritten as follows. |
| 242 | </p> |
| 243 | <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> |
| 244 | |
| 245 | <span class="comment">// [...]</span> |
| 246 | |
| 247 | <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> |
| 248 | <span class="special">{</span> |
| 249 | <a href="http://www.sgi.com/tech/stl/map.html" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code></a><span class="special"><</span><a href="http://www.sgi.com/tech/stl/string.html" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code></a><span class="special">,</span><span class="identifier">a_factory</span><span class="special">></span> <span class="identifier">factories</span><span class="special">;</span> |
| 250 | |
| 251 | <span class="comment">// [...]</span> |
| 252 | |
| 253 | <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> |
| 254 | <span class="identifier">factories</span><span class="special">[</span><span class="string">"another_name"</span><span class="special">]</span> <span class="special">=</span> |
| 255 | <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> |
| 256 | |
| 257 | <span class="comment">// [...]</span> |
| 258 | <span class="special">}</span> |
| 259 | </pre> |
| 260 | <p> |
| 261 | Of course we can just as easy create factories that take arguments and/or return |
| 262 | <a href="http://www.boost.org/libs/smart_ptr/index.html" target="_top">Smart Pointers</a>. |
| 263 | </p> |
| 264 | </div> |
| 265 | <div class="section"> |
| 266 | <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
| 267 | <a name="boost_functional_factory.reference"></a><a class="link" href="index.html#boost_functional_factory.reference" title="Reference">Reference</a> |
| 268 | </h2></div></div></div> |
| 269 | <div class="toc"><dl class="toc"> |
| 270 | <dt><span class="section"><a href="index.html#boost_functional_factory.reference.value_factory">value_factory</a></span></dt> |
| 271 | <dt><span class="section"><a href="index.html#boost_functional_factory.reference.factory">factory</a></span></dt> |
| 272 | </dl></div> |
| 273 | <div class="section"> |
| 274 | <div class="titlepage"><div><div><h3 class="title"> |
| 275 | <a name="boost_functional_factory.reference.value_factory"></a><a class="link" href="index.html#boost_functional_factory.reference.value_factory" title="value_factory">value_factory</a> |
| 276 | </h3></div></div></div> |
| 277 | <h5> |
| 278 | <a name="boost_functional_factory.reference.value_factory.h0"></a> |
| 279 | <span class="phrase"><a name="boost_functional_factory.reference.value_factory.description"></a></span><a class="link" href="index.html#boost_functional_factory.reference.value_factory.description">Description</a> |
| 280 | </h5> |
| 281 | <p> |
| 282 | Function object template that invokes the constructor of the type <code class="computeroutput"><span class="identifier">T</span></code>. |
| 283 | </p> |
| 284 | <h5> |
| 285 | <a name="boost_functional_factory.reference.value_factory.h1"></a> |
| 286 | <span class="phrase"><a name="boost_functional_factory.reference.value_factory.header"></a></span><a class="link" href="index.html#boost_functional_factory.reference.value_factory.header">Header</a> |
| 287 | </h5> |
| 288 | <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> |
| 289 | </pre> |
| 290 | <h5> |
| 291 | <a name="boost_functional_factory.reference.value_factory.h2"></a> |
| 292 | <span class="phrase"><a name="boost_functional_factory.reference.value_factory.synopsis"></a></span><a class="link" href="index.html#boost_functional_factory.reference.value_factory.synopsis">Synopsis</a> |
| 293 | </h5> |
| 294 | <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> |
| 295 | <span class="special">{</span> |
| 296 | <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> |
| 297 | <span class="keyword">class</span> <span class="identifier">value_factory</span><span class="special">;</span> |
| 298 | <span class="special">}</span> |
| 299 | </pre> |
| 300 | <div class="variablelist"> |
| 301 | <p class="title"><b>Notation</b></p> |
| 302 | <dl class="variablelist"> |
| 303 | <dt><span class="term"><code class="computeroutput"><span class="identifier">T</span></code></span></dt> |
| 304 | <dd><p> |
| 305 | an arbitrary type with at least one public constructor |
| 306 | </p></dd> |
| 307 | <dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt> |
| 308 | <dd><p> |
| 309 | argument LValues to a constructor of <code class="computeroutput"><span class="identifier">T</span></code> |
| 310 | </p></dd> |
| 311 | <dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt> |
| 312 | <dd><p> |
| 313 | 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> |
| 314 | </p></dd> |
| 315 | <dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt> |
| 316 | <dd><p> |
| 317 | an instance object of <code class="computeroutput"><span class="identifier">F</span></code> |
| 318 | </p></dd> |
| 319 | </dl> |
| 320 | </div> |
| 321 | <h5> |
| 322 | <a name="boost_functional_factory.reference.value_factory.h3"></a> |
| 323 | <span class="phrase"><a name="boost_functional_factory.reference.value_factory.expression_semantics"></a></span><a class="link" href="index.html#boost_functional_factory.reference.value_factory.expression_semantics">Expression |
| 324 | Semantics</a> |
| 325 | </h5> |
| 326 | <div class="informaltable"><table class="table"> |
| 327 | <colgroup> |
| 328 | <col> |
| 329 | <col> |
| 330 | </colgroup> |
| 331 | <thead><tr> |
| 332 | <th> |
| 333 | <p> |
| 334 | Expression |
| 335 | </p> |
| 336 | </th> |
| 337 | <th> |
| 338 | <p> |
| 339 | Semantics |
| 340 | </p> |
| 341 | </th> |
| 342 | </tr></thead> |
| 343 | <tbody> |
| 344 | <tr> |
| 345 | <td> |
| 346 | <p> |
| 347 | <code class="computeroutput"><span class="identifier">F</span><span class="special">()</span></code> |
| 348 | </p> |
| 349 | </td> |
| 350 | <td> |
| 351 | <p> |
| 352 | creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>. |
| 353 | </p> |
| 354 | </td> |
| 355 | </tr> |
| 356 | <tr> |
| 357 | <td> |
| 358 | <p> |
| 359 | <code class="computeroutput"><span class="identifier">F</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code> |
| 360 | </p> |
| 361 | </td> |
| 362 | <td> |
| 363 | <p> |
| 364 | creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>. |
| 365 | </p> |
| 366 | </td> |
| 367 | </tr> |
| 368 | <tr> |
| 369 | <td> |
| 370 | <p> |
| 371 | <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> |
| 372 | </p> |
| 373 | </td> |
| 374 | <td> |
| 375 | <p> |
| 376 | 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>. |
| 377 | </p> |
| 378 | </td> |
| 379 | </tr> |
| 380 | <tr> |
| 381 | <td> |
| 382 | <p> |
| 383 | <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">result_type</span></code> |
| 384 | </p> |
| 385 | </td> |
| 386 | <td> |
| 387 | <p> |
| 388 | is the type <code class="computeroutput"><span class="identifier">T</span></code>. |
| 389 | </p> |
| 390 | </td> |
| 391 | </tr> |
| 392 | </tbody> |
| 393 | </table></div> |
| 394 | <h5> |
| 395 | <a name="boost_functional_factory.reference.value_factory.h4"></a> |
| 396 | <span class="phrase"><a name="boost_functional_factory.reference.value_factory.limits"></a></span><a class="link" href="index.html#boost_functional_factory.reference.value_factory.limits">Limits</a> |
| 397 | </h5> |
| 398 | <p> |
| 399 | The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set |
| 400 | the maximum arity. It defaults to 10. |
| 401 | </p> |
| 402 | </div> |
| 403 | <div class="section"> |
| 404 | <div class="titlepage"><div><div><h3 class="title"> |
| 405 | <a name="boost_functional_factory.reference.factory"></a><a class="link" href="index.html#boost_functional_factory.reference.factory" title="factory">factory</a> |
| 406 | </h3></div></div></div> |
| 407 | <h5> |
| 408 | <a name="boost_functional_factory.reference.factory.h0"></a> |
| 409 | <span class="phrase"><a name="boost_functional_factory.reference.factory.description"></a></span><a class="link" href="index.html#boost_functional_factory.reference.factory.description">Description</a> |
| 410 | </h5> |
| 411 | <p> |
| 412 | Function object template that dynamically constructs a pointee object for |
| 413 | the type of pointer given as template argument. Smart pointers may be used |
| 414 | 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> |
| 415 | yields the pointee type. |
| 416 | </p> |
| 417 | <p> |
| 418 | If an <a href="http://www.sgi.com/tech/stl/concepts/allocator.html" target="_top">Allocator</a> |
| 419 | is given, it is used for memory allocation and the placement form of the |
| 420 | <code class="computeroutput"><span class="keyword">new</span></code> operator is used to construct |
| 421 | the object. A function object that calls the destructor and deallocates the |
| 422 | memory with a copy of the Allocator is used for the second constructor argument |
| 423 | of <code class="computeroutput"><span class="identifier">Pointer</span></code> (thus it must |
| 424 | be a <a href="http://www.boost.org/libs/smart_ptr/index.html" target="_top">Smart Pointer</a> |
| 425 | that provides a suitable constructor, such as <a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span></code></a>). |
| 426 | </p> |
| 427 | <p> |
| 428 | If a third template argument is <code class="computeroutput"><span class="identifier">factory_passes_alloc_to_smart_pointer</span></code>, |
| 429 | the allocator itself is used for the third constructor argument of <code class="computeroutput"><span class="identifier">Pointer</span></code> (<a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span></code></a> then uses the allocator |
| 430 | to manage the memory of its separately allocated reference counter). |
| 431 | </p> |
| 432 | <h5> |
| 433 | <a name="boost_functional_factory.reference.factory.h1"></a> |
| 434 | <span class="phrase"><a name="boost_functional_factory.reference.factory.header"></a></span><a class="link" href="index.html#boost_functional_factory.reference.factory.header">Header</a> |
| 435 | </h5> |
| 436 | <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> |
| 437 | </pre> |
| 438 | <h5> |
| 439 | <a name="boost_functional_factory.reference.factory.h2"></a> |
| 440 | <span class="phrase"><a name="boost_functional_factory.reference.factory.synopsis"></a></span><a class="link" href="index.html#boost_functional_factory.reference.factory.synopsis">Synopsis</a> |
| 441 | </h5> |
| 442 | <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> |
| 443 | <span class="special">{</span> |
| 444 | <span class="keyword">enum</span> <span class="identifier">factory_alloc_propagation</span> |
| 445 | <span class="special">{</span> |
| 446 | <span class="identifier">factory_alloc_for_pointee_and_deleter</span><span class="special">,</span> |
| 447 | <span class="identifier">factory_passes_alloc_to_smart_pointer</span> |
| 448 | <span class="special">};</span> |
| 449 | |
| 450 | <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Pointer</span><span class="special">,</span> |
| 451 | <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> |
| 452 | <span class="identifier">factory_alloc_propagation</span> <span class="identifier">AllocProp</span> <span class="special">=</span> |
| 453 | <span class="identifier">factory_alloc_for_pointee_and_deleter</span> <span class="special">></span> |
| 454 | <span class="keyword">class</span> <span class="identifier">factory</span><span class="special">;</span> |
| 455 | <span class="special">}</span> |
| 456 | </pre> |
| 457 | <div class="variablelist"> |
| 458 | <p class="title"><b>Notation</b></p> |
| 459 | <dl class="variablelist"> |
| 460 | <dt><span class="term"><code class="computeroutput"><span class="identifier">T</span></code></span></dt> |
| 461 | <dd><p> |
| 462 | an arbitrary type with at least one public constructor |
| 463 | </p></dd> |
| 464 | <dt><span class="term"><code class="computeroutput"><span class="identifier">P</span></code></span></dt> |
| 465 | <dd><p> |
| 466 | pointer or smart pointer to <code class="computeroutput"><span class="identifier">T</span></code> |
| 467 | </p></dd> |
| 468 | <dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt> |
| 469 | <dd><p> |
| 470 | argument LValues to a constructor of <code class="computeroutput"><span class="identifier">T</span></code> |
| 471 | </p></dd> |
| 472 | <dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt> |
| 473 | <dd><p> |
| 474 | the type <code class="computeroutput"><span class="identifier">factory</span><span class="special"><</span><span class="identifier">P</span><span class="special">></span></code> |
| 475 | </p></dd> |
| 476 | <dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt> |
| 477 | <dd><p> |
| 478 | an instance object of <code class="computeroutput"><span class="identifier">F</span></code> |
| 479 | </p></dd> |
| 480 | </dl> |
| 481 | </div> |
| 482 | <h5> |
| 483 | <a name="boost_functional_factory.reference.factory.h3"></a> |
| 484 | <span class="phrase"><a name="boost_functional_factory.reference.factory.expression_semantics"></a></span><a class="link" href="index.html#boost_functional_factory.reference.factory.expression_semantics">Expression |
| 485 | Semantics</a> |
| 486 | </h5> |
| 487 | <div class="informaltable"><table class="table"> |
| 488 | <colgroup> |
| 489 | <col> |
| 490 | <col> |
| 491 | </colgroup> |
| 492 | <thead><tr> |
| 493 | <th> |
| 494 | <p> |
| 495 | Expression |
| 496 | </p> |
| 497 | </th> |
| 498 | <th> |
| 499 | <p> |
| 500 | Semantics |
| 501 | </p> |
| 502 | </th> |
| 503 | </tr></thead> |
| 504 | <tbody> |
| 505 | <tr> |
| 506 | <td> |
| 507 | <p> |
| 508 | <code class="computeroutput"><span class="identifier">F</span><span class="special">()</span></code> |
| 509 | </p> |
| 510 | </td> |
| 511 | <td> |
| 512 | <p> |
| 513 | creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>. |
| 514 | </p> |
| 515 | </td> |
| 516 | </tr> |
| 517 | <tr> |
| 518 | <td> |
| 519 | <p> |
| 520 | <code class="computeroutput"><span class="identifier">F</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code> |
| 521 | </p> |
| 522 | </td> |
| 523 | <td> |
| 524 | <p> |
| 525 | creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>. |
| 526 | </p> |
| 527 | </td> |
| 528 | </tr> |
| 529 | <tr> |
| 530 | <td> |
| 531 | <p> |
| 532 | <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> |
| 533 | </p> |
| 534 | </td> |
| 535 | <td> |
| 536 | <p> |
| 537 | dynamically creates an object of type <code class="computeroutput"><span class="identifier">T</span></code> |
| 538 | using <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code> as arguments for the constructor |
| 539 | invocation. |
| 540 | </p> |
| 541 | </td> |
| 542 | </tr> |
| 543 | <tr> |
| 544 | <td> |
| 545 | <p> |
| 546 | <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">result_type</span></code> |
| 547 | </p> |
| 548 | </td> |
| 549 | <td> |
| 550 | <p> |
| 551 | is the type <code class="computeroutput"><span class="identifier">P</span></code> with |
| 552 | top-level cv-qualifiers removed. |
| 553 | </p> |
| 554 | </td> |
| 555 | </tr> |
| 556 | </tbody> |
| 557 | </table></div> |
| 558 | <h5> |
| 559 | <a name="boost_functional_factory.reference.factory.h4"></a> |
| 560 | <span class="phrase"><a name="boost_functional_factory.reference.factory.limits"></a></span><a class="link" href="index.html#boost_functional_factory.reference.factory.limits">Limits</a> |
| 561 | </h5> |
| 562 | <p> |
| 563 | The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the maximum |
| 564 | arity. It defaults to 10. |
| 565 | </p> |
| 566 | </div> |
| 567 | </div> |
| 568 | <div class="section"> |
| 569 | <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
| 570 | <a name="boost_functional_factory.acknowledgements"></a><a class="link" href="index.html#boost_functional_factory.acknowledgements" title="Acknowledgements">Acknowledgements</a> |
| 571 | </h2></div></div></div> |
| 572 | <p> |
| 573 | Eric Niebler requested a function to invoke a type's constructor (with the |
| 574 | arguments supplied as a Tuple) as a Fusion feature. These Factory utilities |
| 575 | are a factored-out generalization of this idea. |
| 576 | </p> |
| 577 | <p> |
| 578 | Dave Abrahams suggested Smart Pointer support for exception safety, providing |
| 579 | useful hints for the implementation. |
| 580 | </p> |
| 581 | <p> |
| 582 | Joel de Guzman's documentation style was copied from Fusion. |
| 583 | </p> |
| 584 | <p> |
| 585 | Further, I want to thank Peter Dimov for sharing his insights on language details |
| 586 | and their evolution. |
| 587 | </p> |
| 588 | </div> |
| 589 | <div class="section"> |
| 590 | <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
| 591 | <a name="boost_functional_factory.references"></a><a class="link" href="index.html#boost_functional_factory.references" title="References">References</a> |
| 592 | </h2></div></div></div> |
| 593 | <div class="orderedlist"><ol class="orderedlist" type="1"> |
| 594 | <li class="listitem"> |
| 595 | <a href="http://en.wikipedia.org/wiki/Design_Patterns" target="_top">Design Patterns</a>, |
| 596 | Gamma et al. - Addison Wesley Publishing, 1995 |
| 597 | </li> |
| 598 | <li class="listitem"> |
| 599 | <a href="http://www.sgi.com/tech/stl/" target="_top">Standard Template Library Programmer's |
| 600 | Guide</a>, Hewlett-Packard Company, 1994 |
| 601 | </li> |
| 602 | <li class="listitem"> |
| 603 | <a href="http://www.boost.org/libs/bind/bind.html" target="_top">Boost.Bind</a>, |
| 604 | Peter Dimov, 2001-2005 |
| 605 | </li> |
| 606 | <li class="listitem"> |
| 607 | <a href="http://www.boost.org/doc/html/function.html" target="_top">Boost.Function</a>, |
| 608 | Douglas Gregor, 2001-2004 |
| 609 | </li> |
| 610 | </ol></div> |
| 611 | </div> |
| 612 | </div> |
| 613 | <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> |
| 614 | <td align="left"><p><small>Last revised: November 01, 2008 at 21:44:52 GMT</small></p></td> |
| 615 | <td align="right"><div class="copyright-footer"></div></td> |
| 616 | </tr></table> |
| 617 | <hr> |
| 618 | <div class="spirit-nav"></div> |
| 619 | </body> |
| 620 | </html> |