configuration.html 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  5. <title>Boost.Flyweight Documentation - Tutorial - Configuring Boost.Flyweight</title>
  6. <link rel="stylesheet" href="../style.css" type="text/css">
  7. <link rel="start" href="../index.html">
  8. <link rel="prev" href="key_value.html">
  9. <link rel="up" href="index.html">
  10. <link rel="next" href="extension.html">
  11. </head>
  12. <body>
  13. <h1><img src="../../../../boost.png" alt="Boost logo" align=
  14. "middle" width="277" height="86">Boost.Flyweight Tutorial: Configuring Boost.Flyweight</h1>
  15. <div class="prev_link"><a href="key_value.html"><img src="../prev.gif" alt="key-value flyweights" border="0"><br>
  16. Key-value flyweights
  17. </a></div>
  18. <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
  19. Boost.Flyweight tutorial
  20. </a></div>
  21. <div class="next_link"><a href="extension.html"><img src="../next.gif" alt="extending Boost.Flyweight" border="0"><br>
  22. Extending Boost.Flyweight
  23. </a></div><br clear="all" style="clear: all;">
  24. <hr>
  25. <h2>Contents</h2>
  26. <ul>
  27. <li><a href="#intro">Configurable aspects of Boost.Flyweight</a>
  28. <ul>
  29. <li><a href="#free_order_template">Free-order template parameter interface</a></li>
  30. <li><a href="#header_inclusion">Header inclusion</a></li>
  31. </ul>
  32. </li>
  33. <li><a href="#tagging">Tagging</a></li>
  34. <li><a href="#factories">Factory specification</a>
  35. <ul>
  36. <li><a href="#factory_types">Types involved in the configuration of factories</a></li>
  37. <li><a href="#hashed_factory"><code>hashed_factory</code></a></li>
  38. <li><a href="#set_factory"><code>set_factory</code></a></li>
  39. <li><a href="#assoc_container_factory"><code>assoc_container_factory</code></a></li>
  40. </ul>
  41. </li>
  42. <li><a href="#holders">Holder specification</a>
  43. <ul>
  44. <li><a href="#static_holder"><code>static_holder</code></a></li>
  45. <li><a href="#intermodule_holder"><code>intermodule_holder</code></a></li>
  46. </ul>
  47. </li>
  48. <li><a href="#locking">Locking policies</a>
  49. <ul>
  50. <li><a href="#simple_locking"><code>simple_locking</code></a></li>
  51. <li><a href="#no_locking"><code>no_locking</code></a></li>
  52. </ul>
  53. </li>
  54. <li><a href="#tracking">Tracking policies</a>
  55. <ul>
  56. <li><a href="#refcounted"><code>refcounted</code></a></li>
  57. <li><a href="#no_tracking"><code>no_tracking</code></a></li>
  58. </ul>
  59. </li>
  60. </ul>
  61. <h2><a name="intro">Configurable aspects of Boost.Flyweight</a></h2>
  62. <p>
  63. Most of the time, <code>flyweight</code> default configuration is just good
  64. enough and the user need not care about further tuning of her <code>flyweight</code>
  65. instantiations; however, when the necessity for more control over Boost.Flyweight
  66. behavior arises, comprehensive mechanisms are provided to select, configure and
  67. even extend the following implementation aspects:
  68. <ul>
  69. <li><a href="#tagging">Type tagging</a>.</li>
  70. <li><a href="#factories">Factory</a> used to store the shared values
  71. <code>flyweight</code> objects refer to.
  72. </li>
  73. <li><a href="#holders">Mechanism of instantiation</a> of the flyweight factory.</li>
  74. <li>Internal <a href="#locking">synchronization mechanism</a> for access to
  75. the internal factory in multithreaded environments.</li>
  76. <li><a href="#tracking">Tracking policy</a> controlling how a value stored in the
  77. factory is handled when all the flyweight objects associated to it are
  78. destroyed.
  79. </li>
  80. </ul>
  81. </p>
  82. <h3><a name="free_order_template">Free-order template parameter interface</a></h3>
  83. <p>
  84. The <code>flyweight</code> class template features a "smart" specification
  85. interface by which the configuration aspects can be provided as optional template arguments
  86. in whatever order the user pleases. For instance, a tagged <code>flyweight</code>
  87. of <code>std::string</code>s with a <a href="#set_factory">set-based factory</a> and
  88. <a href="#no_tracking">no tracking</a> can be specified like this:
  89. </p>
  90. <blockquote><pre>
  91. <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span> <span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>label_t</span><span class=special>&gt;,</span> <span class=identifier>set_factory</span><span class=special>&lt;&gt;,</span> <span class=identifier>no_tracking</span> <span class=special>&gt;</span>
  92. </pre></blockquote>
  93. <p>
  94. or like this:
  95. </p>
  96. <blockquote><pre>
  97. <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span> <span class=identifier>no_tracking</span><span class=special>,</span> <span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>label_t</span><span class=special>&gt;,</span> <span class=identifier>set_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
  98. </pre></blockquote>
  99. <p>
  100. or in any other order; only <code>std::string</code> is required to occupy
  101. the first place in the specification.
  102. </p>
  103. <h3><a name="header_inclusion">Header inclusion</a></h3>
  104. <p>
  105. The example code shown at the <a href="basics.html#intro">introductory section</a>
  106. uses the
  107. <a href="../reference/index.html#flyweight_synopsis"><code>"boost/flyweight.hpp"</code></a>
  108. convenience header, which simply includes the headers for the class template
  109. <code>flyweight</code> and its default configuration components:
  110. </p>
  111. <blockquote><pre>
  112. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// class template flyweight</span>
  113. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>hashed_factory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// hashed flyweight factory</span>
  114. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>static_holder</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// regular factory instantiation</span>
  115. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>simple_locking</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// simple locking policy</span>
  116. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>refcounted</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// refcounting tracking policy</span>
  117. </pre></blockquote>
  118. <p>
  119. When using components other than these, their specific headers must be
  120. explicitly included.
  121. </p>
  122. <h2><a name="tagging">Tagging</a></h2>
  123. <p>
  124. Consider the following two types:
  125. </p>
  126. <blockquote><pre>
  127. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=identifier>name_t</span><span class=special>;</span>
  128. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=identifier>ip_address_t</span><span class=special>;</span>
  129. </pre></blockquote>
  130. <p>
  131. Although technically both types are identical, this is so by virtue of
  132. coincidence, as there is no sensible relation between names and IP addresses.
  133. Internally, the fact that <code>name_t</code> and <code>ip_address_t</code>
  134. are the same flyweight type causes values of both classes to be stored together
  135. in the same flyweight factory, although their respective ranges
  136. are not expected to overlap. <i>Tagging</i> can be used to turn these
  137. into really different types:
  138. </p>
  139. <blockquote><pre>
  140. <span class=keyword>struct</span> <span class=identifier>name_tag</span><span class=special>{};</span>
  141. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>name_tag</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>name_t</span><span class=special>;</span>
  142. <span class=keyword>struct</span> <span class=identifier>ip_address_tag</span><span class=special>{};</span>
  143. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>ip_address_tag</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>ip_address_t</span><span class=special>;</span>
  144. </pre></blockquote>
  145. <p>
  146. Now, <code>name_t</code> and <code>ip_address_t</code> are different
  147. flyweight classes having separate factories each. Tags are a purely syntactic
  148. device: any type can be used for tagging inside the <code>tag</code>
  149. construct, though good style recommends using tag classes with
  150. descriptive names which are local to the context where the flyweight type
  151. is being defined.
  152. </p>
  153. <h2><a name="factories">Factory specification</a></h2>
  154. <p>
  155. <code>flyweight</code> uses a type of internal component called
  156. <i>factory</i> whose purpose is to store and retrieve the different values
  157. flyweight objects refer to at a given time. By default, a factory based on
  158. a hashed container is used, so that <code>flyweight&lt;T&gt;</code> is
  159. actually equivalent to
  160. </p>
  161. <blockquote><pre>
  162. <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>hashed_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
  163. </pre></blockquote>
  164. <p>
  165. where <code>hashed_factory</code> is a so-called <i>factory specifier</i>.
  166. Boost.Flyweight provides several predefined factory specifiers, which not
  167. only let the user select the specific type of factory used, but also
  168. accept their own template arguments to customize each factory.
  169. </p>
  170. <h3><a name="factory_types">Types involved in the configuration of factories</a></h3>
  171. <p>
  172. A given <code>flyweight</code> instantiation has associated
  173. <code>flyweight::key_type</code>
  174. and <code>flyweight::value_type</code> types (which are equal in the case
  175. of regular flyweights or different if <a href="key_value.html">key-value
  176. flyweights</a>
  177. are used). Also, there is an internal <code>Entry</code> type which
  178. corresponds to the type of the objects actually stored in the factory:
  179. <code>Entry</code> contains the shared <code>value_type</code> objects
  180. of <code>flyweight</code> as well a some internal bookkeeping information;
  181. also, <code>Entry</code> is implicitly convertible to
  182. <code>const key_type&amp;</code>, so that factories can rely on
  183. <code>key_type</code> to look up <code>Entrie</code>s. Since
  184. <code>Entry</code> is internal to the implementation of <code>flyweight</code>,
  185. it cannot be directly referred to by the user in the configuration of
  186. factories. Instead, the proxy
  187. <a href="../../../mpl/doc/refmanual/placeholders.html"><i>placeholder</i></a>
  188. type <code>boost::mpl::_1</code> can be used.
  189. </p>
  190. <h3><a name="hashed_factory"><code>hashed_factory</code></a></h3>
  191. <blockquote>
  192. <b>Header:</b> <a href="../reference/factories.html#hashed_factory_synopsis"><code>"boost/flyweight/hashed_factory.hpp"</code></a><br>
  193. <b>Syntax:</b> <code>hashed_factory&lt;[Hash[,Pred[,Allocator]]]&gt;</code>
  194. </blockquote>
  195. <p>
  196. This specifier, which Boost.Flyweight takes by default, controls the usage of a
  197. factory internally based in a hash container. Values are determined to be
  198. equivalent by means of the
  199. <a href="https://boost.org/sgi/stl/BinaryPredicate.html"><code>Binary
  200. Predicate</code></a> <code>Pred</code>, and indexed into the factory container
  201. using <code>Hash</code>, which is assumed to be a <i>hash function</i>,
  202. i.e. a
  203. <a href="https://boost.org/sgi/stl/UnaryFunction.html"><code>Unary
  204. Function</code></a> assigning to each value a hash identifier of
  205. type <code>std::size_t</code>. The <code>Allocator</code> parameter is
  206. used by the factory container for its memory allocation needs. The default
  207. types for these parameters are such that the expression
  208. </p>
  209. <blockquote><pre>
  210. <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>hashed_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
  211. </pre></blockquote>
  212. <p>
  213. is equivalent to
  214. </p>
  215. <blockquote><pre>
  216. <span class=identifier>flyweight</span><span class=special>&lt;</span>
  217. <span class=identifier>T</span><span class=special>,</span>
  218. <span class=identifier>hashed_factory</span><span class=special>&lt;</span>
  219. <span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&gt;,</span>
  220. <span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&gt;,</span>
  221. <span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span>
  222. <span class=special>&gt;</span>
  223. <span class=special>&gt;</span>
  224. </pre></blockquote>
  225. <p>
  226. where <code>key_type</code> is the key type of the flyweight and
  227. <code>boost::mpl::_1</code>, as explained above, stands for the
  228. internal <code>Entry</code> type of the elements stored in the factory.
  229. Suppose we would like to configure <code>hashed_factory</code> for
  230. a <code>std::string</code> flyweight with
  231. a special hash predicate <code>special_hash</code> and a custom allocator
  232. <code>custom_allocator</code>; this would be specified as follows:
  233. </p>
  234. <blockquote><pre>
  235. <span class=identifier>flyweight</span><span class=special>&lt;</span>
  236. <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
  237. <span class=identifier>hashed_factory</span><span class=special>&lt;</span>
  238. <span class=identifier>special_hash</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;,</span>
  239. <span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&gt;,</span>
  240. <span class=identifier>custom_allocator</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span>
  241. <span class=special>&gt;</span>
  242. <span class=special>&gt;</span>
  243. </pre></blockquote>
  244. <h3><a name="set_factory"><code>set_factory</code></a></h3>
  245. <blockquote>
  246. <b>Header:</b> <a href="../reference/factories.html#set_factory_synopsis"><code>"boost/flyweight/set_factory.hpp"</code></a><br>
  247. <b>Syntax:</b> <code>set_factory&lt;[Compare[,Allocator]]&gt;</code>
  248. </blockquote>
  249. <p>
  250. <code>set_factory</code> resorts to an <code>std::set</code>-like ordered
  251. container for the implementation of the flyweight factory.
  252. <code>Compare</code> must be a
  253. <a href="https://boost.org/sgi/stl/StrictWeakOrdering.html"><code>Strict
  254. Weak Ordering</code></a> on the value type <code>flyweight</code> is
  255. acting upon; as is customary with STL ordered containers, two values
  256. are considered equivalent if none is less than the other according to <code>Pred</code>.
  257. <code>Allocator</code> is an allocator type passed along to the factory
  258. internal container for its memory-related tasks. When default parameters are
  259. used, the expression
  260. </p>
  261. <blockquote><pre>
  262. <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>set_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
  263. </pre></blockquote>
  264. <p>
  265. is equivalent to
  266. </p>
  267. <blockquote><pre>
  268. <span class=identifier>flyweight</span><span class=special>&lt;</span>
  269. <span class=identifier>T</span><span class=special>,</span>
  270. <span class=identifier>set_factory</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>key_type</span><span class=special>&gt;,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span> <span class=special>&gt;</span>
  271. <span class=special>&gt;</span>
  272. </pre></blockquote>
  273. <p>
  274. Usual tradeoffs arising in the comparison of ordered and hashed containers
  275. also apply when choosing between <code>set_factory</code> and
  276. <code>hashed_factory</code>:
  277. so, set-based lookup and insertion of values are generally slower than those based on hashing,
  278. but the latter can be affected by pathological worst-case scenarios with very
  279. poor performance.
  280. </p>
  281. <h3><a name="assoc_container_factory"><code>assoc_container_factory</code></a></h3>
  282. <blockquote>
  283. <b>Header:</b> <a href="../reference/factories.html#assoc_container_factory_synopsis"><code>"boost/flyweight/assoc_container_factory.hpp"</code></a><br>
  284. <b>Syntax:</b> <code>assoc_container_factory&lt;ContainerSpecifier&gt;</code>
  285. </blockquote>
  286. <p>
  287. This specifier can be seen as a generalization of
  288. <code>hashed_factory</code> and <code>set_factory</code> where the user
  289. supplies the exact type of container on which the factory is based.
  290. The way in which the container is specified might seem at first a little
  291. daunting to those unfamiliar with the
  292. <a href="../../../mpl/doc/index.html">Boost MPL Library</a>:
  293. <code>ContainerSpecifier</code> must be an
  294. <a href="lambda_expressions.html"><code>MPL Lambda
  295. Expression</code></a> such that, when invoked with the
  296. types <code>Entry</code> and <code>key_type</code>
  297. explained <a href="#factory_types">above</a>, it produces the type of
  298. a container of <code>Entry</code> elements satisfying the following
  299. requirements:
  300. <ol>
  301. <li>The container type must be a model of
  302. <a href="https://boost.org/sgi/stl/UniqueAssociativeContainer.html"><code>Unique
  303. Associative Container</code></a> where equivalence of <code>Entry</code>s
  304. is determined by the <code>key_type</code> values the entries are convertible
  305. to .
  306. </li>
  307. <li>The container must be <i>stable</i>, i.e. its iterators must remain valid
  308. after insert and erase operations. Note that this condition is not met by
  309. many existing implementations of hashed containers that invalidate iterators
  310. upon a rehashing operation.
  311. </li>
  312. </ol>
  313. </p>
  314. <p>
  315. Let us see what a container specifier looks like with an example.
  316. Suppose we have our own ordered container like the following:
  317. </p>
  318. <blockquote><pre>
  319. <span class=keyword>template</span><span class=special>&lt;</span>
  320. <span class=keyword>typename</span> <span class=identifier>Elem</span><span class=special>,</span>
  321. <span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>Elem</span><span class=special>&gt;,</span>
  322. <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>Elem</span><span class=special>&gt;</span>
  323. <span class=special>&gt;</span>
  324. <span class=keyword>class</span> <span class=identifier>ultrafast_set</span>
  325. <span class=special>{</span>
  326. <span class=special>...</span>
  327. <span class=special>};</span>
  328. </pre></blockquote>
  329. <p>
  330. Then <code>ultrafast_set</code> can be plugged into
  331. <code>assoc_container_factory</code> like this:
  332. </p>
  333. <blockquote><pre>
  334. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span>
  335. <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
  336. <span class=identifier>assoc_container_factory</span><span class=special>&lt;</span>
  337. <span class=comment>// MPL lambda expression follows</span>
  338. <b><span class=identifier>ultrafast_set</span><span class=special>&lt;</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=special>&gt;</span></b>
  339. <span class=special>&gt;</span>
  340. <span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
  341. </pre></blockquote>
  342. <p>
  343. As has been explained, <code>mpl::_1</code> is a so-called MPL
  344. placeholder standing as a "slot" to be replaced with
  345. <code>Entry</code> by the internal machinery of Boost.Flyweight.
  346. Note that we have not
  347. relied on the default argument of <code>ultrafast_set</code> for
  348. <code>Compare</code> and instead we have provided a fixed
  349. instantiation for <code>std::string</code>: this is so because
  350. requirements state that the type with which <code>ContainerSpecifier</code>
  351. will be filled in internally is convertible to <code>const key_type&amp;</code>
  352. (here <code>const std::string&amp;</code>), and it is based on
  353. <code>key_type</code> that lookup and equivalence of entries
  354. should be determined. On the other hand,
  355. the default argument for the <code>Allocator</code> parameter works
  356. just fine, as is more apparent if we write it down explicitly:
  357. </p>
  358. <blockquote><pre>
  359. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span>
  360. <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
  361. <span class=identifier>assoc_container_factory</span><span class=special>&lt;</span>
  362. <b><span class=identifier>ultrafast_set</span><span class=special>&lt;</span>
  363. <span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>,</span>
  364. <span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;,</span>
  365. <span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span>
  366. <span class=special>&gt;</span>
  367. <span class=special>&gt;</span></b>
  368. <span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
  369. </pre></blockquote>
  370. <h2><a name="holders">Holder specification</a></h2>
  371. <p>
  372. Each flyweight type, that is, each distinct instantiation of the class
  373. template <code>flyweight</code>, is associated with exactly one factory
  374. object. In most cases, how this factory object is created is of little
  375. importance to the user of Boost.Flyweight, but there are special
  376. circumstances where control of this aspect is necessary. An internal
  377. component called <i>holder</i> is in charge of instantiating the
  378. factory class and some other internal information; this component is
  379. stipulated by means of a <i>holder specifier</i>, <code>static_holder</code>
  380. being the default one.
  381. </p>
  382. <h3><a name="static_holder"><code>static_holder</code></a></h3>
  383. <blockquote>
  384. <b>Header:</b> <a href="../reference/holders.html#static_holder_synopsis"><code>"boost/flyweight/static_holder.hpp"</code></a><br>
  385. <b>Syntax:</b> <code>static_holder</code>
  386. </blockquote>
  387. <p>
  388. This the default holder specifier of Boost.Flyweight, and produces
  389. holders where the unique factory lives as a local static variable of the
  390. program.
  391. </p>
  392. <h3><a name="intermodule_holder"><code>intermodule_holder</code></a></h3>
  393. <blockquote>
  394. <b>Header:</b> <a href="../reference/holders.html#intermodule_holder_synopsis"><code>"boost/flyweight/intermodule_holder.hpp"</code></a><br>
  395. <b>Syntax:</b> <code>intermodule_holder</code>
  396. </blockquote>
  397. <p>
  398. In most C++ environments, static variables do not mix well with
  399. dynamically loaded modules in the sense that instances of the same
  400. static variable can be duplicated across different modules, even
  401. though by definition the variable should be unique. In many
  402. cases, this duplication goes unnoticed if the modules do not communicate
  403. between each other using the affected types, but consider this
  404. case where such communication does happen:
  405. </p>
  406. <blockquote><pre>
  407. <span class=comment>// module 1</span>
  408. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
  409. <span class=comment>// produce_string is exported so that it can be dynamically
  410. // linked</span>
  411. <span class=identifier>flyweight_string</span> <span class=identifier>produce_string</span><span class=special>()</span>
  412. <span class=special>{</span>
  413. <span class=keyword>return</span> <span class=identifier>flyweight_string</span><span class=special>(</span><span class=string>&quot;boost&quot;</span><span class=special>);</span>
  414. <span class=special>}</span>
  415. </pre></blockquote>
  416. <blockquote><pre>
  417. <span class=comment>// main program</span>
  418. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
  419. <span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
  420. <span class=special>{</span>
  421. <span class=special>...</span> <span class=comment>// import module 1</span>
  422. <span class=identifier>flyweight_string</span> <span class=identifier>str1</span><span class=special>=</span><span class=identifier>produce_string</span><span class=special>();</span>
  423. <span class=identifier>flyweight_string</span> <span class=identifier>str2</span><span class=special>(</span><span class=string>&quot;boost&quot;</span><span class=special>);</span>
  424. <span class=identifier>assert</span><span class=special>(</span><span class=identifier>str1</span><span class=special>==</span><span class=identifier>str2</span><span class=special>);</span>
  425. <span class=special>}</span>
  426. </pre></blockquote>
  427. <p>
  428. In many environments, this program results in an assertion
  429. failure because the flyweight factory object used
  430. by <code>flyweight_string</code> as seen within module 1 is
  431. not the same factory object as seen within the main program: hence
  432. the value representations internally pointed to by <code>str1</code>
  433. and <code>str2</code> will differ and will be mistakenly
  434. considered as not equal. Many other problems might arise
  435. due to factory duplication, including undefined behavior.
  436. </p>
  437. <p>
  438. <code>intermodule_holder</code> specifies a factory holder which
  439. is capable of avoiding the duplication problem and ensuring that
  440. all modules of a program are using the same factory instance.
  441. To fix the example above, it suffices to redefine
  442. <code>flyweight_string</code> in both modules as:
  443. </p>
  444. <blockquote><pre>
  445. <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier><b>intermodule_holder</b></span><span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
  446. </pre></blockquote>
  447. <p>
  448. <code>intermodule_holder</code> is considerably more onerous than
  449. <code>static_holder</code> in terms of compilation times and
  450. introduces a non-negligible overhead at program start-up, so its use
  451. should be reserved to the situations where it is really necessary.
  452. </p>
  453. <h2><a name="locking">Locking policies</a></h2>
  454. <p>
  455. The internal factory associated to each <code>flyweight</code>
  456. type is a shared resource and as such access to it must be properly
  457. synchronized in multithreaded environments. A <i>locking policy</i>
  458. specifies the synchronization mechanisms to be used for this purpose.
  459. </p>
  460. <h3><a name="simple_locking"><code>simple_locking</code></a></h3>
  461. <blockquote>
  462. <b>Header:</b> <a href="../reference/locking.html#simple_locking_synopsis"><code>"boost/flyweight/simple_locking.hpp"</code></a><br>
  463. <b>Syntax:</b> <code>simple_locking</code>
  464. </blockquote>
  465. <p>
  466. This is the default locking policy. It specifies the simplest native
  467. synchronization primitives provided by the operating system, whenever
  468. available.
  469. </p>
  470. <h3><a name="no_locking"><code>no_locking</code></a></h3>
  471. <blockquote>
  472. <b>Header:</b> <a href="../reference/locking.html#no_locking_synopsis"><code>"boost/flyweight/no_locking.hpp"</code></a><br>
  473. <b>Syntax:</b> <code>no_locking</code>
  474. </blockquote>
  475. <p>
  476. No synchronization is enforced so that irrestricted internal access
  477. to the implementation shared resources is allowed.
  478. Selecting <code>no_locking</code> results in somewhat faster execution than
  479. the default <code>simple_locking</code>, but it renders the type
  480. thread-unsafe, which can have catastrophic consequences.
  481. This policy should not be used except in single-threaded environments or
  482. when there is an absolute guarantee that the particular <code>flyweight</code>
  483. type will not be used in a concurrent scenario.
  484. </p>
  485. <h2><a name="tracking">Tracking policies</a></h2>
  486. <p>
  487. A <i>tracking policy</i> controls the lifetimes of the <code>flyweight</code>
  488. objects and can act based on this information. For instance, a suitable
  489. tracking mechanism can determine when a given value stored in the factory
  490. can be safely erased because it is no longer referenced by any
  491. <code>flyweight</code>; this is precisely what the default tracking policy,
  492. <code>refcounted</code>, does.
  493. </p>
  494. <h3><a name="refcounted"><code>refcounted</code></a></h3>
  495. <blockquote>
  496. <b>Header:</b> <a href="../reference/tracking.html#refcounted_synopsis"><code>"boost/flyweight/refcounted.hpp"</code></a><br>
  497. <b>Syntax:</b> <code>refcounted</code>
  498. </blockquote>
  499. <p>
  500. This tracking policy determines that values stored in the factory be
  501. equipped with reference counting mechanisms so that a factory entry is
  502. erased when the last <code>flyweight</code> object associated to it
  503. is destroyed.
  504. </p>
  505. <h3><a name="no_tracking"><code>no_tracking</code></a></h3>
  506. <blockquote>
  507. <b>Header:</b> <a href="../reference/tracking.html#no_tracking_synopsis"><code>"boost/flyweight/no_tracking.hpp"</code></a><br>
  508. <b>Syntax:</b> <code>no_tracking</code>
  509. </blockquote>
  510. <p>
  511. No flyweight tracking is done when this policy is selected, which implies
  512. that the values stored in the factory remain in it until program termination.
  513. As compared with <code>refcounted</code>, <code>no_tracking</code> presents
  514. advantages and drawbacks. The benefits are:
  515. <ul>
  516. <li>Non-tracked flyweight objects are faster to pass around than refcounted ones.</li>
  517. <li>There is some reduction in memory usage due to the
  518. absence of reference counters.</li>
  519. </ul>
  520. whereas potential drawbacks of using <code>no_tracking</code> include:
  521. <ul>
  522. <li>The number of unused entries stored in the factory can keep growing
  523. during the program lifetime, which can become a problem for certain
  524. patterns of flyweight creation where the set of active values "drifts"
  525. over time.</li>
  526. <li>There can be a potential delay during program termination, since
  527. it is then when all the factory entries get destroyed at once.</li>
  528. </ul>
  529. </p>
  530. <hr>
  531. <div class="prev_link"><a href="key_value.html"><img src="../prev.gif" alt="key-value flyweights" border="0"><br>
  532. Key-value flyweights
  533. </a></div>
  534. <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
  535. Boost.Flyweight tutorial
  536. </a></div>
  537. <div class="next_link"><a href="extension.html"><img src="../next.gif" alt="extending Boost.Flyweight" border="0"><br>
  538. Extending Boost.Flyweight
  539. </a></div><br clear="all" style="clear: all;">
  540. <br>
  541. <p>Revised April 24th 2019</p>
  542. <p>&copy; Copyright 2006-2019 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
  543. Distributed under the Boost Software
  544. License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
  545. LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
  546. http://www.boost.org/LICENSE_1_0.txt</a>)
  547. </p>
  548. </body>
  549. </html>