Author: alai04 Date: Thu Apr 9 01:46:49 2009 New Revision: 239 Added: trunk/libs/flyweight/example/ trunk/libs/flyweight/example/Jamfile.v2 trunk/libs/flyweight/example/basic.cpp trunk/libs/flyweight/example/composite.cpp trunk/libs/flyweight/example/custom_factory.cpp trunk/libs/flyweight/example/fibonacci.cpp trunk/libs/flyweight/example/html.cpp trunk/libs/flyweight/example/key_value.cpp trunk/libs/flyweight/example/perf.cpp trunk/libs/flyweight/test/ trunk/libs/flyweight/test/Jamfile.v2 trunk/libs/flyweight/test/heavy_objects.hpp trunk/libs/flyweight/test/intermod_holder_dll.cpp trunk/libs/flyweight/test/intermod_holder_dll.hpp trunk/libs/flyweight/test/test_all_main.cpp trunk/libs/flyweight/test/test_assoc_cont_fact_main.cpp trunk/libs/flyweight/test/test_assoc_cont_factory.cpp trunk/libs/flyweight/test/test_assoc_cont_factory.hpp trunk/libs/flyweight/test/test_basic.cpp trunk/libs/flyweight/test/test_basic.hpp trunk/libs/flyweight/test/test_basic_main.cpp trunk/libs/flyweight/test/test_basic_template.hpp trunk/libs/flyweight/test/test_custom_factory.cpp trunk/libs/flyweight/test/test_custom_factory.hpp trunk/libs/flyweight/test/test_custom_factory_main.cpp trunk/libs/flyweight/test/test_init.cpp trunk/libs/flyweight/test/test_init.hpp trunk/libs/flyweight/test/test_init_main.cpp trunk/libs/flyweight/test/test_intermod_holder.cpp trunk/libs/flyweight/test/test_intermod_holder.hpp trunk/libs/flyweight/test/test_intermod_holder_main.cpp trunk/libs/flyweight/test/test_multictor.cpp trunk/libs/flyweight/test/test_multictor.hpp trunk/libs/flyweight/test/test_multictor_main.cpp trunk/libs/flyweight/test/test_no_locking.cpp trunk/libs/flyweight/test/test_no_locking.hpp trunk/libs/flyweight/test/test_no_locking_main.cpp trunk/libs/flyweight/test/test_no_tracking.cpp trunk/libs/flyweight/test/test_no_tracking.hpp trunk/libs/flyweight/test/test_no_tracking_main.cpp trunk/libs/flyweight/test/test_set_factory.cpp trunk/libs/flyweight/test/test_set_factory.hpp trunk/libs/flyweight/test/test_set_factory_main.cpp Modified: trunk/glossary/glossary.txt trunk/libs/flyweight/doc/examples.html trunk/libs/flyweight/doc/performance.html trunk/libs/flyweight/doc/reference/factories.html trunk/libs/flyweight/doc/reference/flyweight.html trunk/libs/flyweight/doc/reference/holders.html trunk/libs/flyweight/doc/reference/locking.html trunk/libs/flyweight/doc/reference/tracking.html trunk/libs/flyweight/doc/tutorial/configuration.html trunk/libs/flyweight/doc/tutorial/extension.html trunk/libs/flyweight/doc/tutorial/key_value.html trunk/libs/flyweight/doc/tutorial/lambda_expressions.html trunk/libs/flyweight/doc/tutorial/technical.html Log: 校对 flyweight 文 Modified: trunk/glossary/glossary.txt ============================================================================== --- trunk/glossary/glossary.txt (original) +++ trunk/glossary/glossary.txt Thu Apr 9 01:46:49 2009 @@ -128,6 +128,9 @@ callable transform 可调用变换 pass-through transform 直通变换 + 5) flyweight //alai04 + memoization 暗记法 + f) misc 其它 rationale 理论注记 原理 // jinq Modified: trunk/libs/flyweight/doc/examples.html ============================================================================== --- trunk/libs/flyweight/doc/examples.html (original) +++ trunk/libs/flyweight/doc/examples.html Thu Apr 9 01:46:49 2009 @@ -229,7 +229,7 @@ - <li><a href="#example2">Example 2: key-value flyweights</a></li>+ <li><a href="#example2">Example 2: key-value flyweights 例2:键-值 flyweight</a></li>
@@ -238,7 +238,7 @@- <li><a href="#example3">Example 3: flyweights and the composite pattern</a></li> + <li><a href="#example3">Example 3: flyweights and the composite pattern 例3:flyweight和组合模式</a></li>
@@ -247,7 +247,7 @@ - <li><a href="#example4">Example 4: formatted text processing</a></li>+ <li><a href="#example4">Example 4: formatted text processing 例 4:格式化文本处理</a></li>
@@ -256,7 +256,7 @@ - <li><a href="#example5">Example 5: flyweight-based memoization</a></li>+ <li><a href="#example5">Example 5: flyweight-based memoization 例 5:基于flyweight的暗记法</a></li>
@@ -265,7 +265,7 @@ - <li><a href="#example6">Example 6: performance comparison</a></li>+ <li><a href="#example6">Example 6: performance comparison 例6:性能 比较</a></li>
@@ -274,7 +274,7 @@ - <li><a href="#example7">Example 7: custom factory</a></li>+ <li><a href="#example7">Example 7: custom factory 例7:定制工厂 </a></li>
@@ -606,7 +606,7 @@ enconding and HTML entities (e.g. "&copy;" for (c)) are not properlyhandled. Improving the parsing code is left as an exercise to the reader.</p>
-<p>为简洁起见,该程序的HTML分析功能是粗糙的:例如,没有结束标记的元素(比如 <BR>),字符编码和HTML实体字符(比如 "&copy;" 代表 (c))不能适当的处 理。改进这个分析程序留给读者作为练习。 +<p>为简洁起见,该程序的HTML分析功能是粗糙的:例如,没有结束标记的元素(比如 <BR>),字符编码和HTML实体字符(比如 "&copy;" 代表 (c))等不能被正确 地处理。改进这个分析程序留给读者作为练习。
</p> @@ -617,7 +617,7 @@-<h2><a name="example5">Example 5: flyweight-based memoization 例5:基 于flyweight的memoization</a></h2> +<h2><a name="example5">Example 5: flyweight-based memoization 例5:基 于flyweight的暗记法</a></h2>
@@ -655,7 +655,7 @@-<p><a href="http://en.wikipedia.org/wiki/Memoization";>Memoization</a> 是一种 将计算结果缓存起来供以后复用的优化技术;例如这种优化技术在进行递归的数值计算 时可以极大的提升性能。通过将一个函数的memoized调用看作类型 <code>flyweight<key_value<int,compute_f> ></code>的值,<a href="tutorial/key_value.html">键-值 flyweights</a>可以用来实现数值函数 <i>f</i>的memoization化,在这里<code>compute_f</code>类型在它的构造函数 <code>compute_f::compute_f(int)</code>里计算<i>f</i>(<i>n</i>)。例如,<a href="http://mathworld.wolfram.com/FibonacciNumber.html";>Fibonacci 数</a>可 以像这样使用memoization来计算。</p> +<p><a href="http://en.wikipedia.org/wiki/Memoization";>暗记法 Memoization</a> 是一种将计算结果缓存起来供以后复用的优化技术;例如这种 优化技术在进行递归的数值计算时可以极大的提升性能。通过将一个函数的暗记化调用 看作类型<code>flyweight<key_value<int,compute_f> ></code>的 值,<a href="tutorial/key_value.html">键-值 flyweights</a>可以用来实现数值函 数<i>f</i>的暗记化,在这里<code>compute_f</code>类型在它的构造函数 <code>compute_f::compute_f(int)</code>里计算<i>f</i>(<i>n</i>)。例如,<a href="http://mathworld.wolfram.com/FibonacciNumber.html";>Fibonacci 数</a>可 以像这样使用暗记法来计算。</p>
@@ -803,7 +803,7 @@-这个例子演示了怎样编写并使用一个自定义工厂类。这个"罗嗦的"工厂输出 Boost.Flyweight对它的公共接口的调用的信息,以此帮助用户可视化工厂的使用方 式。</p> +这个例子演示了怎样编写并使用一个自定义工厂类。这个"罗嗦的"工厂输出 Boost.Flyweight对它的公共接口的调用的信息,以此帮助用户查看工厂的使用方式。 </p>
Modified: trunk/libs/flyweight/doc/performance.html ============================================================================== --- trunk/libs/flyweight/doc/performance.html (original) +++ trunk/libs/flyweight/doc/performance.html Thu Apr 9 01:46:49 2009 @@ -40,7 +40,6 @@ <link rel="next" href="examples.html"></head> - <body> @@ -810,7 +809,7 @@<p>判断2个<code>flyweight</code>对象是否相等降为判断它们所关联的值的<span style="font-style: italic;">地址</span>是否相同;通常情况下,这个操作要远远 快过比较底层的值。<span style="color: rgb(0, 0, 0);">当 </span>flyweight<span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 0, 0);">对象 -代表的是那些出现在组合模式的应用程序的复杂的值时</span></span><span style="color: rgb(0, 0, 0);">这个方面特别重要。</span> +代表的是那些出现在</span></span><a href="examples.html#example3"><i>组合模 式</i></a><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 0, 0);">的应用程序的复杂的值时</span></span><span style="color: rgb(0, 0, 0);">这个方面特别重要。</span>
</p> @@ -908,8 +907,8 @@ text</a>version of Project Gutenberg edition of <a href="http://www.gutenberg.org/etext/2000";><i>Don
Quijote</i></a> (2.04 MB).</p>-<p>实际测试的类型和上面列出来的不完全一致,而是修改后的可以跟踪内存分配的版 本用以分析。该程序分析一个文本文件并将结果保存在一个单词数组里然后进行各种操 作,涉及到前面讨论的Boost.Flyweight的各种使用环境。我们使用<i><a href="http://www.gutenberg.org/etext/2000";><i>Don -Quijote</i></a></i>的Project Gutenberg版本的<a href="http://www.gutenberg.org/dirs/etext99/2donq10.txt";>纯文本</a>格式作为 我们的文本文件。 +<p>实际测试的类型和上面列出来的不完全一致,而是修改后的可以跟踪内存分配的版 本用以分析。该程序分析一个文本文件并将结果保存在一个单词数组里然后进行各种操 作,涉及到<a href="performance.html#time">前面</a>讨论的Boost.Flyweight的各 种使用环境。我们使用<i><a href="http://www.gutenberg.org/etext/2000";><i>Don +Quijote</i></a></i>的Project Gutenberg版本的<a href="http://www.gutenberg.org/dirs/etext99/2donq10.txt";>纯文本</a>格式 (2.04 MB)作为我们的文本文件。
</p> Modified: trunk/libs/flyweight/doc/reference/factories.html ============================================================================== --- trunk/libs/flyweight/doc/reference/factories.html (original)+++ trunk/libs/flyweight/doc/reference/factories.html Thu Apr 9 01:46:49 2009
@@ -40,7 +40,6 @@ <link rel="next" href="holders.html"></head> - <body> @@ -628,7 +627,7 @@-<p><big><code>hashed_factory_fwd.hpp</code></big>前置声明了类模板<big><a href="factories.html#hashed_factory_class"><code>hashed_factory_class</code></a></big>和 <big><a href="factories.html#hashed_factory"><code>hashed_factory</code></a></big> +<p><big><code>hashed_factory_fwd.hpp</code></big>前向声明了类模板<big><a href="factories.html#hashed_factory_class"><code>hashed_factory_class</code></a></big>和 <big><a href="factories.html#hashed_factory"><code>hashed_factory</code></a></big>
</p> @@ -655,7 +654,7 @@-<p><big><code>hashed_factory_class</code></big>是一个用哈西容器实现的<a href="#factory">工厂</a> +<p><big><code>hashed_factory_class</code></big>是一个用哈希容器实现的<a href="#factory">工厂</a>
</p> @@ -718,9 +717,9 @@象返回相同的值。与工厂相关的<big><code>Key</code></big>上的相等关系是由 <big><code>Pred</code></big>得 出。<big><code>Hash</code></big>和<big><code>Pred</code></big>的默认参数分 别是<big><a href="../../../functional/hash/index.html"><code>boost::hash<Key></code></a></big> 和 <code><big>std::equal_to<Key></big></code>。 <big><code>Allocator</code></big>必 -须是满足<b>[lib.allocator.requirements]</b>里的相关C++要求的 <big><code>Entry</code></big>对 +须是满足C++标准<b>[lib.allocator.requirements]</b>中的相关要求的 <big><code>Entry</code></big>对 象的分配器。默认的参数是 <big><code>std::allocator<Entry></code><code></code></big>。 <big><code>hashed_factory_class</code></big>基 -于的内部哈西容器是用 <big><code>Hash</code></big>,<big><code>Pred</code></big> 和 +于的内部哈希容器是用 <big><code>Hash</code></big>,<big><code>Pred</code></big> 和
<big><code>Allocator</code></big>类型的默认初始化对象创建的。 </p> @@ -917,8 +916,8 @@ 弱序</a>的类型。如果对<big><code>Compare</code></big>类 型的<big><code>c</code></big>类来说<big><code>!c(x,y)&&!c(y, x)</code></big>,2个<big><code>Key</code>s-<code>x</code></big> 和<big><code>y</code></big>被看作相等<code>。 </code><big><code>Compare</code></big>的默认参数是 <big><code>std::less<Key></code></big>。 <big><code>Allocator</code></big>必须是满足 <b>[lib.allocator.requirements]</b>里 -的相关C++要求的<big><code>Entry</code></big>对象的分配器。默认的参数是 <big><code>std::allocator<Entry></code></big><code>。 </code><code></code><code></code><big><code>set_factory_class</code></big>基 +<code>x</code></big> 和<big><code>y</code></big>被看作相等<code>。 </code><big><code>Compare</code></big>的默认参数是 <big><code>std::less<Key></code></big>。 <big><code>Allocator</code></big>必须是满足C++标准 <b>[lib.allocator.requirements]</b>里 +的相关要求的<big><code>Entry</code></big>对象的分配器。默认的参数是 <big><code>std::allocator<Entry></code></big><code>。 </code><code></code><code></code><big><code>set_factory_class</code></big>基 于的内部容器是用<big><code>Compare</code></big> 和 <big><code>Allocator</code></big>类
型的默认初始化对象创建的。<code></code> </p> @@ -1050,7 +1049,7 @@ -<p><big><code>assoc_container_factory_fwd.hpp</code></big>前置声明了类模 +<p><big><code>assoc_container_factory_fwd.hpp</code></big>前向声明了类模板<big><a href="factories.html#assoc_container_factory_class"><code>assoc_container_factory_class</code></a></big> 和 <big><a href="factories.html#assoc_container_factory"><code>assoc_container_factory</code></a></big>
</p> Modified: trunk/libs/flyweight/doc/reference/flyweight.html ============================================================================== --- trunk/libs/flyweight/doc/reference/flyweight.html (original)+++ trunk/libs/flyweight/doc/reference/flyweight.html Thu Apr 9 01:46:49 2009
@@ -79,7 +79,6 @@ <link rel="next" href="key_value.html"></head> - <body> @@ -1107,7 +1106,7 @@ <span style="font-weight: bold;"> -注意:</span>同步执行这个函数是线程不安全的 +注意:</span>同步执行这个函数不是线程安全的 </blockquote> @@ -1151,7 +1150,7 @@ <span style="font-weight: bold;">-要求:</span><big><code>key_type</code></big>可以<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html";>默认构造</a>。 <br> +要求:</span><big><code>key_type</code></big>可以<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html";>缺省构造</a>。 <br>
@@ -2207,7 +2206,7 @@ is 5.<br>-效果:全局定义这个宏来设置<big><code>flyweight</code></big><a href="#fwd_ctors">构造函数</a>的最大参数个数,默认是5 +效果:全局定义这个宏来设置<big><code>flyweight</code></big><a href="#fwd_ctors">前转构造函数</a>的最大参数个数,默认是5
</blockquote> Modified: trunk/libs/flyweight/doc/reference/holders.html ============================================================================== --- trunk/libs/flyweight/doc/reference/holders.html (original) +++ trunk/libs/flyweight/doc/reference/holders.html Thu Apr 9 01:46:49 2009 @@ -40,7 +40,6 @@ <link rel="next" href="locking.html"></head> - <body> @@ -366,7 +365,7 @@ and <a href="#static_holder"><code>static_holder</code></a>.</p>-<p><big><code>static_holder_fwd.hpp</code></big>前置声明<big><a href="holders.html#static_holder_class"><code>static_holder_class</code></a></big> 和 <big><a href="holders.html#static_holder"><code>static_holder</code></a></big>。 +<p><big><code>static_holder_fwd.hpp</code></big>前向声明<big><a href="holders.html#static_holder_class"><code>static_holder_class</code></a></big> 和 <big><a href="holders.html#static_holder"><code>static_holder</code></a></big>。
</p> @@ -442,7 +441,7 @@<a href="#intermodule_holder_class"><code>intermodule_holder_class</code></a>
and <a href="#intermodule_holder"><code>intermodule_holder</code></a>.</p>-<p><big><code>intermodule_holder_fwd.hpp</code></big>前置声明<big><a href="holders.html#intermodule_holder_class"><code>intermodule_holder_class</code></a> </big>和 <big><a href="holders.html#intermodule_holder"><code>intermodule_holder</code></a></big> +<p><big><code>intermodule_holder_fwd.hpp</code></big>前向声明<big><a href="holders.html#intermodule_holder_class"><code>intermodule_holder_class</code></a> </big>和 <big><a href="holders.html#intermodule_holder"><code>intermodule_holder</code></a></big>
</p> Modified: trunk/libs/flyweight/doc/reference/locking.html ============================================================================== --- trunk/libs/flyweight/doc/reference/locking.html (original) +++ trunk/libs/flyweight/doc/reference/locking.html Thu Apr 9 01:46:49 2009 @@ -40,7 +40,6 @@ <link rel="next" href="tracking.html"></head> - <body> @@ -547,7 +546,7 @@ <a href="#simple_locking"><code>simple_locking</code></a>.</p>-<p><big><code>simple_locking_fwd.hpp</code></big>前置声明类<big><a href="locking.html#simple_locking"><code>simple_locking</code></a></big> +<p><big><code>simple_locking_fwd.hpp</code></big>前向声明类<big><a href="locking.html#simple_locking"><code>simple_locking</code></a></big>
</p> @@ -612,7 +611,7 @@ <a href="#no_locking"><code>no_locking</code></a>.</p>-<p><big><code>no_locking_fwd.hpp</code></big>前置申明类<big><a href="locking.html#no_locking"><code>no_locking</code></a></big>。 +<p><big><code>no_locking_fwd.hpp</code></big>前向声明类<big><a href="locking.html#no_locking"><code>no_locking</code></a></big>。
</p> Modified: trunk/libs/flyweight/doc/reference/tracking.html ============================================================================== --- trunk/libs/flyweight/doc/reference/tracking.html (original)+++ trunk/libs/flyweight/doc/reference/tracking.html Thu Apr 9 01:46:49 2009
@@ -40,7 +40,6 @@ <link rel="next" href="../performance.html"></head> - <body> @@ -540,7 +539,7 @@ <a href="#refcounted"><code>refcounted</code></a>.</p>-<p><big><code>refcounted_fwd.hpp</code></big>前置声明了类<big><a href="tracking.html#refcounted"><code>refcounted</code></a></big> +<p><big><code>refcounted_fwd.hpp</code></big>前向声明了类<big><a href="tracking.html#refcounted"><code>refcounted</code></a></big>
</p> @@ -608,7 +607,7 @@ <a href="#no_tracking"><code>no_tracking</code></a>.</p>-<p><big><code>no_tracking_fwd.hpp</code></big>前置声明了类<big><a href="tracking.html#no_tracking"><code>no_tracking</code></a></big> +<p><big><code>no_tracking_fwd.hpp</code></big>前向声明了类<big><a href="tracking.html#no_tracking"><code>no_tracking</code></a></big>
</p> Modified: trunk/libs/flyweight/doc/tutorial/configuration.html ============================================================================== --- trunk/libs/flyweight/doc/tutorial/configuration.html (original)+++ trunk/libs/flyweight/doc/tutorial/configuration.html Thu Apr 9 01:46:49 2009
@@ -40,7 +40,6 @@ <link rel="next" href="extension.html"></head> - <body> @@ -257,8 +256,8 @@ <p>-绝大多数时候,<code>flyweight</code>的默认配置足够好,并且用户不需要关对心 对<code>flyweight</code>实 -例的进一步调整;然而,当有必要对Boost.Flyweight的行为进行更多的控制时,提供 了全面的机制可供挑选,配置甚至扩展如下的实现方面。</p> +绝大多数时候,<code>flyweight</code>的默认配置足够好,并且用户不需要关心对 <code>flyweight</code>实 +例的进一步调整;然而,当有必要对Boost.Flyweight的行为进行更多的控制时,我们 提供了全面的机制可供挑选,进行配置以及甚至扩展如下的实现方面。</p>
@@ -267,35 +266,32 @@ <li><a href="#tagging">Type tagging</a>. - 类型标注</li> + <a href="configuration.html#tagging">类型标注</a></li> <li><a href="#factories">Factory</a> used to store the shared values <code>flyweight</code> objects -refer to. 用来存储被flyweight对象所引用的共享的值的工厂 </li>+refer to. 用来存储被flyweight对象所引用的共享的值的<a href="configuration.html#factories">工厂</a> </li>
<li><a href="#holders">Mechanism of instantiation</a> -of the flyweight factory. flyweight工厂的实例化机制</li>+of the flyweight factory. flyweight工厂的<a href="configuration.html#holders">实例化机制</a></li>
<li>Internal <a href="#locking">synchronization mechanism</a> for access to the internal factory in multithreaded -environments. 在多线程环境下对内部工厂访问时的内部同步机制</li>+environments. 在多线程环境下对内部工厂访问时的内部<a href="configuration.html#locking">同步机制</a></li>
<li><a href="#tracking">Tracking policy</a> controlling how a value stored in the factory is handled when all the flyweight objects associated to it are destroyed. - 跟踪策略控制当所有关联到存储在工厂中的值的flyweight - - - <div id=":3b" class="ii gt"><wbr>对象都销毁后它该怎 -么处理。</div>+ <a href="configuration.html#tracking">跟踪策略</a>控制当所有关联到存 储在工厂中的值的flyweight对象都销毁后它该怎
+么处理。 @@ -326,8 +322,7 @@ <p> <code>flyweight</code>类模板的特性是有一个"智能的"接口, -通过这个接口配置界面作为可选的模板参数以用户喜欢的任意顺-序提供。例如,一个<code></code>同时拥有tagged,<a href="configuration.html#set_factory">set-based factory</a>和<a href="configuration.html#no_tracking">no tracking</a>等几 +通过这个接口配用户可以以任何喜欢的顺序来提供可选的模板参数。例如,一个 <code></code>同时拥有tagged,<a href="configuration.html#set_factory">set-based factory</a>和<a href="configuration.html#no_tracking">no tracking</a>等几
项配置界面的<code>std::string</code>s类的<code>flyweight</code>可 以按这样的方式指定:</p> @@ -395,7 +390,7 @@ -<p><a href="basics.html#intro">简介章节</a>中展示的示例代码 +<p><a href="basics.html#intro">简介一节</a>中展示的示例代码使用<a href="../reference/index.html#flyweight_synopsis"><code>"boost/flyweight.hpp"</code></a>简 易头文件,它只是简单的包含了<code>flyweight</code>类模板和它的默认配置组件 的头文件。
</p> @@ -420,7 +415,7 @@ <p> -当使用除此之外其它的组件时,必须显示包含特定的头文件。 +当使用除此之外其它的组件时,必须显式包含特定的头文件。 </p> @@ -593,11 +588,10 @@ <p>一个给定的<code>flyweight</code>实例有相关的 <code>flyweight::key_type</code>和<code>flyweight::value_type</code>类
-型(它们在普通flyweights情况下是相同的在<a href="key_value.html">键-值-flyweights</a>时不同的)。与此同时,还有一个内部的<code>Entry</code>类型相 当
+型(它们在普通flyweights情况下是相同的,而在<a href="key_value.html">键-值+flyweights</a>时是不同的)。与此同时,还有一个内部的<code>Entry</code>类型 相当 于实际存储在工厂里的对象的类型:<code>Entry</code>包含 <code>flyweight</code>对
-象所共享的<code>value_type</code>,还包括一些内部<span class="mn">簿 -记</span>记信息;而且,<code>Entry</code>可以隐式转换成<code>const+象所共享的<code>value_type</code>,还包括一些内部<span class="mn">簿 </span>记信息;而且,<code>Entry</code>可以隐式转换成<code>const
key_type&,</code>因此工厂可以依赖<code>key_type</code>来 查找<code>Entrie</code>s。既然<code>Entry</code>是<code>flyweight</code>的内部实现细节,它不能在配置工厂的时候被用户直接引用。可以用代理的<i><a href="../../../mpl/doc/refmanual/placeholders.html"><i>占
@@ -644,11 +638,7 @@<p>这是Boost.Flyweight默认使用的描述符,它控制一个在内部基于哈希容器的工厂 的使用。<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html";>二元谓词 </a><big><code>Pred</code></big>用
来判断值是否相等,<big><code>Hash</code></big>用来计算出到这个工厂容 -器的索引<code></code>,<br> - - --假定它是一个<i style="font-style: italic;">哈希</i><span style="font-style: italic;">函数</span>,就是说,为每个值分配一个 <big><code>std::size_t</code></big>类 +器的索引<code></code>,假定它是一个<i style="font-style: italic;">哈希 </i><span style="font-style: italic;">函数</span>,即一个为每个值分配一个 <big><code>std::size_t</code></big>类
型的哈希标识符的<a href="http://www.sgi.com/tech/stl/UnaryFunction.html";>一 元函数</a>。<big><code>Allocator</code></big>参 数被工厂容器用来进行所需的内存分配。这些参数的默认类型的表达式 @@ -763,7 +753,7 @@ 类似于<big><code>std::set</code></big>的有序容器来实现flyweight工厂。<big><code>Compare</code></big>对于 <big><code>flyweight</code></big>用 到的值类型必须是<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html";>严
-格弱序</a>的;按照STL有序容器的惯例,根据<big><code>Pred</code></big>来+格弱序</a>的;按照STL有序容器的惯例,根据<code>Compare</code><font size="-1">(译注:原文有误)</font>来 判断如果没有一个值比另一个值小那么这两个值被认为是相等的。 <big><code>Allocator</code><code></code></big>是 一个传递给工厂内部容器的分配器类型,用来处理内存相关的任务。当使用默认的参 数时,表达式
</p> @@ -971,7 +961,7 @@<p>正如已经描述的那样,<big><code>mpl::_1</code></big>的是一个所谓的MPL占位 符,代表一个被Boost.Flyweight的内部机制用<big><code>Entry</code></big>替换掉 的"插槽" 。注意我们没有使用<big><code>ultrafast_set</code></big>的 默认<big><code>Compare</code></big>参数而是提供了一个 <code>std::string</code>类的不变实例: 这是因为规范声明 <big><code>ContainerSpecifier</code></big>内部将要填充的类型可以转换为 <big><code>const key_type&</code></big>(这里是<big><code>const std::string&</code></big>),而且entries的查找和判等是基于 <big><code>key_type</code></big>来决定的<code>。</code> -另一方面,<big><code>Allocator</code></big>参数的默认值可以很好的工作,如果 我们显示得写出来会更明显: +另一方面,<big><code>Allocator</code></big>参数的默认值可以很好的工作,如果 我们显式地写出来会更明显:
</p> @@ -1065,7 +1055,7 @@-<p>在大多数C++环境里,静态变量不能与动态加载的模块很好的协同原因在于同一个 静态变量可以在不同的模块中重复,即使根据定义这个变量应 +<p>在大多数C++环境里,静态变量不能与动态加载的模块很好地协同,原因在于同一 个静态变量可以在不同的模块中重复,即使根据定义这个变量应 该是唯一的。在很多情况下,如果模块之间不通过受影响的类型来交互的话是不会注 意到这个重复的,但是考虑一下这种通讯确实发生的例子:
</p> @@ -1149,7 +1139,7 @@-<p><big><code>intermodule_holder</code></big>修在编译时要比 <big><code>static_holder</code></big>笨重的多并且导致不可忽视的程序启动时的 额外开销,因此只有当真有必要时才使用它。 +<p><big><code>intermodule_holder</code></big>修在编译时要比 <big><code>static_holder</code></big>笨重的多并且导致不可忽视的程序启动时的 额外开销,因此只有真的有必要时才使用它。
</p> @@ -1193,7 +1183,7 @@ -<p>这是默认的锁定机制。只要可行它就使用操作系统所提供的最简的本机同步原语。+<p>这是默认的锁定机制。只要可行它就使用操作系统所提供的最简单的原生同步原 语。
</p> @@ -1253,8 +1243,7 @@ <p>跟踪策略控制着<code>flyweight</code>对象的生存期。例如,一种合适的跟踪策略 可以决定当工厂里的某个给 -定的值没有被任何<code>flyweight</code>对象引用的时候它可以被安全的清理;这 正是默认的跟踪策略<code>refcounted</code>,
-所做的事情</p>+定的值没有被任何<code>flyweight</code>对象引用的时候它可以被安全的清理;这 正是默认的跟踪策略<code>refcounted</code>所做的事情</p>
@@ -1281,7 +1270,7 @@ <p>-这种跟踪策略决定存储在工厂里的值配有引用计数机制,于是当关联到该工厂条目的 最后一个<code>flyweight</code>对 +这种跟踪策略决定存储在工厂里的值配有引用计数机制,于是当关联到该工厂某个条 目的最后一个<code>flyweight</code>对
象被销毁的时候,该条目将被清理。</p> @@ -1379,8 +1368,7 @@ -存储在工厂中没用的条目的数量在程序运行期间可能持续增长,这对某些类型 flyweight的创建可能成为问题,这里活动的值会不时的&
-ldquo;漂移"。+存储在工厂中没用的条目的数量在程序运行期间可能持续增长,这对于特定的 flyweight模式的创建可能会成为问题,在那些特定模式中活动值的集合会不时的"漂移 "。
<ul> Modified: trunk/libs/flyweight/doc/tutorial/extension.html ============================================================================== --- trunk/libs/flyweight/doc/tutorial/extension.html (original)+++ trunk/libs/flyweight/doc/tutorial/extension.html Thu Apr 9 01:46:49 2009
@@ -14,7 +14,6 @@ <link rel="up" href="index.html"> <link rel="next" href="technical.html"></head> - <body><h1><img src="../../../../boost.png" alt="Boost logo" align="middle" height="86" width="277">Boost.Flyweight
@@ -141,7 +140,7 @@In a way, factories resemble unique associative containers like <code>std::set</code>,
though their expected interface is much more concise:</p>-<p><span class="mn">在某种程度上,工厂类似于唯一关联容器比如 </span><big><code>std::set</code></big><span class="mn">,然而它们期待的界面 要简洁的多:</span> +<p><span class="mn">在某种程度上,工厂类似于唯一关联容器比如 </span><big><code>std::set</code></big><span class="mn">,然而它们要求的接口 要简洁的多:</span>
</p> <blockquote> @@ -308,7 +307,7 @@ to do this tagging:</p><p>还有最后一个细节:为了实现<big><code>flyweight</code></big>的<a href="configuration.html#free_order_template">自由顺序模板参数</a><a href="configuration.html#free_order_template">接口</a>, -必须显示的标记一个工厂描述符,这样它才能同其它类型的描述符区分开。 Boost.Flyweight提供3种标记的办法:<a href="configuration.html#free_order_template"><code></code></a> +必须显式地标记一个工厂描述符,这样它才能同其它类型的描述符区分开。 Boost.Flyweight提供3种标记的办法:<a href="configuration.html#free_order_template"><code></code></a>
</p> <ol> @@ -328,7 +327,7 @@ </li><li>Specialize a special class template called <a href="../reference/factories.html#is_factory"><code>is_factory</code></a>: - <p>专门化一个叫做<big><a href="../reference/factories.html#is_factory"><code>is_factory</code></a></big>的 + <p>特化一个叫做<big><a href="../reference/factories.html#is_factory"><code>is_factory</code></a></big>的
特殊类型。</p> <blockquote> @@ -342,8 +341,8 @@ <li>The third mechanism, which is the least intrusive, consistsin wrapping the specifier inside the <a href="../reference/factories.html#factory_construct"><code>factory</code></a>
construct:- <p>第三种办法,这是对boost名字空间入侵性最小的办法,是包装描述符到 <big><a href="../reference/factories.html#factory_construct"><code>factory</code></a></big>的
-构造函数里:</p>+ <p>第三种办法,这是对boost名字空间入侵性最小的办法,是把描述符包到 <big><a href="../reference/factories.html#factory_construct"><code>factory</code></a></big>结
+构中:</p> <blockquote><pre><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">flyweight</span><span class="special">/</span><span class="identifier">factory_tag</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span><br><br><span class="keyword">typedef</span> <span class="identifier">flyweight</span><span class="special"><</span><br><span class="identifier"> std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span><br><span class="identifier"><b> factory</b></span><span class="special"><</span><span class="identifier">custom_factory_specifier</span><span class="special">></span><br><span class="special">></span> <span class="identifier">flyweight_string</span><span class="special">;</span>
@@ -373,8 +372,8 @@ giving access to a unique instance of a given type <code>C</code>:</p> -<p><big>holder</big>类的静态成员函数<big><code>get()</code></big>提 -供到给定类型<big><code>C</code></big>的+<p><big>holder</big>是这样一个类,它的静态成员函数 <big><code>get()</code></big>提
+供了到给定类型<big><code>C</code></big>的 唯一实例的访问: </p> Modified: trunk/libs/flyweight/doc/tutorial/key_value.html ============================================================================== --- trunk/libs/flyweight/doc/tutorial/key_value.html (original)+++ trunk/libs/flyweight/doc/tutorial/key_value.html Thu Apr 9 01:46:49 2009
@@ -27,7 +27,6 @@ <link rel="next" href="configuration.html"></head> - <body> @@ -180,7 +179,7 @@ example, we can explicity specify both types using the<a href="../reference/key_value.html#key_value_construct"><code>key_value</code></a>
construct:</p>-<p><code>flyweight<T></code>让这种键和值之间的界限模糊了,因为它既让 <code>T</code>作为键类型同时也让<code>T</code>作为关联的值类型。当这种做法效 率不高时,正如在我们这个纹理的例子里,我们可以通过使用<a href="../reference/key_value.html#key_value_construct"><code>key_value</code></a>构 造来显示的指明键和值的类型。</p> +<p><code>flyweight<T></code>让这种键和值之间的界限模糊了,因为它既让 <code>T</code>作为键类型同时也让<code>T</code>作为关联的值类型。当这种做法效 率不高时,正如在我们这个纹理的例子里,我们可以通过使用<a href="../reference/key_value.html#key_value_construct"><code>key_value</code></a>构 造来明确指出键和值的类型。</p>
@@ -323,8 +322,8 @@ assigned a <code>T</code> object is also <code>T</code> required to be<a href="http://www.sgi.com/tech/stl/Assignable.html";><code>Assignable</code></a>.</p>
<p>-对于<a href="basics.html#requirements">普通的flyweights</a>来说许多施加在 T上的需求在键-值<code>flyweight<key_value<K,T> ></code>的情况下 转移到了键类型上。现在是<code>K</code>必须是<a href="http://www.sgi.com/tech/stl/Assignable.html";>可赋值的</a>,<a href="http://www.sgi.com/tech/stl/EqualityComparable.html";>可断等的</a>还有 必须和<a href="../../../functional/hash/index.html">Boost.Hash</a>互操作,其 中,判等和哈西兼容性是Boost.Flyweight的默认内部工厂施加的要求,如果这个工厂 -被配置或者用用户的类型来替换这些要求是可以改变的。保留在<code>T</code>上的 唯一要求是它必须能从<code>K</code>构造而来;只有在flyweight被直接赋予一个 <code>T</code>对象时要求<code>T</code>必须是<a href="http://www.sgi.com/tech/stl/Assignable.html";>可赋值的</a>。</p> +对于<a href="basics.html#requirements">普通的flyweights</a>来说许多施加在 T上的需求在键-值<code>flyweight<key_value<K,T> ></code>的情况下 转移到了键类型上。现在是<code>K</code>必须是<a href="http://www.sgi.com/tech/stl/Assignable.html";>可赋值的</a>,<a href="http://www.sgi.com/tech/stl/EqualityComparable.html";>可判等的</a>还有 必须和<a href="../../../functional/hash/index.html">Boost.Hash</a>互操作,其 中,判等和哈希兼容性是Boost.Flyweight的默认内部工厂施加的要求,如果这个工厂 +被配置或者被用户的类型所替换,这些要求是可以改变的。保留在<code>T</code>上 的唯一要求是它必须能从<code>K</code>构造而来;只有在flyweight被直接赋予一个 <code>T</code>对象时才要求<code>T</code>必须是<a href="http://www.sgi.com/tech/stl/Assignable.html";>可赋值的</a>。</p>
Modified: trunk/libs/flyweight/doc/tutorial/lambda_expressions.html ============================================================================== --- trunk/libs/flyweight/doc/tutorial/lambda_expressions.html (original)+++ trunk/libs/flyweight/doc/tutorial/lambda_expressions.html Thu Apr 9 01:46:49 2009
@@ -14,7 +14,6 @@ <link rel="up" href="index.html"> <link rel="next" href="../reference/index.html"></head> - <body><h1><img src="../../../../boost.png" alt="Boost logo" align="middle" height="86" width="277">Boost.Flyweight
@@ -67,9 +66,7 @@ template:</p><p>Boost.Flyweight定义的描述符非常依赖于<a href="../../../mpl/doc/index.html">Boost MPL 库</a>定义的<a href="../../../mpl/doc/refmanual/lambda-expression.html"><code>Lambda </code>表 -达式<code></code></a>这个概念。一个lambda表达式可以被认为是一个编译时的 &
-amp;-ldquo;类型函数",或者是一个用一串类型调用后反过来返回某个相关类型的实体(实 际上是一个具体类型)。例如考虑任意的一个类 +达式<code></code></a>这个概念。一个lambda表达式可以被认为是一个编译时的"类 型函数",或者是一个用一串类型调用后返回某个相关类型的实体(实际上是一个具体 类型)。例如考虑任意的一个类
模板: </p> Modified: trunk/libs/flyweight/doc/tutorial/technical.html ============================================================================== --- trunk/libs/flyweight/doc/tutorial/technical.html (original)+++ trunk/libs/flyweight/doc/tutorial/technical.html Thu Apr 9 01:46:49 2009
@@ -27,7 +27,6 @@ <link rel="next" href="lambda_expressions.html"></head> - <body> @@ -91,7 +90,7 @@ required by the C++ standard, in current practice dynamic initialization is completed before <code>main()</code> begins.</p>-<p>对任何给定的 <code><big>T</big>,</code><big><code>flyweight<T></code></big>类型维 护着一些类级别的或者静态数据,这些数据在类可以被使用之前需要被恰当的初始化。 Boost.Flyweight的内部机制保证:程序中某个 <big><code>flyweight<T></code></big>的实例首次使用之前静态数据的初始化 会自动进行,而且无论如何总是在程序启动顺序中所谓的<span style="font-style: italic;">动态初始化阶段</span>进行。虽然C++标准没严格要求,但是目前的做法是 动态初始化是在<big><code>main()</code></big>开始前就完成了。 +<p>对任何给定的 <code><big>T</big>,</code><big><code>flyweight<T></code></big>类型维 护着一些类级别的数据或者静态数据,这些数据在类可以被使用之前需要被恰当的初始 化。Boost.Flyweight的内部机制保证:程序中某个 <big><code>flyweight<T></code></big>的实例首次使用之前静态数据的初始化 会自动进行,而且无论如何总是在程序启动顺序中所谓的<span style="font-style: italic;">动态初始化阶段</span>进行。虽然C++标准没严格要求,但是目前的做法是 动态初始化是在<big><code>main()</code></big>开始前就完成了。
</p> @@ -150,7 +149,7 @@ static data initialization in a thread safe context before launching the threads:</p>-<p>这个例子中的全局的线程池启动了若干线程,每个线程内部都会使用 <code><big>flyweight<std::string></big></code>。静态数据初始化有可能并 发执行2次,如果2个线程都恰好第一次使用 <code><big>flyweight<std::string></big>:</code>Boost.Flyweight的初始 化没有考虑线程安全。因此,在启动这些线程之前,我们必须在一个线程安全的环境下 显示的处理好静态数据初始化 。 +<p>这个例子中的全局的线程池启动了若干线程,每个线程内部都会使用 <code><big>flyweight<std::string></big></code>。静态数据初始化有可能并 发执行2次,如果2个线程都恰好第一次使用 <code><big>flyweight<std::string></big>:</code>Boost.Flyweight的初始 化没有考虑线程安全。因此,在启动这些线程之前,我们必须在一个线程安全的环境下 显式地处理好静态数据的初始化 。
</p> Added: trunk/libs/flyweight/example/Jamfile.v2 ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/Jamfile.v2 Thu Apr 9 01:46:49 2009 @@ -0,0 +1,49 @@ +# Boost.Flyweight examples Jamfile +# +# Copyright 2006-2008 Joaqu n M L pez Mu oz. +# 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) +# +# See http://www.boost.org/libs/flyweight for library home page. + +project + : requirements + <os>LINUX:<threading>multi + ; + +exe basic + : basic.cpp + : <include>$(BOOST_ROOT) + ; + +exe composite + : composite.cpp + : <include>$(BOOST_ROOT) + ; + +exe custom_factory + : custom_factory.cpp + : <include>$(BOOST_ROOT) + ; + +exe fibonacci + : fibonacci.cpp + : <include>$(BOOST_ROOT) + ; + +exe html + : html.cpp + : <include>$(BOOST_ROOT) + ; + +exe key_value + : key_value.cpp + : <include>$(BOOST_ROOT) + ; + +exe perf + : perf.cpp + : <include>$(BOOST_ROOT) + : release + ; Added: trunk/libs/flyweight/example/basic.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/basic.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,152 @@ +/* Boost.Flyweight basic example. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/bind.hpp> +#include <boost/flyweight.hpp> +#include <algorithm> +#include <iostream> +#include <iterator> +#include <sstream> +#include <string> +#include <vector> + +using namespace boost::flyweights; + +/* Information associated to a given user of some massive system. + * first_name and last_name are turned into flyweights to leverage the + * implicit redundancy of names within the user community. + */ + +struct user_entry +{ + flyweight<std::string> first_name; + flyweight<std::string> last_name; + int age; + + user_entry(); + user_entry(const char* first_name,const char* last_name,int age); + user_entry(const user_entry& x); +}; + +/* flyweight<std::string> default ctor simply calls the default ctor of + * std::string. + */ + +user_entry::user_entry() +{} + +/* flyweight<std::string> is constructible from a const char* much as + * a std::string is. + */ + +user_entry::user_entry(const char* f,const char* l,int a): + first_name(f), + last_name(l), + age(a) +{} + +/* flyweight's are copyable and assignable --unlike std::string, + * copy and assignment of flyweight<std::string>s do not ever throw. + */ + +user_entry::user_entry(const user_entry& x): + first_name(x.first_name), + last_name(x.last_name), + age(x.age) +{} + +/* flyweight<std::string> has operator==,!=,<,>,<=,>= with the same + * semantics as those of std::string. + */ + +bool same_name(const user_entry& user1,const user_entry& user2) +{ + bool b=user1.first_name==user2.first_name && + user1.last_name==user2.last_name; + return b; +} + +/* operator<< forwards to the std::string overload */ + +std::ostream& operator<<(std::ostream& os,const user_entry& user) +{ + return os<<user.first_name<<" "<<user.last_name<<" "<<user.age; +} + +/* operator>> internally uses std::string's operator>> */ + +std::istream& operator>>(std::istream& is,user_entry& user) +{ + return is>>user.first_name>>user.last_name>>user.age; +} + +std::string full_name(const user_entry& user) +{ + std::string full; + + /* get() returns the underlying const std::string& */ + + full.reserve( + user.first_name.get().size()+user.last_name.get().size()+1); + + /* here, on the other hand, implicit conversion is used */ + + full+=user.first_name; + full+=" "; + full+=user.last_name; + + return full; +} + +/* flyweight<std::string> value is immutable, but a flyweight object can + * be assigned a different value. + */ ++void change_name(user_entry& user,const std::string& f,const std::string& l)
+{ + user.first_name=f; + user.last_name=l; +} + +int main() +{ + /* play a little with a vector of user_entry's */ + + std::string users_txt= + "olegh smith 31\n" + "john brown 28\n" + "anna jones 45\n" + "maria garcia 30\n" + "john fox 56\n" + "anna brown 19\n" + "thomas smith 46\n" + "andrew martin 28"; + + std::vector<user_entry> users; + std::istringstream iss(users_txt); + while(iss){ + user_entry u; + if(iss>>u)users.push_back(u); + } + + change_name(users[0],"oleg","smith"); + + user_entry anna("anna","jones",20); + std::replace_if( + users.begin(),users.end(), + boost::bind(same_name,_1,anna), + anna); + + std::copy( + users.begin(),users.end(), + std::ostream_iterator<user_entry>(std::cout,"\n")); + + return 0; +} Added: trunk/libs/flyweight/example/composite.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/composite.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,179 @@ +/* Boost.Flyweight example of a composite design. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/flyweight.hpp> +#include <boost/functional/hash.hpp> +#include <boost/tokenizer.hpp> +#include <boost/variant.hpp> +#include <boost/variant/apply_visitor.hpp> +#include <boost/variant/recursive_wrapper.hpp> +#include <iostream> +#include <stdexcept> +#include <string> +#include <vector> + +using namespace boost::flyweights; + +/* A node of a lisp-like list can be modeled as a boost::variant of + * 1. A string (primitive node) + * 2. A vector of nodes (embedded list) + * To save space, 2 is stored as a vector of flyweights. + * As is usual with recursive data structures, a node can be thought + * of also as a list. To close the flyweight circle, the final + * type list is a flyweight wrapper, so that the final structure can + * be described as follows in BNF-like style: + * + * list ::= flyweight<list_impl> + * list_impl ::= std::string | std::vector<list> + */ + +struct list_elems; + +typedef boost::variant< + std::string, + boost::recursive_wrapper<list_elems> +> list_impl; + +struct list_elems:std::vector<flyweight<list_impl> >{}; + +typedef flyweight<list_impl> list; + +/* list_impl must be hashable to be used by flyweight: If a + * node is a std::string, its hash resolves to that of the string; + * if it is a vector of nodes, we compute the hash by combining + * the *addresses* of the stored flyweights' associated values: this is + * consistent because flyweight equality implies equality of reference. + * Using this trick instead of hashing the node values themselves + * allow us to do the computation without recursively descending down + * through the entire data structure. + */ + +struct list_hasher:boost::static_visitor<std::size_t> +{ + std::size_t operator()(const std::string& str)const + { + boost::hash<std::string> h; + return h(str); + } + + std::size_t operator()( + const boost::recursive_wrapper<list_elems>& elmsw)const + { + const list_elems& elms=elmsw.get(); + std::size_t res=0; + for(list_elems::const_iterator it=elms.begin(),it_end=elms.end(); + it!=it_end;++it){ + const list_impl* p=&it->get(); + boost::hash_combine(res,p); + } + return res; + } +}; + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace boost{ +#endif + +std::size_t hash_value(const list_impl& limpl) +{ + return boost::apply_visitor(list_hasher(),limpl); +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace boost */ +#endif + +/* basic pretty printer with indentation according to the nesting level */ + +struct list_pretty_printer:boost::static_visitor<> +{ + list_pretty_printer():nest(0){} + + void operator()(const std::string& str) + { + indent(); + std::cout<<str<<"\n"; + } + + void operator()(const boost::recursive_wrapper<list_elems>& elmsw) + { + indent(); + std::cout<<"(\n"; + ++nest; + const list_elems& elms=elmsw.get(); + for(list_elems::const_iterator it=elms.begin(),it_end=elms.end(); + it!=it_end;++it){ + boost::apply_visitor(*this,it->get()); + } + --nest; + indent(); + std::cout<<")\n"; + } + +private: + void indent()const + { + for(int i=nest;i--;)std::cout<<" "; + } + + int nest; +}; + +void pretty_print(const list& l) +{ + list_pretty_printer pp; + boost::apply_visitor(pp,l.get()); +} + +/* list parser */ + +template<typename InputIterator> +list parse_list(InputIterator& first,InputIterator last,int nest) +{ + list_elems elms; + while(first!=last){ + std::string str=*first++; + if(str=="("){ + elms.push_back(parse_list(first,last,nest+1)); + } + else if(str==")"){ + if(nest==0)throw std::runtime_error("unmatched )"); + return list(elms); + } + else{ + elms.push_back(list(str)); + } + } + if(nest!=0)throw std::runtime_error("unmatched ("); + return list(elms); +} + +list parse_list(const std::string str) +{ + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + tokenizer tok(str,boost::char_separator<char>(" ","()")); + tokenizer::iterator begin=tok.begin(); + return parse_list(begin,tok.end(),0); +} + +int main() +{ + std::cout<<"enter list: "; + std::string str; + std::getline(std::cin,str); + try{ + pretty_print(parse_list(str)); + } + catch(const std::exception& e){ + std::cout<<"error: "<<e.what()<<"\n"; + } + + return 0; +} Added: trunk/libs/flyweight/example/custom_factory.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/custom_factory.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,122 @@ +/* Boost.Flyweight example of custom factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +/* We include the default components of Boost.Flyweight except the factory, + * which will be provided by ourselves. + */ +#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/factory_tag.hpp> +#include <boost/flyweight/static_holder.hpp> +#include <boost/flyweight/simple_locking.hpp> +#include <boost/flyweight/refcounted.hpp> +#include <boost/tokenizer.hpp> +#include <functional> +#include <iostream> +#include <set> + +using namespace boost::flyweights; + +/* custom factory based on std::set with some logging capabilities */ + +/* Entry is the type of the stored objects. Value is the type + * on which flyweight operates, that is, the T in flyweoght<T>. It + * is guaranteed that Entry implicitly converts to const Value&. + * The factory class could accept other template arguments (for + * instance, a comparison predicate for the values), we leave it like + * that for simplicity. + */ + +template<typename Entry,typename Key> +class verbose_factory_class +{ + /* Entry store. Since Entry is implicitly convertible to const Key&, + * we can directly use std::less<Key> as the comparer for std::set. + */ + + typedef std::set<Entry,std::less<Key> > store_type; + + store_type store; + +public: + typedef typename store_type::iterator handle_type; + + handle_type insert(const Entry& x) + { + /* locate equivalent entry or insert otherwise */ + + std::pair<handle_type, bool> p=store.insert(x); + if(p.second){ /* new entry */ + std::cout<<"new: "<<(const Key&)x<<std::endl; + } + else{ /* existing entry */ + std::cout<<"hit: "<<(const Key&)x<<std::endl; + } + return p.first; + } + + void erase(handle_type h) + { + std::cout<<"del: "<<(const Key&)*h<<std::endl; + store.erase(h); + } + + const Entry& entry(handle_type h) + { + return *h; /* handle_type is an iterator */ + } +}; + +/* Specifier for verbose_factory_class. The simplest way to tag + * this struct as a factory specifier, so that flyweight<> accepts it + * as such, is by deriving from boost::flyweights::factory_marker. + * See the documentation for info on alternative tagging methods. + */ + +struct verbose_factory: factory_marker +{ + template<typename Entry,typename Key> + struct apply + { + typedef verbose_factory_class<Entry,Key> type; + } ; +}; + +/* ready to use it */ + +typedef flyweight<std::string,verbose_factory> fw_string; + +int main() +{ + typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer; + + + std::string text= + "I celebrate myself, and sing myself, " + "And what I assume you shall assume, " + "For every atom belonging to me as good belongs to you. " + + "I loafe and invite my soul, " + "I lean and loafe at my ease observing a spear of summer grass. " + + "My tongue, every atom of my blood, form'd from this soil, this air, " + "Born here of parents born here from parents the same, and their " + " parents the same, " + "I, now thirty-seven years old in perfect health begin, " + "Hoping to cease not till death."; + + std::vector<fw_string> v; + + text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-")); + for(text_tokenizer::iterator it=tok.begin();it!=tok.end();){ + v.push_back(fw_string(*it++)); + } + + return 0; +} Added: trunk/libs/flyweight/example/fibonacci.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/fibonacci.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,58 @@ +/* Boost.Flyweight example of flyweight-based memoization. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/flyweight.hpp> +#include <boost/flyweight/key_value.hpp> +#include <boost/flyweight/no_tracking.hpp> +#include <boost/noncopyable.hpp> +#include <iostream> + +using namespace boost::flyweights; + +/* Memoized calculation of Fibonacci numbers */ + +/* This class takes an int n and calculates F(n) at construction time */ + +struct compute_fibonacci; + +/* A Fibonacci number can be modeled as a key-value flyweight + * We choose the no_tracking policy so that the calculations + * persist for future use throughout the program. See + * Tutorial: Configuring Boost.Flyweight: Tracking policies for + * further information on tracking policies. + */ + +typedef flyweight<key_value<int,compute_fibonacci>,no_tracking> fibonacci; + +/* Implementation of compute_fibonacci. Note that the construction + * of compute_fibonacci(n) uses fibonacci(n-1) and fibonacci(n-2), + * which effectively memoizes the computation. + */ + +struct compute_fibonacci:private boost::noncopyable +{ + compute_fibonacci(int n): + result(n==0?0:n==1?1:fibonacci(n-2).get()+fibonacci(n-1).get()) + {} + + operator int()const{return result;} + int result; +}; + +int main() +{ + /* list some Fibonacci numbers */ + + for(int n=0;n<40;++n){ + std::cout<<"F("<<n<<")="<<fibonacci(n)<<std::endl; + } + + return 0; +} Added: trunk/libs/flyweight/example/html.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/html.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,343 @@ +/* Boost.Flyweight example of flyweight-based formatted text processing. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/flyweight.hpp> +#include <boost/functional/hash.hpp> +#include <algorithm> +#include <cctype> +#include <cstdio> +#include <fstream> +#include <iostream> +#include <iterator> +#include <sstream> +#include <string> +#include <vector> + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{using ::exit;using ::tolower;} +#endif + +using namespace boost::flyweights; + +/* See the portability section of Boost.Hash at + * http://boost.org/doc/html/hash/portability.html + * for an explanation of the ADL-related workarounds. + */ + +namespace boost{ +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace flyweights{ +#endif + +/* We hash the various flyweight types used in the program hashing + * a *pointer* to their contents: this is consistent as equality of + * flyweights implies equality of references. + */ + +template<typename T> +std::size_t hash_value(const flyweight<T>& x) +{ + boost::hash<const T*> h; + return h(&x.get()); +} + +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace flyweights */ +#endif +} /* namespace boost */ + +/* An HTML tag consists of a name and optional properties of the form + * name1=value1 ... namen=valuen. We do not need to parse the properties + * for the purposes of the program, hence they are all stored in + * html_tag_data::properties in raw form. + */ + +struct html_tag_data +{ + std::string name; + std::string properties; +}; + +bool operator==(const html_tag_data& x,const html_tag_data& y) +{ + return x.name==y.name&&x.properties==y.properties; +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace boost{ +#endif + +std::size_t hash_value(const html_tag_data& x) +{ + std::size_t res=0; + boost::hash_combine(res,x.name); + boost::hash_combine(res,x.properties); + return res; +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace boost */ +#endif + +typedef flyweight<html_tag_data> html_tag; + +/* parse_tag is passed an iterator positioned at the first char of + * the tag after the opening '<' and returns, if succesful, a parsed tag + * and whether it is opening (<xx>) or closing (</xx>). + */ + +enum tag_type{opening,closing,failure}; + +struct parse_tag_res +{ + parse_tag_res(tag_type type_,const html_tag_data& tag_=html_tag_data()): + type(type_),tag(tag_){} + parse_tag_res(const parse_tag_res& x):type(x.type),tag(x.tag){} + + tag_type type; + html_tag tag; +}; + +template<typename ForwardIterator> +parse_tag_res parse_tag(ForwardIterator& first,ForwardIterator last) +{ + html_tag_data tag; + std::string buf; + bool in_quote=false; + for(ForwardIterator it=first;it!=last;){ + char ch=*it++; + if(ch=='>'&&!in_quote){ /* ignore '>'s if inside quotes */ + tag_type type; + std::string::size_type + bname=buf.find_first_not_of("\t\n\r "), + ename=bname==std::string::npos? + std::string::npos: + buf.find_first_of("\t\n\r ",bname), + bprop=ename==std::string::npos? + std::string::npos: + buf.find_first_not_of("\t\n\r ",ename); + if(bname==ename){ /* null name */ + return parse_tag_res(failure); + } + else if(buf[bname]=='/'){ /* closing tag */ + type=closing; + ++bname; + } + else type=opening; + tag.name=buf.substr(bname,ename-bname);+ std::transform( /* normalize tag name to lower case */
+ tag.name.begin(),tag.name.end(),tag.name.begin(), + (int(*)(int))std::tolower); + if(bprop!=std::string::npos){ + tag.properties=buf.substr(bprop,buf.size()); + }+ first=it; /* result good, consume the chars */
+ return parse_tag_res(type,tag); + } + else{ + if(ch=='"')in_quote=!in_quote; + buf+=ch; + } + } + return parse_tag_res(failure); /* end reached and found no '>' */ +} + +/* A character context is just a vector containing the tags enclosing the + * character, from the outermost level to the innermost. + */ + +typedef std::vector<html_tag> html_context_data; +typedef flyweight<html_context_data> html_context; + +/* A character is a char code plus its context. + */ + +struct character_data +{ + character_data(char code_=0,html_context context_=html_context()): + code(code_),context(context_){} + character_data(const character_data& x):code(x.code),context(x.context){} + + char code; + html_context context; +}; + +bool operator==(const character_data& x,const character_data& y) +{ + return x.code==y.code&&x.context==y.context; +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace boost{ +#endif + +std::size_t hash_value(const character_data& x) +{ + std::size_t res=0; + boost::hash_combine(res,x.code); + boost::hash_combine(res,x.context); + return res; +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace boost */ +#endif + +typedef flyweight<character_data> character; + +/* scan_html converts HTML code into a stream of contextualized characters. + */ + +template<typename ForwardIterator,typename OutputIterator>+void scan_html(ForwardIterator first,ForwardIterator last,OutputIterator out)
+{ + html_context_data context; + while(first!=last){ + if(*first=='<'){ /* tag found */ + ++first; + parse_tag_res res=parse_tag(first,last); + if(res.type==opening){ /* add to contex */ + context.push_back(res.tag); + continue; + }+ else if(res.type==closing){ /* remove from context */
+ /* Pop all tags from the innermost to the matching one; this takes + * care of missing </xx>s like vg. in <ul><li>hello</ul>. + */ + + for(html_context_data::reverse_iterator rit=context.rbegin(); + rit!=context.rend();++rit){ + if(rit->get().name==res.tag.get().name){ + context.erase(rit.base()-1,context.end()); + break; + } + } + continue; + } + } + *out++=character(*first++,html_context(context)); + } +} + +/* HTML-producing utilities */ + +void print_opening_tag(std::ostream& os,const html_tag_data& x) +{ + os<<"<"<<x.name; + if(!x.properties.empty())os<<" "<<x.properties; + os<<">"; +} + +void print_closing_tag(std::ostream& os,const html_tag_data& x) +{ + /* SGML declarations (beginning with '!') are not closed */ + + if(x.name[0]!='!')os<<"</"<<x.name<<">"; +} + +/* change_context takes contexts from and to with tags + * + * from<- c1 ... cn fn+1 ... fm + * to <- c1 ... cn tn+1 ... tk + * + * (that is, they share the first n tags, n might be 0), and + * produces code closing fm ... fn+1 and opening tn+1 ... tk. + */ + +template<typename OutputIterator> +void change_context( + const html_context_data& from,const html_context_data& to, + OutputIterator out) +{ + std::ostringstream oss; + html_context_data::const_iterator + it0=from.begin(), + it0_end=from.end(), + it1=to.begin(), + it1_end=to.end(); + for(;it0!=it0_end&&it1!=it1_end&&*it0==*it1;++it0,++it1); + while(it0_end!=it0)print_closing_tag(oss,*--it0_end); + while(it1!=it1_end)print_opening_tag(oss,*it1++); + std::string str=oss.str(); + std::copy(str.begin(),str.end(),out); +} + +/* produce_html is passed a bunch of contextualized characters and emits+ * the corresponding HTML. The algorithm is simple: tags are opened and closed
+ * as a result of the context from one character to the following changing. + */ + +template<typename ForwardIterator,typename OutputIterator>+void produce_html(ForwardIterator first,ForwardIterator last,OutputIterator out)
+{ + html_context context; + while(first!=last){ + if(first->get().context!=context){ + change_context(context,first->get().context,out); + context=first->get().context; + } + *out++=(first++)->get().code; + } + change_context(context,html_context(),out); /* close remaining context */ +} + +/* Without these explicit instantiations, MSVC++ 6.5/7.0 does not + * find some friend operators in certain contexts. + */ + +character dummy1; +html_tag dummy2; + +int main() +{ + std::cout<<"input html file: "; + std::string in; + std::getline(std::cin,in); + std::ifstream ifs(in.c_str()); + if(!ifs){ + std::cout<<"can't open "<<in<<std::endl; + std::exit(EXIT_FAILURE); + } + typedef std::istreambuf_iterator<char> istrbuf_iterator; + std::vector<char> html_source; + std::copy( + istrbuf_iterator(ifs),istrbuf_iterator(), + std::back_inserter(html_source)); + + /* parse the HTML */ + + std::vector<character> scanned_html; + scan_html(+ html_source.begin(),html_source.end(),std::back_inserter(scanned_html));
+ + /* Now that we have the text as a vector of contextualized characters, + * we can shuffle it around and manipulate in almost any way we please. + * For instance, the following reverses the central portion of the doc. + */ + + std::reverse( + scanned_html.begin()+scanned_html.size()/4, + scanned_html.begin()+3*(scanned_html.size()/4)); + + /* emit the resulting HTML */ + + std::cout<<"output html file: "; + std::string out; + std::getline(std::cin,out); + std::ofstream ofs(out.c_str()); + if(!ofs){ + std::cout<<"can't open "<<out<<std::endl; + std::exit(EXIT_FAILURE); + } + typedef std::ostreambuf_iterator<char> ostrbuf_iterator;+ produce_html(scanned_html.begin(),scanned_html.end(),ostrbuf_iterator(ofs));
+ + return 0; +} Added: trunk/libs/flyweight/example/key_value.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/key_value.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,99 @@ +/* Boost.Flyweight example of use of key-value flyweights. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/array.hpp> +#include <boost/flyweight.hpp> +#include <boost/flyweight/key_value.hpp> +#include <cstdlib> +#include <iostream> +#include <string> +#include <vector> + +using namespace boost::flyweights; + +/* A class simulating a texture resource loaded from file */ + +class texture +{ +public: + texture(const std::string& filename):filename(filename) + { + std::cout<<"loaded "<<filename<<" file"<<std::endl; + } + + texture(const texture& x):filename(x.filename) + { + std::cout<<"texture["<<filename<<"] copied"<<std::endl; + } + + ~texture() + { + std::cout<<"unloaded "<<filename<<std::endl; + } + + const std::string& get_filename()const{return filename;} + + // rest of the interface + +private: + std::string filename; +}; + +/* key extractor of filename strings from textures */ + +struct texture_filename_extractor +{ + const std::string& operator()(const texture& x)const + { + return x.get_filename(); + } +}; + +/* texture flyweight */ + +typedef flyweight< + key_value<std::string,texture,texture_filename_extractor> +> texture_flyweight; + +int main() +{ + /* texture filenames */ + + const char* texture_filenames[]={ + "grass.texture","sand.texture","water.texture","wood.texture", + "granite.texture","cotton.texture","concrete.texture","carpet.texture" + }; + const int num_texture_filenames= + sizeof(texture_filenames)/sizeof(texture_filenames[0]); + + /* create a massive vector of textures */ + + std::cout<<"creating flyweights...\n"<<std::endl; + + std::vector<texture_flyweight> textures; + for(int i=0;i<50000;++i){ + textures.push_back(+ texture_flyweight(texture_filenames[std::rand()%num_texture_filenames]));
+ } + + /* Just for the sake of making use of the key extractor, + * assign some flyweights with texture objects rather than strings. + */ + + for(int j=0;j<50000;++j){ + textures.push_back( + texture_flyweight( + textures[std::rand()%textures.size()].get())); + } + + std::cout<<"\n"<<textures.size()<<" flyweights created\n"<<std::endl; + + return 0; +} Added: trunk/libs/flyweight/example/perf.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/example/perf.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,312 @@ +/* Boost.Flyweight example of performance comparison. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/hashed_factory.hpp> +#include <boost/flyweight/set_factory.hpp> +#include <boost/flyweight/static_holder.hpp> +#include <boost/flyweight/simple_locking.hpp> +#include <boost/flyweight/refcounted.hpp> +#include <boost/flyweight/no_tracking.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/tokenizer.hpp> +#include <algorithm> +#include <cstddef> +#include <cstdlib> +#include <ctime> +#include <fstream> +#include <iostream> +#include <numeric> +#include <sstream> +#include <string> +#include <vector> + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ +using ::clock; +using ::clock_t; +using ::exit; +} +#endif + +using namespace boost::flyweights; + +/* Instrumented allocator family keeping track of the memory in + * current use. + */ + +std::size_t count_allocator_mem=0; + +template<typename T> +class count_allocator +{ +public: + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + template<class U>struct rebind{typedef count_allocator<U> other;}; + + count_allocator(){} + count_allocator(const count_allocator<T>&){} + template<class U>count_allocator(const count_allocator<U>&,int=0){} + + pointer address(reference x)const{return &x;} + const_pointer address(const_reference x)const{return &x;} + + pointer allocate(size_type n,const void* =0) + { + pointer p=(T*)(new char[n*sizeof(T)]); + count_allocator_mem+=n*sizeof(T); + return p; + } + + void deallocate(void* p,size_type n) + { + count_allocator_mem-=n*sizeof(T); + delete [](char *)p; + } + + size_type max_size() const{return (size_type )(-1);} + void construct(pointer p,const T& val){new(p)T(val);} + void destroy(pointer p){p->~T();} + + friend bool operator==(const count_allocator&,const count_allocator&) + { + return true; + } + + friend bool operator!=(const count_allocator&,const count_allocator&) + { + return false; + } +}; + +template<> +class count_allocator<void> +{ +public: + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + template<class U>struct rebind{typedef count_allocator<U> other;}; +}; ++/* Define some count_allocator-based types and Boost.Flyweight components */
+ +typedef std::basic_string< + char,std::char_traits<char>,count_allocator<char> +> count_string; + +typedef hashed_factory< + boost::hash<boost::mpl::_2>, + std::equal_to<boost::mpl::_2>, + count_allocator<boost::mpl::_1> +> count_hashed_factory; + +typedef set_factory< + std::less<boost::mpl::_2>, + count_allocator<boost::mpl::_1> +> count_set_factory; + +/* Some additional utilities used by the test routine */ + +class timer +{ +public: + timer(){restart();} + + void restart(){t=std::clock();} + + void time(const char* str) + { + std::cout<<str<<": "<<(double)(std::clock()-t)/CLOCKS_PER_SEC<<" s\n"; + } + +private: + std::clock_t t; +}; + +template<typename T> +struct is_flyweight: + boost::mpl::false_{}; + +template< + typename T, + typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5 +> +struct is_flyweight<flyweight<T,Arg1,Arg2,Arg3,Arg4,Arg5> >: + boost::mpl::true_{}; + +struct length_adder +{ + std::size_t operator()(std::size_t n,const count_string& x)const + { + return n+x.size(); + } +}; + +/* Measure time and memory performance for a String, which is assumed + * to be either a plain string type or a string flyweight. + */ + +template<typename String> +struct test +{ + static std::size_t run(const std::string& file) + { + typedef std::vector<String,count_allocator<String> > count_vector; + + /* Define a tokenizer on std::istreambuf. */ + + typedef std::istreambuf_iterator<char> char_iterator; + typedef boost::tokenizer< + boost::char_separator<char>, + char_iterator + > tokenizer; + + std::ifstream ifs(file.c_str()); + if(!ifs){ + std::cout<<"can't open "<<file<<std::endl; + std::exit(EXIT_FAILURE); + } + + /* Initialization; tokenize using space and common punctuaction as + * separators, and keeping the separators. + */ + + timer t; + + tokenizer tok=tokenizer( + char_iterator(ifs),char_iterator(), + boost::char_separator<char>( + "", + "\t\n\r !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")); + count_vector txt; + for(tokenizer::iterator it=tok.begin();it!=tok.end();++it){ + txt.push_back(String(it->c_str())); + } + + t.time("initialization time"); + + /* Assignment */ + + t.restart(); + + count_vector txt2; + for(int i=0;i<10;++i){ + txt2.insert(txt2.end(),txt.begin(),txt.end()); + } + + t.time("assignment time"); + + /* Equality comparison */ + + t.restart(); + + std::size_t c=0; + for(int i=0;i<100;++i){ + c+=std::count(txt.begin(),txt.end(),txt[c%txt.size()]); + } + + t.time("equality comparison time"); + + /* Value access */ + + t.restart(); + + std::size_t s=0; + for(int i=0;i<20;++i){ + s+=std::accumulate(txt2.begin(),txt2.end(),s,length_adder()); + } + + t.time("value access time"); + + std::cout<<"bytes used: "<<count_allocator_mem; + if(is_flyweight<String>::value){+ std::size_t flyweight_mem=(txt.capacity()+txt2.capacity())*sizeof(String);
+ std::cout<<"= flyweights("<<flyweight_mem + <<")+values("<<count_allocator_mem-flyweight_mem<<")"; + } + std::cout<<"\n"; + + return c+s; + } +}; + +/* table of test cases for the user to select from */ + +struct test_case +{ + const char* name; + std::size_t (*test)(const std::string&); +}; + +test_case test_table[]= +{ + { + "simple string", + test<count_string>::run + }, + { + "flyweight, hashed factory", + test<flyweight<count_string,count_hashed_factory> >::run + }, + { + "flyweight, hashed factory, no tracking", + test<flyweight<count_string,count_hashed_factory,no_tracking> >::run + }, + { + "flyweight, set-based factory", + test<flyweight<count_string,count_set_factory> >::run + }, + { + "flyweight, set-based factory, no tracking", + test<flyweight<count_string,count_set_factory,no_tracking> >::run + } +}; + +const int num_test_cases=sizeof(test_table)/sizeof(test_case); + +int main() +{ + try{ + for(int i=0;i<num_test_cases;++i){ + std::cout<<i+1<<". "<<test_table[i].name<<"\n"; + } + int option=-1; + for(;;){ + std::cout<<"select option, enter to exit: "; + std::string str; + std::getline(std::cin,str); + if(str.empty())std::exit(EXIT_SUCCESS); + std::istringstream istr(str); + istr>>option; + if(option>=1&&option<=num_test_cases){ + --option; /* pass from 1-based menu to 0-based test_table */ + break; + } + } + + std::cout<<"enter file name: "; + std::string file; + std::getline(std::cin,file); + std::size_t result=0; + result=test_table[option].test(file); + } + catch(const std::exception& e){ + std::cout<<"error: "<<e.what()<<"\n"; + } + + return 0; +} Added: trunk/libs/flyweight/test/Jamfile.v2 ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/Jamfile.v2 Thu Apr 9 01:46:49 2009 @@ -0,0 +1,34 @@ +# Boost.Flyweight tests Jamfile +# +# Copyright 2006-2008 Joaqu n M L pez Mu oz. +# 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) +# +# See http://www.boost.org/libs/flyweight for library home page. + +project + : requirements + <os>LINUX:<threading>multi + ; + +test-suite "flyweight" : + [ run test_assoc_cont_factory.cpp test_assoc_cont_fact_main.cpp ] + [ run test_basic.cpp test_basic_main.cpp ] + [ run test_custom_factory.cpp test_custom_factory_main.cpp ] + [ run test_init.cpp test_init_main.cpp ] + [ run test_intermod_holder.cpp test_intermod_holder_main.cpp + intermod_holder_dll + : # command line + : # input files + : # requirements + <threading>multi ] + [ run test_multictor.cpp test_multictor_main.cpp ] + [ run test_no_locking.cpp test_no_locking_main.cpp ] + [ run test_no_tracking.cpp test_no_tracking_main.cpp ] + [ run test_set_factory.cpp test_set_factory_main.cpp ] + ; + +lib intermod_holder_dll : intermod_holder_dll.cpp : + <link>shared + <define>BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_SOURCE=1 ; Added: trunk/libs/flyweight/test/heavy_objects.hpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/heavy_objects.hpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,87 @@ +/* Boost.Flyweight basic test template. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#ifndef BOOST_FLYWEIGHT_TEST_HEAVY_OBJECTS_HPP +#define BOOST_FLYWEIGHT_TEST_HEAVY_OBJECTS_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/noncopyable.hpp> +#include <iosfwd> +#include <string> + +struct texture +{ + texture(const std::string& str=""):str(str){} + + friend bool operator==( + const texture& x,const texture& y){return x.str==y.str;} + friend bool operator< ( + const texture& x,const texture& y){return x.str< y.str;} + friend bool operator!=( + const texture& x,const texture& y){return x.str!=y.str;} + friend bool operator> ( + const texture& x,const texture& y){return x.str> y.str;} + friend bool operator>=( + const texture& x,const texture& y){return x.str>=y.str;} + friend bool operator<=( + const texture& x,const texture& y){return x.str<=y.str;} + + friend std::ostream& operator<<(std::ostream& os,const texture& x) + { + return os<<x.str; + } + + friend std::istream& operator>>(std::istream& is,texture& x) + { + return is>>x.str; + } + + std::string str; +}; + +struct from_texture_to_string +{ + const std::string& operator()(const texture& x)const{return x.str;} +}; + +struct factorization:private boost::noncopyable +{ + factorization(int n=0):n(n){} + + friend bool operator==( + const factorization& x,const factorization& y){return x.n==y.n;} + friend bool operator< ( + const factorization& x,const factorization& y){return x.n< y.n;} + friend bool operator!=( + const factorization& x,const factorization& y){return x.n!=y.n;} + friend bool operator> ( + const factorization& x,const factorization& y){return x.n> y.n;} + friend bool operator>=( + const factorization& x,const factorization& y){return x.n>=y.n;} + friend bool operator<=( + const factorization& x,const factorization& y){return x.n<=y.n;} + + friend std::ostream& operator<<(std::ostream& os,const factorization& x) + { + return os<<x.n; + } + + friend std::istream& operator>>(std::istream& is,factorization& x) + { + return is>>x.n; + } + + int n; +}; + +#endif Added: trunk/libs/flyweight/test/intermod_holder_dll.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/intermod_holder_dll.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,17 @@ +/* Boost.Flyweight test of intermodule_holder. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "intermod_holder_dll.hpp" + +intermodule_flyweight_string create_intermodule_flyweight_string( + const std::string& str) +{ + return intermodule_flyweight_string(str); +} Added: trunk/libs/flyweight/test/intermod_holder_dll.hpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/intermod_holder_dll.hpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,45 @@ +/* Boost.Flyweight test of intermodule_holder. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#ifndef BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_HPP +#define BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/hashed_factory.hpp> +#include <boost/flyweight/intermodule_holder.hpp> +#include <boost/flyweight/refcounted.hpp> +#include <boost/flyweight/simple_locking.hpp> +#include <string> + +#ifdef BOOST_HAS_DECLSPEC +#ifdef BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_SOURCE +#define BOOST_FLYWEIGHT_DLL_DECL __declspec(dllexport) +#else +#define BOOST_FLYWEIGHT_DLL_DECL __declspec(dllimport) +#endif +#else +#define BOOST_FLYWEIGHT_DLL_DECL +#endif + +typedef boost::flyweights::flyweight< + std::string, + boost::flyweights::intermodule_holder> intermodule_flyweight_string; + +BOOST_FLYWEIGHT_DLL_DECL intermodule_flyweight_string +create_intermodule_flyweight_string(const std::string&); + +#undef BOOST_FLYWEIGHT_DLL_DECL + +#endif Added: trunk/libs/flyweight/test/test_all_main.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_all_main.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,36 @@ +/* Boost.Flyweight test suite. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp> +#include "test_assoc_cont_factory.hpp" +#include "test_basic.hpp" +#include "test_custom_factory.hpp" +#include "test_intermod_holder.hpp" +#include "test_init.hpp" +#include "test_multictor.hpp" +#include "test_no_locking.hpp" +#include "test_no_tracking.hpp" +#include "test_set_factory.hpp" + +int main() +{ + test_assoc_container_factory(); + test_basic(); + test_custom_factory(); + test_init(); + test_intermodule_holder(); + test_multictor(); + test_no_locking(); + test_no_tracking(); + test_set_factory(); + + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_assoc_cont_fact_main.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_assoc_cont_fact_main.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,18 @@ +/* Boost.Flyweight test of assoc_container_factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_assoc_cont_factory.hpp" + +int main() +{ + test_assoc_container_factory(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_assoc_cont_factory.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_assoc_cont_factory.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,68 @@ +/* Boost.Flyweight test of assoc_container_factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_assoc_cont_factory.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/assoc_container_factory.hpp> +#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/refcounted.hpp> +#include <boost/flyweight/simple_locking.hpp> +#include <boost/flyweight/static_holder.hpp> +#include <functional> +#include <set> +#include "test_basic_template.hpp" + +using namespace boost::flyweights; + +struct reverse_set_specifier +{ + template<typename Entry,typename Key> + struct apply + { + typedef std::set<Entry,std::greater<Key> > type; + }; +}; + +struct assoc_container_factory_flyweight_specifier1 +{ + template<typename T> + struct apply + { + typedef flyweight< + T, + assoc_container_factory<reverse_set_specifier> + > type; + }; +}; + +struct assoc_container_factory_flyweight_specifier2 +{ + template<typename T> + struct apply + { + typedef flyweight< + T, + assoc_container_factory_class< + std::set< + boost::mpl::_1, + std::greater<boost::mpl::_2>, + std::allocator<boost::mpl::_1> + > + > + > type; + }; +}; + +void test_assoc_container_factory() +{ + test_basic_template<assoc_container_factory_flyweight_specifier1>(); + test_basic_template<assoc_container_factory_flyweight_specifier2>(); +} Added: trunk/libs/flyweight/test/test_assoc_cont_factory.hpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_assoc_cont_factory.hpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,11 @@ +/* Boost.Flyweight test of assoc_container_factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_assoc_container_factory(); Added: trunk/libs/flyweight/test/test_basic.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_basic.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,68 @@ +/* Boost.Flyweight basic test. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_basic.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight.hpp> +#include "test_basic_template.hpp" + +using namespace boost::flyweights; + +struct basic_flyweight_specifier1 +{ + template<typename T> + struct apply + { + typedef flyweight<T> type; + }; +}; + +struct basic_flyweight_specifier2 +{ + template<typename T> + struct apply + { + typedef flyweight< + T,tag<int>, + static_holder_class<boost::mpl::_1>, + hashed_factory_class< + boost::mpl::_1,boost::mpl::_2, + boost::hash<boost::mpl::_2>,std::equal_to<boost::mpl::_2>, + std::allocator<boost::mpl::_1> + >, + simple_locking, + refcounted + > type; + }; +}; + +struct basic_flyweight_specifier3 +{ + template<typename T> + struct apply + { + typedef flyweight< + T, + hashed_factory< + boost::hash<boost::mpl::_2>,std::equal_to<boost::mpl::_2>, + std::allocator<boost::mpl::_1> + >, + tag<int> + > type; + }; +}; + +void test_basic() +{ + test_basic_template<basic_flyweight_specifier1>(); + test_basic_template<basic_flyweight_specifier2>(); + test_basic_template<basic_flyweight_specifier3>(); +} Added: trunk/libs/flyweight/test/test_basic.hpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_basic.hpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,11 @@ +/* Boost.Flyweight basic test. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_basic(); Added: trunk/libs/flyweight/test/test_basic_main.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_basic_main.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,18 @@ +/* Boost.Flyweight basic test. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_basic.hpp" + +int main() +{ + test_basic(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_basic_template.hpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_basic_template.hpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,232 @@ +/* Boost.Flyweight basic test template. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#ifndef BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP +#define BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp> +#include <boost/flyweight/key_value.hpp> +#include <boost/mpl/apply.hpp> +#include <boost/utility/value_init.hpp> +#include <string> +#include <sstream> +#include "heavy_objects.hpp" + +#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0])) + +template<typename Flyweight,typename ForwardIterator> +void test_basic_template( + ForwardIterator first,ForwardIterator last + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight)) +{ + typedef typename Flyweight::value_type value_type; + + ForwardIterator it; + + for(it=first;it!=last;++it){ + /* construct/copy/destroy */ + + Flyweight f1(*it); + Flyweight f2; + Flyweight c1(f1);+ Flyweight c2(static_cast<const Flyweight&>(f2));
+ value_type v1(*it); + boost::value_initialized<value_type> v2; + BOOST_TEST(f1.get_key()==*it); + BOOST_TEST((f1==f2)==(f1.get()==v2.data())); + BOOST_TEST(f1==c1); + BOOST_TEST(f2==c2); + + f1=f1; + BOOST_TEST(f1==f1); + + c1=f2; + BOOST_TEST(c1==f2); + + c1=f1; + BOOST_TEST(c1==f1); + + /* convertibility to underlying type */ + + BOOST_TEST(f1.get()==v1); + + /* identity of reference */ + + BOOST_TEST(&f1.get()==&c1.get()); + + /* modifiers */ + + f1.swap(f1); + BOOST_TEST(f1==c1); + + f1.swap(f2); + BOOST_TEST(f1==c2); + BOOST_TEST(f2==c1); + + boost::flyweights::swap(f1,f2); + BOOST_TEST(f1==c1); + BOOST_TEST(f2==c2); + + /* specialized algorithms */ + + std::ostringstream oss1; + oss1<<f1; + std::ostringstream oss2; + oss2<<f1.get(); + BOOST_TEST(oss1.str()==oss2.str()); + } +} + +template<typename Flyweight,typename ForwardIterator> +void test_basic_with_assign_template( + ForwardIterator first,ForwardIterator last + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight)) +{ + typedef typename Flyweight::value_type value_type; + + ForwardIterator it; + + test_basic_template<Flyweight>(first,last); + + for(it=first;it!=last;++it){ + /* value construction */ + + value_type v(*it); + Flyweight f1(v); + Flyweight f2(f1.get()); + BOOST_TEST(f1.get()==v); + BOOST_TEST(f2.get()==v); + BOOST_TEST(f1==f2); + + /* value assignment */ + + Flyweight f3,f4; + f3=v; + f4=f1.get(); + BOOST_TEST(f2.get()==v); + BOOST_TEST(f3.get()==v); + BOOST_TEST(f2==f3); + + /* specialized algorithms */ + + std::ostringstream oss1; + oss1<<f1; + std::istringstream iss1(oss1.str()); + Flyweight f5; + iss1>>f5; + BOOST_TEST(f5==f1); + } +} + +template< + typename Flyweight1,typename Flyweight2, + typename ForwardIterator1,typename ForwardIterator2 +> +void test_basic_comparison_template( + ForwardIterator1 first1,ForwardIterator1 last1, + ForwardIterator2 first2 + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight1) + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight2)) +{ + typedef typename Flyweight1::value_type value_type1; + typedef typename Flyweight2::value_type value_type2; + + for(;first1!=last1;++first1,++first2){ + value_type1 v1=value_type1(*first1); + value_type2 v2=value_type2(*first2); + Flyweight1 f1(v1); + Flyweight2 f2(v2); + + BOOST_TEST((f1==f2)==(f1.get()==v2)); + BOOST_TEST((f1< f2)==(f1.get()< v2)); + BOOST_TEST((f1!=f2)==(f1.get()!=v2)); + BOOST_TEST((f1> f2)==(f1.get()> v2)); + BOOST_TEST((f1>=f2)==(f1.get()>=v2)); + BOOST_TEST((f1<=f2)==(f1.get()<=v2)); + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + BOOST_TEST((f1==v2)==(f1.get()==v2)); + BOOST_TEST((f1< v2)==(f1.get()< v2)); + BOOST_TEST((f1!=v2)==(f1.get()!=v2)); + BOOST_TEST((f1> v2)==(f1.get()> v2)); + BOOST_TEST((f1>=v2)==(f1.get()>=v2)); + BOOST_TEST((f1<=v2)==(f1.get()<=v2)); + + BOOST_TEST((v1==f2)==(f1.get()==v2)); + BOOST_TEST((v1< f2)==(f1.get()< v2)); + BOOST_TEST((v1!=f2)==(f1.get()!=v2)); + BOOST_TEST((v1> f2)==(f1.get()> v2)); + BOOST_TEST((v1>=f2)==(f1.get()>=v2)); + BOOST_TEST((v1<=f2)==(f1.get()<=v2)); +#endif + + } +} + +template<typename FlyweightSpecifier> +void test_basic_template(BOOST_EXPLICIT_TEMPLATE_TYPE(FlyweightSpecifier)) +{ + typedef typename boost::mpl::apply1< + FlyweightSpecifier,int + >::type int_flyweight; + + typedef typename boost::mpl::apply1< + FlyweightSpecifier,std::string + >::type string_flyweight; + + typedef typename boost::mpl::apply1< + FlyweightSpecifier,char + >::type char_flyweight; + + typedef typename boost::mpl::apply1< + FlyweightSpecifier,+ boost::flyweights::key_value<std::string,texture,from_texture_to_string>
+ >::type texture_flyweight; + + typedef typename boost::mpl::apply1< + FlyweightSpecifier, + boost::flyweights::key_value<int,factorization> + >::type factorization_flyweight; + + int ints[]={0,1,1,0,1,2,3,4,3,4,0,0}; + test_basic_with_assign_template<int_flyweight>( + &ints[0],&ints[0]+LENGTHOF(ints)); ++ const char* words[]={"hello","boost","flyweight","boost","bye","c++","c++"};
+ test_basic_with_assign_template<string_flyweight>( + &words[0],&words[0]+LENGTHOF(words)); + + const char* textures[]={"wood","grass","sand","granite","terracotta"}; + test_basic_with_assign_template<texture_flyweight>( + &textures[0],&textures[0]+LENGTHOF(textures)); + + int factorizations[]={1098,102387,90846,2223978}; + test_basic_template<factorization_flyweight>( + &factorizations[0],&factorizations[0]+LENGTHOF(factorizations)); + + char chars[]={0,2,4,5,1,1,1,3,4,1,1,0}; + test_basic_comparison_template<int_flyweight,char_flyweight>( + &ints[0],&ints[0]+LENGTHOF(ints),&chars[0]); + + test_basic_comparison_template<string_flyweight,string_flyweight>( + &words[0],&words[0]+LENGTHOF(words)-1,&words[1]); + + test_basic_comparison_template<texture_flyweight,texture_flyweight>( + &textures[0],&textures[0]+LENGTHOF(textures)-1,&textures[1]); +} + +#undef LENGTHOF + +#endif Added: trunk/libs/flyweight/test/test_custom_factory.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_custom_factory.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,111 @@ +/* Boost.Flyweight test of a custom factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_custom_factory.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/refcounted.hpp> +#include <boost/flyweight/simple_locking.hpp> +#include <boost/flyweight/static_holder.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> +#include <list> +#include "test_basic_template.hpp" + +using namespace boost::flyweights; + +/* Info on list-update containers:+ * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/lu_based_containers.html
+ */ + +template<typename Entry,typename Key> +class lu_factory_class:public factory_marker +{ + struct entry_type + { + entry_type(const Entry& x_):x(x_),count(0){} + + Entry x; + std::size_t count; + }; + + typedef std::list<entry_type> container_type; + +public: + typedef typename container_type::iterator handle_type; + + handle_type insert(const Entry& x) + { + handle_type h; + for(h=cont.begin();h!=cont.end();++h){ + if(static_cast<const Key&>(h->x)==static_cast<const Key&>(x)){ + if(++(h->count)==10){ + h->count=0; + cont.splice(cont.begin(),cont,h); /* move to front */ + } + return h; + } + } + cont.push_back(entry_type(x)); + h=cont.end(); + --h; + return h; + } + + void erase(handle_type h) + { + cont.erase(h); + } + + const Entry& entry(handle_type h){return h->x;} + +private: + container_type cont; + +public: + typedef lu_factory_class type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,lu_factory_class,(Entry,Key)) +}; + +struct lu_factory:factory_marker +{ + template<typename Entry,typename Key> + struct apply + { + typedef lu_factory_class<Entry,Key> type; + }; +}; + +struct custom_factory_flyweight_specifier1 +{ + template<typename T> + struct apply + { + typedef flyweight<T,lu_factory> type; + }; +}; + +struct custom_factory_flyweight_specifier2 +{ + template<typename T> + struct apply + { + typedef flyweight< + T, + lu_factory_class<boost::mpl::_1,boost::mpl::_2> + > type; + }; +}; + +void test_custom_factory() +{ + test_basic_template<custom_factory_flyweight_specifier1>(); + test_basic_template<custom_factory_flyweight_specifier2>(); +} Added: trunk/libs/flyweight/test/test_custom_factory.hpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_custom_factory.hpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,11 @@ +/* Boost.Flyweight test of a custom factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_custom_factory(); Added: trunk/libs/flyweight/test/test_custom_factory_main.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_custom_factory_main.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,18 @@ +/* Boost.Flyweight test of a custom factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_custom_factory.hpp" + +int main() +{ + test_custom_factory(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_init.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_init.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,47 @@ +/* Boost.Flyweight test of static data initialization facilities. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_init.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp> +#include <boost/flyweight.hpp> + +using namespace boost::flyweights; + +template<bool* pmark,typename Entry,typename Value> +struct marked_hashed_factory_class:hashed_factory_class<Entry,Value> +{ + marked_hashed_factory_class(){*pmark=true;} +}; + +template<bool* pmark> +struct marked_hashed_factory:factory_marker +{ + template<typename Entry,typename Value> + struct apply + { + typedef marked_hashed_factory_class<pmark,Entry,Value> type; + }; +}; + +namespace{ +bool mark1=false; +bool init1=flyweight<int,marked_hashed_factory<&mark1> >::init(); + +bool mark2=false; +flyweight<int,marked_hashed_factory<&mark2> >::initializer init2; +} + +void test_init() +{ + BOOST_TEST(mark1); + BOOST_TEST(mark2); +} Added: trunk/libs/flyweight/test/test_init.hpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_init.hpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,11 @@ +/* Boost.Flyweight test of static data initialization facilities. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_init(); Added: trunk/libs/flyweight/test/test_init_main.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_init_main.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,18 @@ +/* Boost.Flyweight test of static data initialization facilities. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_init.hpp" + +int main() +{ + test_init(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_intermod_holder.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_intermod_holder.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,34 @@ +/* Boost.Flyweight test of intermodule_holder. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_intermod_holder.hpp" + +#include "intermod_holder_dll.hpp" +#include "test_basic_template.hpp" + +using namespace boost::flyweights; + +struct intermodule_holder_flyweight_specifier1 +{ + template<typename T> + struct apply + { + typedef flyweight<T,intermodule_holder> type; + }; +}; + +void test_intermodule_holder() +{ + test_basic_template<intermodule_holder_flyweight_specifier1>(); + + intermodule_flyweight_string str= + create_intermodule_flyweight_string("boost"); + BOOST_TEST(str==intermodule_flyweight_string("boost")); +} Added: trunk/libs/flyweight/test/test_intermod_holder.hpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_intermod_holder.hpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,11 @@ +/* Boost.Flyweight test of intermodule_holder. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_intermodule_holder(); Added: trunk/libs/flyweight/test/test_intermod_holder_main.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_intermod_holder_main.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,18 @@ +/* Boost.Flyweight test of intermodule_holder. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_intermod_holder.hpp" + +int main() +{ + test_intermodule_holder(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_multictor.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_multictor.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,105 @@ +/* Boost.Flyweight test of flyweight forwarding ctors. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_multictor.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/workaround.hpp> +#include <boost/flyweight.hpp> +#include <boost/functional/hash.hpp> +#include <boost/tuple/tuple.hpp> +#include <boost/tuple/tuple_comparison.hpp> +#include "test_basic_template.hpp" + +using boost::flyweight; + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +#define NONCONST const +#else +#define NONCONST +#endif + +struct multictor +{ + typedef multictor type; + + multictor(): + t(0,0,0.0,"",false){} + multictor(NONCONST int& x0): + t(x0,0,0.0,"",false){} + multictor(int x0,NONCONST char& x1): + t(x0,x1,0.0,"",false){} + multictor(int x0,char x1,NONCONST double& x2): + t(x0,x1,x2,"",false){} + multictor(int x0,char x1,double x2,NONCONST std::string& x3): + t(x0,x1,x2,x3,false){}+ multictor(int x0,char x1,double x2,const std::string& x3,NONCONST bool& x4):
+ t(x0,x1,x2,x3,x4){} + + friend bool operator==(const type& x,const type& y){return x.t==y.t;} + friend bool operator< (const type& x,const type& y){return x.t< y.t;} + friend bool operator!=(const type& x,const type& y){return x.t!=y.t;} + friend bool operator> (const type& x,const type& y){return x.t> y.t;} + friend bool operator>=(const type& x,const type& y){return x.t>=y.t;} + friend bool operator<=(const type& x,const type& y){return x.t<=y.t;} + + boost::tuples::tuple<int,char,double,std::string,bool> t; +}; + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace boost{ +#endif + +inline std::size_t hash_value(const multictor& x) +{ + std::size_t res=0; + boost::hash_combine(res,boost::tuples::get<0>(x.t)); + boost::hash_combine(res,boost::tuples::get<1>(x.t)); + boost::hash_combine(res,boost::tuples::get<2>(x.t)); + boost::hash_combine(res,boost::tuples::get<3>(x.t)); + boost::hash_combine(res,boost::tuples::get<4>(x.t)); + return res; +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace boost */ +#endif + +void test_multictor() +{ + flyweight<multictor> f; + multictor m; + BOOST_TEST(f==m); + + int x0=1; + flyweight<multictor> f0(x0); + multictor m0(x0); + BOOST_TEST(f0==m0); + + char x1='a'; + flyweight<multictor> f1(1,x1); + multictor m1(1,x1); + BOOST_TEST(f1==m1); + + double x2=3.1416; + flyweight<multictor> f2(1,'a',x2); + multictor m2(1,'a',x2); + BOOST_TEST(f2==m2); + + std::string x3("boost"); + flyweight<multictor> f3(1,'a',3.1416,x3); + multictor m3(1,'a',3.1416,x3); + BOOST_TEST(f3==m3); + + bool x4=true; + flyweight<multictor> f4(1,'a',3.1416,"boost",x4); + multictor m4(1,'a',3.1416,"boost",x4); + BOOST_TEST(f4==m4); +} Added: trunk/libs/flyweight/test/test_multictor.hpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_multictor.hpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,11 @@ +/* Boost.Flyweight test of flyweight forwarding ctors. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_multictor(); Added: trunk/libs/flyweight/test/test_multictor_main.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_multictor_main.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,18 @@ +/* Boost.Flyweight test of flyweight forwarding ctors. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_multictor.hpp" + +int main() +{ + test_multictor(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_no_locking.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_no_locking.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,35 @@ +/* Boost.Flyweight test of no_locking. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_no_locking.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/hashed_factory.hpp> +#include <boost/flyweight/no_locking.hpp> +#include <boost/flyweight/refcounted.hpp> +#include <boost/flyweight/static_holder.hpp> +#include "test_basic_template.hpp" + +using namespace boost::flyweights; + +struct no_locking_flyweight_specifier +{ + template<typename T> + struct apply + { + typedef flyweight<T,no_locking> type; + }; +}; + +void test_no_locking() +{ + test_basic_template<no_locking_flyweight_specifier>(); +} Added: trunk/libs/flyweight/test/test_no_locking.hpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_no_locking.hpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,11 @@ +/* Boost.Flyweight test of no_locking. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_no_locking(); Added: trunk/libs/flyweight/test/test_no_locking_main.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_no_locking_main.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,18 @@ +/* Boost.Flyweight test of no_locking. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_no_locking.hpp" + +int main() +{ + test_no_locking(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_no_tracking.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_no_tracking.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,35 @@ +/* Boost.Flyweight test of no_tracking. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_no_tracking.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/hashed_factory.hpp> +#include <boost/flyweight/no_tracking.hpp> +#include <boost/flyweight/simple_locking.hpp> +#include <boost/flyweight/static_holder.hpp> +#include "test_basic_template.hpp" + +using namespace boost::flyweights; + +struct no_tracking_flyweight_specifier +{ + template<typename T> + struct apply + { + typedef flyweight<T,no_tracking> type; + }; +}; + +void test_no_tracking() +{ + test_basic_template<no_tracking_flyweight_specifier>(); +} Added: trunk/libs/flyweight/test/test_no_tracking.hpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_no_tracking.hpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,11 @@ +/* Boost.Flyweight test of no_tracking. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_no_tracking(); Added: trunk/libs/flyweight/test/test_no_tracking_main.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_no_tracking_main.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,18 @@ +/* Boost.Flyweight test of no_tracking. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_no_tracking.hpp" + +int main() +{ + test_no_tracking(); + return boost::report_errors(); +} Added: trunk/libs/flyweight/test/test_set_factory.cpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_set_factory.cpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,71 @@ +/* Boost.Flyweight test of set_factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include "test_set_factory.hpp" ++#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp> +#include <boost/flyweight/refcounted.hpp> +#include <boost/flyweight/set_factory.hpp> +#include <boost/flyweight/simple_locking.hpp> +#include <boost/flyweight/static_holder.hpp> +#include "test_basic_template.hpp" + +using namespace boost::flyweights; + +struct set_factory_flyweight_specifier1 +{ + template<typename T> + struct apply + { + typedef flyweight<T,set_factory<> > type; + }; +}; + +struct set_factory_flyweight_specifier2 +{ + template<typename T> + struct apply + { + typedef flyweight< + T, + static_holder_class<boost::mpl::_1>, + set_factory_class< + boost::mpl::_1,boost::mpl::_2, + std::greater<boost::mpl::_2>, + std::allocator<boost::mpl::_1> + > + > type; + }; +}; + +struct set_factory_flyweight_specifier3 +{ + template<typename T> + struct apply + { + typedef flyweight< + T, + set_factory< + std::greater<boost::mpl::_2>, + std::allocator<boost::mpl::_1> + >, + static_holder_class<boost::mpl::_1>, + tag<char> + > type; + }; +}; + +void test_set_factory() +{ + test_basic_template<set_factory_flyweight_specifier1>(); + test_basic_template<set_factory_flyweight_specifier2>(); + test_basic_template<set_factory_flyweight_specifier3>(); +} Added: trunk/libs/flyweight/test/test_set_factory.hpp ============================================================================== --- (empty file) +++ trunk/libs/flyweight/test/test_set_factory.hpp Thu Apr 9 01:46:49 2009 @@ -0,0 +1,11 @@ +/* Boost.Flyweight test of set_factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +void test_set_factory(); Added: trunk/libs/flyweight/test/test_set_factory_main.cpp ============================================================================== --- (empty file)+++ trunk/libs/flyweight/test/test_set_factory_main.cpp Thu Apr 9 01:46:49 2009
@@ -0,0 +1,18 @@ +/* Boost.Flyweight test of set_factory. + * + * Copyright 2006-2008 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/flyweight for library home page. + */ + +#include <boost/detail/lightweight_test.hpp> +#include "test_set_factory.hpp" + +int main() +{ + test_set_factory(); + return boost::report_errors(); +}