[boost-doc-zh] r427 committed - 升级至1.44.0,第3批,libs/目录g-k子目录

  • From: boost-doc-zh@xxxxxxxxxxxxxx
  • To: boost-doc-zh-notify@xxxxxxxxxxxxx
  • Date: Tue, 24 Aug 2010 06:05:56 +0000

Revision: 427
Author: alai04
Date: Mon Aug 23 23:00:26 2010
Log: 升级至1.44.0,第3批,libs/目录g-k子目录
http://code.google.com/p/boost-doc-zh/source/detail?r=427

Added:
 /trunk/libs/graph/doc/boykov_kolmogorov_max_flow.html
 /trunk/libs/graph/doc/figs/bk_max_flow.gif
 /trunk/libs/graph/doc/figs/warning.png
 /trunk/libs/graph/doc/random_spanning_tree.html
 /trunk/libs/graph/example/boykov_kolmogorov-eg.cpp
 /trunk/libs/graph/test/boykov_kolmogorov_max_flow_test.cpp
 /trunk/libs/graph/test/random_spanning_tree_test.cpp
 /trunk/libs/intrusive/test
 /trunk/libs/intrusive/test/Jamfile.v2
 /trunk/libs/intrusive/test/any_test.cpp
 /trunk/libs/intrusive/test/avl_multiset_test.cpp
 /trunk/libs/intrusive/test/avl_set_test.cpp
 /trunk/libs/intrusive/test/common_functors.hpp
 /trunk/libs/intrusive/test/custom_bucket_traits_test.cpp
 /trunk/libs/intrusive/test/default_hook_test.cpp
 /trunk/libs/intrusive/test/external_value_traits_test.cpp
 /trunk/libs/intrusive/test/generic_assoc_test.hpp
 /trunk/libs/intrusive/test/generic_multiset_test.hpp
 /trunk/libs/intrusive/test/generic_set_test.hpp
 /trunk/libs/intrusive/test/itestvalue.hpp
 /trunk/libs/intrusive/test/list_test.cpp
 /trunk/libs/intrusive/test/make_functions_test.cpp
 /trunk/libs/intrusive/test/multiset_test.cpp
 /trunk/libs/intrusive/test/set_test.cpp
 /trunk/libs/intrusive/test/sg_multiset_test.cpp
 /trunk/libs/intrusive/test/sg_set_test.cpp
 /trunk/libs/intrusive/test/slist_test.cpp
 /trunk/libs/intrusive/test/smart_ptr.hpp
 /trunk/libs/intrusive/test/splay_multiset_test.cpp
 /trunk/libs/intrusive/test/splay_set_test.cpp
 /trunk/libs/intrusive/test/stateful_value_traits_test.cpp
 /trunk/libs/intrusive/test/test_container.hpp
 /trunk/libs/intrusive/test/test_macros.hpp
 /trunk/libs/intrusive/test/treap_multiset_test.cpp
 /trunk/libs/intrusive/test/treap_set_test.cpp
 /trunk/libs/intrusive/test/unordered_multiset_test.cpp
 /trunk/libs/intrusive/test/unordered_set_test.cpp
 /trunk/libs/intrusive/test/virtual_base_test.cpp
 /trunk/libs/iostreams/test/deprecated_file_descriptor_test.cpp
 /trunk/libs/iostreams/test/detail/file_handle.hpp
 /trunk/libs/iterator/doc/Jamfile.v2
Deleted:
 /trunk/libs/iostreams/doc/concepts/multi-character.html
Modified:
 /trunk/libs/graph/doc/AStarVisitor.html
 /trunk/libs/graph/doc/adjacency_list.html
 /trunk/libs/graph/doc/astar_search.html
 /trunk/libs/graph/doc/bibliography.html
 /trunk/libs/graph/doc/edmonds_karp_max_flow.html
 /trunk/libs/graph/doc/graph_concepts.html
 /trunk/libs/graph/doc/graph_traits.html
 /trunk/libs/graph/doc/grid_graph.html
 /trunk/libs/graph/doc/history.html
 /trunk/libs/graph/doc/kolmogorov_max_flow.html
 /trunk/libs/graph/doc/planar_canonical_ordering.html
 /trunk/libs/graph/doc/push_relabel_max_flow.html
 /trunk/libs/graph/doc/quick_tour.html
 /trunk/libs/graph/doc/table_of_contents.html
 /trunk/libs/graph/doc/write-graphviz.html
 /trunk/libs/graph/example/Jamfile.v2
 /trunk/libs/graph/example/accum-compile-times.cpp
 /trunk/libs/graph/example/astar-cities.cpp
 /trunk/libs/graph/example/bellman-example.cpp
 /trunk/libs/graph/example/bfs-example2.cpp
 /trunk/libs/graph/example/bfs-name-printer.cpp
 /trunk/libs/graph/example/biconnected_components.cpp
 /trunk/libs/graph/example/bipartite_example.cpp
 /trunk/libs/graph/example/boost_web_graph.cpp
 /trunk/libs/graph/example/cc-internet.cpp
 /trunk/libs/graph/example/components_on_edgelist.cpp
 /trunk/libs/graph/example/copy-example.cpp
 /trunk/libs/graph/example/cycle-file-dep.cpp
 /trunk/libs/graph/example/cycle-file-dep2.cpp
 /trunk/libs/graph/example/cycle_ratio_example.cpp
 /trunk/libs/graph/example/dag_shortest_paths.cpp
 /trunk/libs/graph/example/dfs-parenthesis.cpp
 /trunk/libs/graph/example/dijkstra-example-listS.cpp
 /trunk/libs/graph/example/dijkstra-example.cpp
 /trunk/libs/graph/example/dijkstra-no-color-map-example.cpp
 /trunk/libs/graph/example/eccentricity.cpp
 /trunk/libs/graph/example/edge-connectivity.cpp
 /trunk/libs/graph/example/edge-function.cpp
 /trunk/libs/graph/example/edge_property.cpp
 /trunk/libs/graph/example/edmonds-karp-eg.cpp
 /trunk/libs/graph/example/family-tree-eg.cpp
 /trunk/libs/graph/example/file_dependencies.cpp
 /trunk/libs/graph/example/filtered-copy-example.cpp
 /trunk/libs/graph/example/filtered_graph_edge_range.cpp
 /trunk/libs/graph/example/fr_layout.cpp
 /trunk/libs/graph/example/gerdemann.cpp
 /trunk/libs/graph/example/graph-property-iter-eg.cpp
 /trunk/libs/graph/example/graphviz.cpp
 /trunk/libs/graph/example/helper.hpp
 /trunk/libs/graph/example/in_edges.cpp
 /trunk/libs/graph/example/isomorphism.cpp
 /trunk/libs/graph/example/johnson-eg.cpp
 /trunk/libs/graph/example/kevin-bacon.cpp
 /trunk/libs/graph/example/kevin-bacon2.cpp
 /trunk/libs/graph/example/knights-tour.cpp
 /trunk/libs/graph/example/kruskal-example.cpp
 /trunk/libs/graph/example/kruskal-telephone.cpp
 /trunk/libs/graph/example/leda-graph-eg.cpp
 /trunk/libs/graph/example/loops_dfs.cpp
 /trunk/libs/graph/example/max_flow.cpp
 /trunk/libs/graph/example/min_max_paths.cpp
 /trunk/libs/graph/example/modify_graph.cpp
 /trunk/libs/graph/example/ordered_out_edges.cpp
 /trunk/libs/graph/example/ospf-example.cpp
 /trunk/libs/graph/example/parallel-compile-time.cpp
 /trunk/libs/graph/example/prim-example.cpp
 /trunk/libs/graph/example/prim-telephone.cpp
 /trunk/libs/graph/example/print-adjacent-vertices.cpp
 /trunk/libs/graph/example/print-edges.cpp
 /trunk/libs/graph/example/print-in-edges.cpp
 /trunk/libs/graph/example/print-out-edges.cpp
 /trunk/libs/graph/example/push-relabel-eg.cpp
 /trunk/libs/graph/example/quick-tour.cpp
 /trunk/libs/graph/example/quick_tour.cpp
 /trunk/libs/graph/example/reachable-loop-head.cpp
 /trunk/libs/graph/example/reachable-loop-tail.cpp
 /trunk/libs/graph/example/read_write_dimacs-eg.cpp
 /trunk/libs/graph/example/remove_edge_if_bidir.cpp
 /trunk/libs/graph/example/remove_edge_if_undir.cpp
 /trunk/libs/graph/example/roget_components.cpp
 /trunk/libs/graph/example/scc.cpp
 /trunk/libs/graph/example/subgraph.cpp
 /trunk/libs/graph/example/tiernan_girth_circumference.cpp
 /trunk/libs/graph/example/topo-sort-file-dep.cpp
 /trunk/libs/graph/example/topo-sort-file-dep2.cpp
 /trunk/libs/graph/example/transpose-example.cpp
 /trunk/libs/graph/example/undirected.cpp
 /trunk/libs/graph/src/graphml.cpp
 /trunk/libs/graph/test/Jamfile.v2
 /trunk/libs/graph/test/astar_search_test.cpp
 /trunk/libs/graph/test/betweenness_centrality_test.cpp
 /trunk/libs/graph/test/biconnected_components_test.cpp
 /trunk/libs/graph/test/bidir_remove_edge.cpp
 /trunk/libs/graph/test/bidir_vec_remove_edge.cpp
 /trunk/libs/graph/test/csr_graph_test.cpp
 /trunk/libs/graph/test/cycle_ratio_tests.cpp
 /trunk/libs/graph/test/dijkstra_heap_performance.cpp
 /trunk/libs/graph/test/dijkstra_no_color_map_compare.cpp
 /trunk/libs/graph/test/dominator_tree_test.cpp
 /trunk/libs/graph/test/graphml_test.cpp
 /trunk/libs/graph/test/graphviz_test.cpp
 /trunk/libs/graph/test/index_graph.cpp
 /trunk/libs/graph/test/layout_test.cpp
 /trunk/libs/graph/test/matching_test.cpp
 /trunk/libs/graph/test/max_flow_test.cpp
 /trunk/libs/graph/test/mcgregor_subgraphs_test.cpp
 /trunk/libs/graph/test/metric_tsp_approx.cpp
 /trunk/libs/graph/test/property_iter.cpp
 /trunk/libs/graph/test/random_matching_test.cpp
 /trunk/libs/graph/test/subgraph.cpp
 /trunk/libs/graph/test/subgraph_bundled.cpp
 /trunk/libs/graph/test/transitive_closure_test.cpp
 /trunk/libs/graph_parallel/test/adjlist_build_test.cpp
 /trunk/libs/graph_parallel/test/adjlist_redist_test.cpp
 /trunk/libs/graph_parallel/test/distributed_adjacency_list_test.cpp
 /trunk/libs/graph_parallel/test/distributed_betweenness_centrality_test.cpp
 /trunk/libs/graph_parallel/test/distributed_shortest_paths_test.cpp
 /trunk/libs/integer/doc/Jamfile.v2
 /trunk/libs/integer/doc/html/boost_integer/cstdint.html
 /trunk/libs/integer/doc/html/boost_integer/history.html
 /trunk/libs/integer/doc/html/boost_integer/integer.html
 /trunk/libs/integer/doc/html/boost_integer/log2.html
 /trunk/libs/integer/doc/html/boost_integer/mask.html
 /trunk/libs/integer/doc/html/boost_integer/minmax.html
 /trunk/libs/integer/doc/html/boost_integer/traits.html
 /trunk/libs/integer/doc/html/index.html
 /trunk/libs/interprocess/doc/Jamfile.v2
 /trunk/libs/iostreams/doc/classes/file_descriptor.html
 /trunk/libs/iostreams/doc/classes/mapped_file.html
 /trunk/libs/iostreams/doc/faq.html
 /trunk/libs/iostreams/doc/guide/asynchronous.html
 /trunk/libs/iostreams/doc/guide/buffering.html
 /trunk/libs/iostreams/doc/guide/code_conversion.html
 /trunk/libs/iostreams/doc/guide/concepts.html
 /trunk/libs/iostreams/doc/guide/exceptions.html
 /trunk/libs/iostreams/doc/guide/filtering_streams.html
 /trunk/libs/iostreams/doc/guide/generic_streams.html
 /trunk/libs/iostreams/doc/guide/lifetimes.html
 /trunk/libs/iostreams/doc/guide/modes.html
 /trunk/libs/iostreams/doc/guide/pipelines.html
 /trunk/libs/iostreams/doc/guide/views.html
 /trunk/libs/iostreams/doc/release_notes.html
 /trunk/libs/iostreams/doc/tutorial/container_device.html
 /trunk/libs/iostreams/doc/tutorial/container_sink.html
 /trunk/libs/iostreams/doc/tutorial/container_source.html
 /trunk/libs/iostreams/doc/tutorial/dictionary_filters.html
 /trunk/libs/iostreams/doc/tutorial/dual_use_filters.html
 /trunk/libs/iostreams/doc/tutorial/filter_usage.html
 /trunk/libs/iostreams/doc/tutorial/finite_state_filters.html
 /trunk/libs/iostreams/doc/tutorial/line_wrapping_filters.html
 /trunk/libs/iostreams/doc/tutorial/multichar_filters.html
 /trunk/libs/iostreams/doc/tutorial/shell_comments_filters.html
 /trunk/libs/iostreams/doc/tutorial/tab_expanding_filters.html
 /trunk/libs/iostreams/doc/tutorial/unix2dos_filters.html
 /trunk/libs/iostreams/doc/tutorial/writing_devices.html
 /trunk/libs/iostreams/doc/tutorial/writing_filters.html
 /trunk/libs/iostreams/src/bzip2.cpp
 /trunk/libs/iostreams/src/file_descriptor.cpp
 /trunk/libs/iostreams/src/mapped_file.cpp
 /trunk/libs/iostreams/src/zlib.cpp
 /trunk/libs/iostreams/test/Jamfile.v2
 /trunk/libs/iostreams/test/bzip2_test.cpp
 /trunk/libs/iostreams/test/detail/temp_file.hpp
 /trunk/libs/iostreams/test/detail/verification.hpp
 /trunk/libs/iostreams/test/file_descriptor_test.cpp
 /trunk/libs/iostreams/test/gzip_test.cpp
 /trunk/libs/iostreams/test/regex_filter_test.cpp
 /trunk/libs/iostreams/test/symmetric_filter_test.cpp
 /trunk/libs/iostreams/test/tee_test.cpp
 /trunk/libs/iostreams/test/zlib_test.cpp

=======================================
--- /dev/null
+++ /trunk/libs/graph/doc/boykov_kolmogorov_max_flow.html Mon Aug 23 23:00:26 2010
@@ -0,0 +1,395 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; 
charset=iso-8859-15">
+       <TITLE>Boost Graph Library: Boykov-Kolmogorov Maximum Flow</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0  (Linux)">
+       <META NAME="CREATED" CONTENT="20060820;17315200">
+       <META NAME="CHANGEDBY" CONTENT="Stephan Diederich">
+       <META NAME="CHANGED" CONTENT="20060820;23125100">
+<!--
+//  Copyright (c) 2006 Stephan Diederich
+//
+// This documentation may be used under either of the following two licences:
+//
+//    Permission is hereby granted, free of charge, to any person
+//    obtaining a copy of this software and associated documentation
+//    files (the "Software"), to deal in the Software without
+//    restriction, including without limitation the rights to use,
+//    copy, modify, merge, publish, distribute, sublicense, and/or
+//    sell copies of the Software, and to permit persons to whom the
+//    Software is furnished to do so, subject to the following
+//    conditions:
+//
+//    The above copyright notice and this permission notice shall be
+//    included in all copies or substantial portions of the Software.
+//
+//    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+//    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+//    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+//    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+//    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+//    OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
+//
+//  Or:
+//
+//    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)
+ -->
+       <STYLE>
+       <!--
+               TD P { color: #000000 }
+               H1 { color: #000000 }
+               P { color: #000000 }
+               PRE { color: #000000 }
+               H3 { color: #000000 }
+               BLOCKQUOTE { color: #000000 }
+               A:link { color: #0000ee }
+               A:visited { color: #551a8b }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="de-DE" TEXT="#000000" LINK="#0000ee" VLINK="#551a8b" BGCOLOR="#ffffff" DIR="LTR"> +<P><IMG SRC="../../../boost.png" NAME="Grafik1" ALT="C++ Boost" ALIGN=BOTTOM WIDTH=277 HEIGHT=86 BORDER=0>
+</P>
+<H1><A NAME="sec:boykov_kolmogorov_max_flow"></A><TT>boykov_kolmogorov_max_flow</TT>
+</H1>
+<PRE><I>// named parameter version</I>
+template &lt;class Graph, class P, class T, class R&gt;
+typename property_traits&lt;typename property_map&lt;Graph, edge_capacity_t&gt;::const_type&gt;::value_type
+boykov_kolmogorov_max_flow(Graph&amp; g,
+   typename graph_traits&lt;Graph&gt;::vertex_descriptor src,
+   typename graph_traits&lt;Graph&gt;::vertex_descriptor sink,
+   const bgl_named_params&lt;P, T, R&gt;&amp; params = <I>all defaults</I>)
+
+<I>// non-named parameter version</I>
+template &lt;class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, class ReverseEdgeMap, + class PredecessorMap, class ColorMap, class DistanceMap, class IndexMap&gt;
+typename property_traits&lt;CapacityEdgeMap&gt;::value_type
+boykov_kolmogorov_max_flow(Graph&amp; g,
+       CapacityEdgeMap cap,
+       ResidualCapacityEdgeMap res_cap,
+       ReverseEdgeMap rev_map,
+       PredecessorMap pre_map,
+       ColorMap color,
+       DistanceMap dist,
+       IndexMap idx,
+       typename graph_traits &lt;Graph&gt;::vertex_descriptor src,
+ typename graph_traits &lt;Graph &gt;::vertex_descriptor sink)</PRE><P>
+<FONT SIZE=3>Additional overloaded versions for non-named parameters
+are provided (without DistanceMap/ColorMap/DistanceMap; for those
+iterator_property_maps with the provided index map are used)</FONT></P>
+<P>The <TT>boykov_kolmogorov_max_flow()</TT> function calculates the maximum +flow of a network. See Section <A HREF="graph_theory_review.html#sec:network-flow-algorithms">Network
+Flow Algorithms</A> for a description of maximum flow. The calculated
+maximum flow will be the return value of the function. The function
+also calculates the flow values <I>f(u,v)</I> for all <I>(u,v)</I> in
+<I>E</I>, which are returned in the form of the residual capacity
+<I>r(u,v) = c(u,v) - f(u,v)</I>.
+</P>
+<P><B>Requirements:</B><BR>The directed graph <I>G=(V,E)</I> that
+represents the network must include a reverse edge for every edge in
+<I>E</I>. That is, the input graph should be <I>G<SUB>in</SUB> =
+(V,{E U E<SUP>T</SUP>})</I>. The <TT>ReverseEdgeMap</TT> argument <TT>rev</TT>
+must map each edge in the original graph to its reverse edge, that is
+<I>(u,v) -&gt; (v,u)</I> for all <I>(u,v)</I> in <I>E</I>.
+</P>
+
+<P>Remarks: While the push-relabel method states that each edge in <I>E<SUP>T</SUP></I>
+has to have capacity of 0, the reverse edges for this algorithm ARE
+allowed to carry capacities. If there are already reverse edges in
+the input Graph <I><FONT FACE="Courier New, monospace">G</FONT></I>,
+those can be used. This can halve the amount of edges and will
+noticeably increase the performance.</P>
+
+<P>
+<B>Algorithm description:</B><BR>The Boykov-Kolmogorov max-flow (or often
+BK max-flow) algorithm is a variety of the augmenting-path algorithm. Standard +augmenting path algorithms find shortest paths from source to sink vertex and +augment them by substracting the bottleneck capacity found on that path from the +residual capacities of each edge and adding it to the total flow. Additionally +the minimum capacity is added to the residual capacity of the reverse edges. If +no more paths in the residual-edge tree are found, the algorithm terminates. +Instead of finding a new shortest path from source to sink in the graph in each
+iteration, the Boykov-Kolmogorov algorithm keeps the already found paths as
+follows:</P>
+
+<P>The algorithm builds up two search trees, a source-tree and a
+sink-tree. Each vertex has a label (stored in <I>ColorMap</I>) to
+which tree it belongs and a status-flag if this vertex is active or
+passive. In the beginning of the algorithm only the source and the
+sink are colored (source==black, sink==white) and have active status.
+All other vertices are colored gray. The algorithm consists of three
+phases:</P>
+<P><I>grow-phase</I>: In this phase active vertices are allowed to
+acquire neighbor vertices that are connected through an edge that has
+a capacity-value greater than zero. Acquiring means that those vertices
+become active and belong now to the search tree of the current
+active vertex. If there are no more valid connections to neighbor
+vertices, the current vertex becomes passive and the grow phase
+continues with the next active vertex. The grow phase terminates if
+there are no more active vertices left or a vertex discovers a vertex
+from the other search tree through an unsaturated edge. In this case
+a path from source to sink is found.</P>
+<P><I>augment-phase</I>: This phase augments the path that was found
+in the grow phase. First it finds the bottleneck capacity of the
+found path, and then it updates the residual-capacity of the edges
+from this path by substracting the bottleneck capacity from the
+residual capacity. Furthermore the residual capacity of the reverse
+edges are updated by adding the bottleneck capacity. This phase can
+destroy the built up search trees, as it creates at least one
+saturated edge. That means, that the search trees collapse to
+forests, because a condition for the search trees is, that each
+vertex in them has a valid (=non-saturated) connection to a terminal.</P>
+<P><I>adoption-phase</I>: Here the search trees are reconstructed. A
+simple solution would be to mark all vertices coming after the first
+orphan in the found path free vertices (gray). A more sophisticated
+solution is to give those orphans new parents: The neighbor vertices
+are checked if they have a valid connection to the same terminal like
+this vertex had (a path with unsaturated edges). If there is one,
+this vertex becomes the new parent of the current orphan and this
+forest is re-included into the search tree. If no new valid parent is
+found, this vertex becomes a free vertex (marked gray), and it's
+children become orphans. The adoption phase terminates if there are
+no more orphans.</P>
+<P><IMG SRC="figs/bk_max_flow.gif" NAME="Grafik2" ALIGN=LEFT WIDTH=827 HEIGHT=311 BORDER=0><BR CLEAR=LEFT><B>Details:</B></P>
+<UL>
+       <LI><P>Marking heuristics: A timestamp is stored for each vertex
+       which shows in which iteration of the algorithm the distance to the
+       corresponding terminal was calculated.
+       </P>
+       <UL>
+               <LI><P>This distance is used and gets calculated in the
+               adoption-phase. In order to find a valid new parent for an 
orphan,
+               the possible parent is checked for a connection to the terminal 
to
+               which tree it belongs. If there is such a connection, the path 
is
+               tagged with the current time-stamp, and the distance value. If
+               another orphan has to find a parent and it comes across a vertex
+               with a current timestamp, this information is used.</P>
+               <LI><P>The distance is also used in the grow-phase. If a vertex
+               comes across another vertex of the same tree while searching for
+               new vertices, the other's distance is compared to its distance. 
If
+               it is smaller, that other vertex becomes the new parent of the
+               current. This can decrease the length of the search paths, and 
so
+               amount of adoptions.</P>
+       </UL>
+       <LI><P>Ordering of orphans: As described above, the augment-phase
+       and the adoption phase can create orphans. The orphans the
+       augment-phase generates, are ordered according to their distance to
+       the terminals (smallest first). This combined with the
+       distance/timestamp heuristics results in the possibility for not
+       having to recheck terminal-connections too often. New orphans which
+       are generated in adoption phase are processed before orphans from
+       the main queue for the same reason.</P>
+</UL>
+<P><BR><B>Implementation notes:</B></P>
+<P>The algorithm is mainly implemented as described by Boykov and Kolmogorov in +[<a href="bibliography.html#boykov-kolmogorov04">69</a>]. An extended version +can be found in the PhD Thesis of Kolmogorov [<A HREF="bibliography.html#kolmogorov03">68</a>].
+The following changes are made to improve performance:</P>
+<UL>
+       <LI>initialization: the algorithm first augments all paths from
+       source-&gt;sink and all paths from source-&gt;VERTEX-&gt;sink. This
+       improves especially graph-cuts used in image vision where nearly
+       each vertex has a source and sink connect. During this step, all
+       vertices that have an unsaturated connection from source are added
+       to the active vertex list and so the source is not.</LI>
+       <LI>active vertices: Boykov-Kolmogorov uses two lists for active nodes
+       and states that new active vertices are added to the rear of the
+       second. Fetching an active vertex is done from the beginning of the
+       first list. If the first list is empty, it is exchanged by the
+       second. This implementation uses just one list.</LI>
+       <LI>grow-phase: In the grow phase the first vertex in the
+       active-list is taken and all outgoing edges are checked if they are
+       unsaturated. This decreases performance for graphs with high-edge
+       density. This implementation stores the last accessed edge and
+       continues with it, if the first vertex in the active-list is the
+       same one as during the last grow-phase.</LI>
+</UL>
+<H3>Where Defined</H3>
+<P><TT><A HREF="../../../boost/graph/boykov_kolmogorov_max_flow.hpp">boost/graph/boykov_kolmogorov_max_flow.hpp</A></TT>
+</P>
+<H3>Parameters</H3>
+<P>IN: <TT>Graph&amp; g</TT>
+</P>
+<BLOCKQUOTE>A directed graph. The graph's type must be a model of
+<A HREF="VertexListGraph.html">Vertex List Graph</A>, <A HREF="EdgeListGraph.html">Edge
+List Graph</A> and <A HREF="IncidenceGraph.html">Incidence Graph</A>.
+For each edge <I>(u,v)</I> in the graph, the reverse edge <I>(v,u)</I>
+must also be in the graph.  Performance of the algorithm will be slightly
+improved if the graph type also models <a href="AdjacencyMatrix.html">Adjacency
+Matrix</a>.
+</BLOCKQUOTE>
+<P>IN: <TT>vertex_descriptor src</TT>
+</P>
+<BLOCKQUOTE>The source vertex for the flow network graph.
+</BLOCKQUOTE>
+<P>IN: <TT>vertex_descriptor sink</TT>
+</P>
+<BLOCKQUOTE>The sink vertex for the flow network graph.
+</BLOCKQUOTE>
+<H3>Named Parameters</H3>
+<P>IN: <TT>edge_capacity(EdgeCapacityMap cap)</TT>
+</P>
+<BLOCKQUOTE>The edge capacity property map. The type must be a model
+of a constant <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
+Property Map</A>. The key type of the map must be the graph's edge
+descriptor type.<BR><B>Default:</B> <TT>get(edge_capacity, g)</TT>
+</BLOCKQUOTE>
+<P>OUT: <TT>edge_residual_capacity(ResidualCapacityEdgeMap res)</TT>
+</P>
+<BLOCKQUOTE>The edge residual capacity property map. The type must be
+a model of a mutable <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
+Property Map</A>. The key type of the map must be the graph's edge
+descriptor type.<BR><B>Default:</B> <TT>get(edge_residual_capacity,
+g)</TT>
+</BLOCKQUOTE>
+<P>IN: <TT>edge_reverse(ReverseEdgeMap rev)</TT>
+</P>
+<BLOCKQUOTE>An edge property map that maps every edge <I>(u,v)</I> in
+the graph to the reverse edge <I>(v,u)</I>. The map must be a model
+of constant <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
+Property Map</A>. The key type of the map must be the graph's edge
+descriptor type.<BR><B>Default:</B> <TT>get(edge_reverse, g)</TT>
+</BLOCKQUOTE>
+<P>UTIL: <TT>vertex_predecessor(PredecessorMap pre_map)</TT>
+</P>
+<BLOCKQUOTE>A vertex property map that stores the edge to the vertex'
+predecessor. The map must be a model of mutable <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
+Property Map</A>. The key type of the map must be the graph's vertex
+descriptor type.<BR><B>Default:</B> <TT>get(vertex_predecessor, g)</TT>
+</BLOCKQUOTE>
+<P>OUT/UTIL: <TT>vertex_color(ColorMap color)</TT>
+</P>
+<BLOCKQUOTE>A vertex property map that stores a color for edge
+vertex. If the color of a vertex after running the algorithm is black
+the vertex belongs to the source tree else it belongs to the
+sink-tree (used for minimum cuts). The map must be a model of mutable
+<A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property
+Map</A>. The key type of the map must be the graph's vertex
+descriptor type.<BR><B>Default:</B> <TT>get(vertex_color, g)</TT>
+</BLOCKQUOTE>
+<P>UTIL: <TT>vertex_distance(DistanceMap dist)</TT>
+</P>
+<BLOCKQUOTE>A vertex property map that stores the distance to the
+corresponding terminal. It's a utility-map for speeding up the
+algorithm. The map must be a model of mutable <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
+Property Map</A>. The key type of the map must be the graph's vertex
+descriptor type.<BR><B>Default:</B> <TT>get(vertex_distance, g)</TT>
+</BLOCKQUOTE>
+<P>IN: <TT>vertex_index(VertexIndexMap index_map)</TT>
+</P>
+<BLOCKQUOTE>Maps each vertex of the graph to a unique integer in the
+range <TT>[0, num_vertices(g))</TT>. The map must be a model of
+constant <A HREF="../../property_map/doc/LvaluePropertyMap.html">LvaluePropertyMap</A>.
+The key type of the map must be the graph's vertex descriptor
+type.<BR><B>Default:</B> <TT>get(vertex_index, g)</TT>
+</BLOCKQUOTE>
+<H3>Example</H3>
+<P>This reads an example maximum flow problem (a graph with edge
+capacities) from a file in the DIMACS format (<TT><A HREF="../example/max_flow.dat">example/max_flow.dat</A></TT>).
+The source for this example can be found in
+<TT><A HREF="../example/boykov_kolmogorov-eg.cpp">example/boykov_kolmogorov-eg.cpp</A></TT>.
+</P>
+<PRE>#include &lt;boost/config.hpp&gt;
+#include &lt;iostream&gt;
+#include &lt;string&gt;
+#include &lt;boost/graph/adjacency_list.hpp&gt;
+#include &lt;boost/graph/boykov_kolmogorov_max_flow.hpp&gt;
+#include &lt;boost/graph/read_dimacs.hpp&gt;
+#include &lt;boost/graph/graph_utility.hpp&gt;
+
+int
+main()
+{
+  using namespace boost;
+
+  typedef adjacency_list_traits &lt; vecS, vecS, directedS &gt; Traits;
+  typedef adjacency_list &lt; vecS, vecS, directedS,
+    property &lt; vertex_name_t, std::string,
+    property &lt; vertex_index_t, long,
+    property &lt; vertex_color_t, boost::default_color_type,
+    property &lt; vertex_distance_t, long,
+ property &lt; vertex_predecessor_t, Traits::edge_descriptor &gt; &gt; &gt; &gt; &gt;,
+
+    property &lt; edge_capacity_t, long,
+    property &lt; edge_residual_capacity_t, long,
+ property &lt; edge_reverse_t, Traits::edge_descriptor &gt; &gt; &gt; &gt; Graph;
+
+  Graph g;
+  property_map &lt; Graph, edge_capacity_t &gt;::type
+      capacity = get(edge_capacity, g);
+  property_map &lt; Graph, edge_residual_capacity_t &gt;::type
+      residual_capacity = get(edge_residual_capacity, g);
+ property_map &lt; Graph, edge_reverse_t &gt;::type rev = get(edge_reverse, g);
+  Traits::vertex_descriptor s, t;
+  read_dimacs_max_flow(g, capacity, rev, s, t);
+
+  std::vector&lt;default_color_type&gt; color(num_vertices(g));
+  std::vector&lt;long&gt; distance(num_vertices(g));
+  long flow = boykov_kolmogorov_max_flow(g ,s, t);
+
+  std::cout &lt;&lt; "c  The total flow:" &lt;&lt; std::endl;
+ std::cout &lt;&lt; "s " &lt;&lt; flow &lt;&lt; std::endl &lt;&lt; std::endl;
+
+  std::cout &lt;&lt; "c flow values:" &lt;&lt; std::endl;
+  graph_traits &lt; Graph &gt;::vertex_iterator u_iter, u_end;
+  graph_traits &lt; Graph &gt;::out_edge_iterator ei, e_end;
+  for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
+    for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
+      if (capacity[*ei] &gt; 0)
+ std::cout &lt;&lt; "f " &lt;&lt; *u_iter &lt;&lt; " " &lt;&lt; target(*ei, g) &lt;&lt; " " + &lt;&lt; (capacity[*ei] - residual_capacity[*ei]) &lt;&lt; std::endl;
+
+  return EXIT_SUCCESS;
+}</PRE><P>
+The output is:
+</P>
+<PRE>c  The total flow:
+s 13
+
+c flow values:
+f 0 6 3
+f 0 1 0
+f 0 2 10
+f 1 5 1
+f 1 0 0
+f 1 3 0
+f 2 4 4
+f 2 3 6
+f 2 0 0
+f 3 7 5
+f 3 2 0
+f 3 1 1
+f 4 5 4
+f 4 6 0
+f 5 4 0
+f 5 7 5
+f 6 7 3
+f 6 4 0
+f 7 6 0
+f 7 5 0</PRE><H3>
+See Also</H3>
+<P STYLE="margin-bottom: 0cm">
+<TT><A HREF="edmonds_karp_max_flow.html">edmonds_karp_max_flow()</A></TT>,
+<TT><A HREF="push_relabel_max_flow.html">push_relabel_max_flow()</A></TT>.
+</P>
+<HR>
+<TABLE CELLPADDING=2 CELLSPACING=2>
+       <TR VALIGN=TOP>
+               <TD>
+                       <P>Copyright &copy; 2006</P>
+               </TD>
+               <TD>
+                       <P>Stephan Diederich, University
+ Mannheim(<A HREF="mailto:diederich@xxxxxxxxxxxxxxxxx";>diederich@xxxxxxxxxxxxxxxxx</A>)</P>
+               </TD>
+       </TR>
+</TABLE>
+<P><BR><BR>
+</P>
+</BODY>
+</HTML>
=======================================
--- /dev/null   
+++ /trunk/libs/graph/doc/figs/bk_max_flow.gif  Mon Aug 23 23:00:26 2010
Binary file, no diff available.
=======================================
--- /dev/null   
+++ /trunk/libs/graph/doc/figs/warning.png      Mon Aug 23 23:00:26 2010
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/libs/graph/doc/random_spanning_tree.html     Mon Aug 23 23:00:26 2010
@@ -0,0 +1,160 @@
+<HTML>
+<!--
+     Copyright 2010 The Trustees of Indiana University.
+
+     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)
+
+      Authors: Jeremiah Willcock
+               Jeremy Siek (due to adaptation from depth_first_search.html)
+               Andrew Lumsdaine
+  -->
+<Head>
+<Title>Boost Graph Library: Random Spanning Tree</Title>
+<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
+        ALINK="#ff0000">
+<IMG SRC="../../../boost.png"
+     ALT="C++ Boost" width="277" height="86">
+
+<BR Clear>
+
+<TT>random_spanning_tree</TT>
+</H1>
+
+<P>
+<PRE>
+<i>// named parameter version</i>
+template &lt;class Graph, class Gen, class class P, class T, class R&gt;
+void random_spanning_tree(Graph&amp; G,
+  Gen&amp; gen,
+  const bgl_named_params&lt;P, T, R&gt;&amp; params);
+
+<i>// non-named parameter versions</i>
+template &lt;class Graph, class Gen, class PredMap, class WeightMap, class ColorMap&gt; +void random_spanning_tree(const Graph&amp; g, Gen&amp; gen, vertex_descriptor root,
+  PredMap pred, WeightMap weight, ColorMap color);
+</PRE>
+
+<p>
+The <tt>random_spanning_tree()</tt> function generates a random spanning tree +on a directed or undirected graph. The algorithm used is Wilson's algorithm (<a +href="bibliography.html#wilson96generating">73</a>, based on <!-- (FIXME: add
+documentation for loop_erased_random_walk()) <a
+href="loop_erased_random_walk.html"> -->loop-erased random walks<!-- </a> -->. There must
+be a path from every non-root vertex of the graph to the root;
+the algorithm typically enters an infinite loop when
+given a graph that does not satisfy this property, but may also throw the
+exception <tt>loop_erased_random_walk_stuck</tt> if the search reaches a vertex
+with no outgoing edges.  Both weighted and unweighted versions of
+<tt>random_spanning_tree()</tt> are
+implemented. In the unweighted version, all spanning trees are equally likely. +In the weighted version, the probability of a particular spanning tree being
+selected is the product of its edge weights.
+In the non-named-parameter
+version of the algorithm, the unweighted version can be selected by passing an +object of type <tt>static_property_map&lt;double&gt;</tt> as the weight map. +In the named-parameter version, leaving off the <tt>weight_map</tt> parameter
+has the same effect.
+</p>
+
+<H3>Where Defined</H3>
+
+<P>
+<a href="../../../boost/graph/random_spanning_tree.hpp"><TT>boost/graph/random_spanning_tree.hpp</TT></a>
+
+<h3>Parameters</h3>
+
+IN: <tt>const Graph&amp; g</tt>
+<blockquote>
+  An undirected graph. The graph type must
+  be a model of <a href="./IncidenceGraph.html">Incidence Graph</a>
+  and <a href="./VertexListGraph.html">Vertex List Graph</a>.<br>
+</blockquote>
+
+IN: <tt>Gen&amp; gen</tt>
+<blockquote>
+  A random number generator. The generator type must
+  be a model of <a
+ href="../../random/doc/reference.html#boost_random.reference.concepts.uniform_random_number_generator">Uniform
+  Random Number Generator</a> or a pointer or reference to such a type.<br>
+</blockquote>
+
+
+<h3>Named Parameters</h3>
+
+IN: <tt>root_vertex(vertex_descriptor root)</tt>
+<blockquote>
+  This parameter, whose type must be the vertex descriptor type of
+ <tt>Graph</tt>, gives the root of the tree to be generated. The default is
+  <tt>*vertices(g).first</tt>.<br>
+</blockquote>
+
+UTIL: <tt>color_map(ColorMap color)</tt>
+<blockquote>
+  This is used by the algorithm to keep track of its progress through
+  the graph. The type <tt>ColorMap</tt> must be a model of <a
+  href="../../property_map/doc/ReadWritePropertyMap.html">Read/Write
+  Property Map</a> and its key type must be the graph's vertex
+  descriptor type and the value type of the color map must model
+  <a href="./ColorValue.html">ColorValue</a>.<br>
+  <b>Default:</b> a <tt>two_bit_color_map</tt> of size
+  <tt>num_vertices(g)</tt> and using the <tt>i_map</tt> for the index
+  map.<br>
+</blockquote>
+
+IN: <tt>vertex_index_map(VertexIndexMap i_map)</tt>
+<blockquote>
+  This maps each vertex to an integer in the range <tt>[0,
+  num_vertices(g))</tt>. This parameter is only necessary when the
+  default color property map is used. The type <tt>VertexIndexMap</tt>
+  must be a model of <a
+  href="../../property_map/doc/ReadablePropertyMap.html">Readable Property
+  Map</a>. The value type of the map must be an integer type. The
+  vertex descriptor type of the graph needs to be usable as the key
+  type of the map.<br>
+</blockquote>
+
+OUT: <tt>predecessor_map(PredMap pred)</tt>
+<blockquote>
+ This map, on output, will contain the predecessor of each vertex in the graph
+  in the spanning tree.  The value
+  <tt>graph_traits&lt;Graph&gt;::null_vertex()</tt> will be used as the
+  predecessor of the root of the tree.  The type <tt>PredMap</tt> must be a
+  model of
+  <a
+ href="../../property_map/doc/ReadWritePropertyMap.html">Read/Write Property + Map</a>. The key and value types of the map must both be the graph's vertex type.<br>
+</blockquote>
+
+IN: <tt>weight_map(WeightMap weight)</tt>
+<blockquote>
+ This map contains the weight of each edge in the graph. The probability of
+  any given spanning tree being produced as the result of the algorithm is
+  proportional to the product of its edge weights.  If the weight map is
+ omitted, a default that gives an equal weight to each edge will be used; a
+  faster algorithm that relies on constant weights will also be invoked.
+  The type <tt>WeightMap</tt> must be a
+  model of
+  <a
+  href="../../property_map/doc/ReadablePropertyMap.html">Readable Property
+ Map</a>. The key type of the map must be the graph's edge type, and the value
+  type must be a real number type (such as <tt>double</tt>).<br>
+</blockquote>
+
+<br>
+<HR>
+<TABLE>
+<TR valign=top>
+<TD nowrap>Copyright &copy; 2000-2001</TD><TD>
+<A HREF="http://www.boost.org/people/jeremy_siek.htm";>Jeremy Siek</A>,
+Indiana University (<A
+HREF="mailto:jsiek@xxxxxxxxxx";>jsiek@xxxxxxxxxx</A>)<br>
+<A HREF="http://www.boost.org/people/liequan_lee.htm";>Lie-Quan Lee</A>, Indiana University (<A HREF="mailto:llee@xxxxxxxxxxxxxx";>llee@xxxxxxxxxxxxxx</A>)<br>
+<A HREF="http://www.osl.iu.edu/~lums";>Andrew Lumsdaine</A>,
+Indiana University (<A
+HREF="mailto:lums@xxxxxxxxxx";>lums@xxxxxxxxxx</A>)
+</TD></TR></TABLE>
+
+</BODY>
+</HTML>
=======================================
--- /dev/null
+++ /trunk/libs/graph/example/boykov_kolmogorov-eg.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,111 @@
+//  Copyright (c) 2006, Stephan Diederich
+//
+//  This code may be used under either of the following two licences:
+//
+//    Permission is hereby granted, free of charge, to any person
+//    obtaining a copy of this software and associated documentation
+//    files (the "Software"), to deal in the Software without
+//    restriction, including without limitation the rights to use,
+//    copy, modify, merge, publish, distribute, sublicense, and/or
+//    sell copies of the Software, and to permit persons to whom the
+//    Software is furnished to do so, subject to the following
+//    conditions:
+//
+//    The above copyright notice and this permission notice shall be
+//    included in all copies or substantial portions of the Software.
+//
+//    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+//    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+//    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+//    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+//    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+//    OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
+//
+//  Or:
+//
+//    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)
+
+#include <boost/config.hpp>
+#include <iostream>
+#include <string>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
+#include <boost/graph/read_dimacs.hpp>
+#include <boost/graph/graph_utility.hpp>
+
+// Use a DIMACS network flow file as stdin.
+// boykov_kolmogorov-eg < max_flow.dat
+//
+// Sample output:
+// c  The total flow:
+// s 13
+//
+// c flow values:
+// f 0 6 3
+// f 0 1 6
+// f 0 2 4
+// f 1 5 1
+// f 1 0 0
+// f 1 3 5
+// f 2 4 4
+// f 2 3 0
+// f 2 0 0
+// f 3 7 5
+// f 3 2 0
+// f 3 1 0
+// f 4 5 0
+// f 4 6 4
+// f 5 4 0
+// f 5 7 1
+// f 6 7 7
+// f 6 4 0
+// f 7 6 0
+// f 7 5 0
+
+int main()
+{
+  using namespace boost;
+
+  typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
+  typedef adjacency_list < vecS, vecS, directedS,
+    property < vertex_name_t, std::string,
+    property < vertex_index_t, long,
+    property < vertex_color_t, boost::default_color_type,
+    property < vertex_distance_t, long,
+    property < vertex_predecessor_t, Traits::edge_descriptor > > > > >,
+
+    property < edge_capacity_t, long,
+    property < edge_residual_capacity_t, long,
+    property < edge_reverse_t, Traits::edge_descriptor > > > > Graph;
+
+  Graph g;
+  property_map < Graph, edge_capacity_t >::type
+      capacity = get(edge_capacity, g);
+  property_map < Graph, edge_residual_capacity_t >::type
+      residual_capacity = get(edge_residual_capacity, g);
+  property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g);
+  Traits::vertex_descriptor s, t;
+  read_dimacs_max_flow(g, capacity, rev, s, t);
+
+  std::vector<default_color_type> color(num_vertices(g));
+  std::vector<long> distance(num_vertices(g));
+  long flow = boykov_kolmogorov_max_flow(g ,s, t);
+
+  std::cout << "c  The total flow:" << std::endl;
+  std::cout << "s " << flow << std::endl << std::endl;
+
+  std::cout << "c flow values:" << std::endl;
+  graph_traits < Graph >::vertex_iterator u_iter, u_end;
+  graph_traits < Graph >::out_edge_iterator ei, e_end;
+  for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
+    for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
+      if (capacity[*ei] > 0)
+        std::cout << "f " << *u_iter << " " << target(*ei, g) << " "
+          << (capacity[*ei] - residual_capacity[*ei]) << std::endl;
+
+  return EXIT_SUCCESS;
+}
=======================================
--- /dev/null
+++ /trunk/libs/graph/test/boykov_kolmogorov_max_flow_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,464 @@
+//  Copyright (c) 2006, Stephan Diederich
+//
+//  This code may be used under either of the following two licences:
+//
+//    Permission is hereby granted, free of charge, to any person
+//    obtaining a copy of this software and associated documentation
+//    files (the "Software"), to deal in the Software without
+//    restriction, including without limitation the rights to use,
+//    copy, modify, merge, publish, distribute, sublicense, and/or
+//    sell copies of the Software, and to permit persons to whom the
+//    Software is furnished to do so, subject to the following
+//    conditions:
+//
+//    The above copyright notice and this permission notice shall be
+//    included in all copies or substantial portions of the Software.
+//
+//    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+//    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+//    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+//    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+//    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+//    OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
+//
+//  Or:
+//
+//    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)
+
+#include <vector>
+#include <iterator>
+#include <iostream>
+#include <algorithm>
+#include <fstream>
+
+#include <boost/test/minimal.hpp>
+#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/adjacency_matrix.hpp>
+#include <boost/graph/random.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/lexical_cast.hpp>
+
+using namespace boost;
+
+template <typename Graph, typename CapacityMap, typename ReverseEdgeMap>
+std::pair< typename graph_traits<Graph>::vertex_descriptor,typename graph_traits<Graph>::vertex_descriptor> +fill_random_max_flow_graph(Graph& g, CapacityMap cap, ReverseEdgeMap rev, typename graph_traits<Graph>::vertices_size_type n_verts, + typename graph_traits<Graph>::edges_size_type n_edges, std::size_t seed)
+{
+  typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+  const int cap_low = 1;
+  const int cap_high = 1000;
+
+  //init random numer generator
+  minstd_rand gen(seed);
+  //generate graph
+  generate_random_graph(g, n_verts, n_edges, gen);
+
+  //init an uniform distribution int generator
+  typedef variate_generator<minstd_rand, uniform_int<int> > tIntGen;
+  tIntGen int_gen(gen, uniform_int<int>(cap_low, cap_high));
+  //randomize edge-capacities
+ //randomize_property<edge_capacity, Graph, tIntGen> (g,int_gen); //we cannot use this, as we have no idea how properties are stored, right?
+  typename graph_traits<Graph>::edge_iterator ei, e_end;
+  for(boost::tie(ei,e_end) = edges(g); ei != e_end; ++ei)
+    cap[*ei] = int_gen();
+
+  //get source and sink node
+  vertex_descriptor s = random_vertex(g, gen);
+  vertex_descriptor t = graph_traits<Graph>::null_vertex();
+  while(t == graph_traits<Graph>::null_vertex() || t == s)
+    t = random_vertex(g, gen);
+
+  //add reverse edges (ugly... how to do better?!)
+  std::list<edge_descriptor> edges_copy;
+  boost::tie(ei, e_end) = edges(g);
+ std::copy(ei, e_end, std::back_insert_iterator< std::list<edge_descriptor> >(edges_copy));
+  while(!edges_copy.empty()){
+    edge_descriptor old_edge = edges_copy.front();
+    edges_copy.pop_front();
+    vertex_descriptor source_vertex = target(old_edge, g);
+    vertex_descriptor target_vertex = source(old_edge, g);
+    bool inserted;
+    edge_descriptor  new_edge;
+ boost::tie(new_edge,inserted) = add_edge(source_vertex, target_vertex, g);
+    assert(inserted);
+    rev[old_edge] = new_edge;
+    rev[new_edge] = old_edge ;
+    cap[new_edge] = 0;
+  }
+  return std::make_pair(s,t);
+}
+
+long test_adjacency_list_vecS(int n_verts, int n_edges, std::size_t seed){
+  typedef adjacency_list_traits<vecS, vecS, directedS> tVectorTraits;
+  typedef adjacency_list<vecS, vecS, directedS,
+  property<vertex_index_t, long,
+  property<vertex_predecessor_t, tVectorTraits::edge_descriptor,
+  property<vertex_color_t, boost::default_color_type,
+  property<vertex_distance_t, long> > > >,
+  property<edge_capacity_t, long,
+  property<edge_residual_capacity_t, long,
+ property<edge_reverse_t, tVectorTraits::edge_descriptor > > > > tVectorGraph;
+
+  tVectorGraph g;
+
+  graph_traits<tVectorGraph>::vertex_descriptor src,sink;
+ boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed);
+
+  return boykov_kolmogorov_max_flow(g, get(edge_capacity, g),
+                                    get(edge_residual_capacity, g),
+                                    get(edge_reverse, g),
+                                    get(vertex_predecessor, g),
+                                    get(vertex_color, g),
+                                    get(vertex_distance, g),
+                                    get(vertex_index, g),
+                                    src, sink);
+}
+
+long test_adjacency_list_listS(int n_verts, int n_edges, std::size_t seed){
+  typedef adjacency_list_traits<listS, listS, directedS> tListTraits;
+  typedef adjacency_list<listS, listS, directedS,
+  property<vertex_index_t, long,
+  property<vertex_predecessor_t, tListTraits::edge_descriptor,
+  property<vertex_color_t, boost::default_color_type,
+  property<vertex_distance_t, long> > > >,
+  property<edge_capacity_t, long,
+  property<edge_residual_capacity_t, long,
+  property<edge_reverse_t, tListTraits::edge_descriptor > > > > tListGraph;
+
+  tListGraph g;
+
+  graph_traits<tListGraph>::vertex_descriptor src,sink;
+ boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed);
+
+  //initialize vertex indices
+  graph_traits<tListGraph>::vertex_iterator vi,v_end;
+  graph_traits<tListGraph>::vertices_size_type index = 0;
+  for(boost::tie(vi, v_end) = vertices(g); vi != v_end; ++vi){
+    put(vertex_index, g, *vi, index++);
+  }
+  return boykov_kolmogorov_max_flow(g, get(edge_capacity, g),
+                                    get(edge_residual_capacity, g),
+                                    get(edge_reverse, g),
+                                    get(vertex_predecessor, g),
+                                    get(vertex_color, g),
+                                    get(vertex_distance, g),
+                                    get(vertex_index, g),
+                                    src, sink);
+}
+
+template<typename EdgeDescriptor>
+    struct Node{
+  boost::default_color_type vertex_color;
+  long vertex_distance;
+  EdgeDescriptor vertex_predecessor;
+};
+
+template<typename EdgeDescriptor>
+    struct Link{
+  long edge_capacity;
+  long edge_residual_capacity;
+  EdgeDescriptor edge_reverse;
+};
+
+long test_bundled_properties(int n_verts, int n_edges, std::size_t seed){
+  typedef adjacency_list_traits<vecS, vecS, directedS> tTraits;
+  typedef Node<tTraits::edge_descriptor> tVertex;
+  typedef Link<tTraits::edge_descriptor> tEdge;
+ typedef adjacency_list<vecS, vecS, directedS, tVertex, tEdge> tBundleGraph;
+
+  tBundleGraph g;
+
+  graph_traits<tBundleGraph>::vertex_descriptor src,sink;
+ boost::tie(src,sink) = fill_random_max_flow_graph(g, get(&tEdge::edge_capacity,g), get(&tEdge::edge_reverse, g), n_verts, n_edges, seed);
+  return boykov_kolmogorov_max_flow(g, get(&tEdge::edge_capacity, g),
+                                    get(&tEdge::edge_residual_capacity, g),
+                                    get(&tEdge::edge_reverse, g),
+                                    get(&tVertex::vertex_predecessor, g),
+                                    get(&tVertex::vertex_color, g),
+                                    get(&tVertex::vertex_distance, g),
+                                    get(vertex_index, g),
+                                    src, sink);
+}
+
+long test_overloads(int n_verts, int n_edges, std::size_t seed){
+  typedef adjacency_list_traits<vecS, vecS, directedS> tTraits;
+  typedef property <edge_capacity_t, long,
+     property<edge_residual_capacity_t, long,
+     property<edge_reverse_t, tTraits::edge_descriptor> > >tEdgeProperty;
+ typedef adjacency_list<vecS, vecS, directedS, no_property, tEdgeProperty> tGraph;
+
+  tGraph g;
+
+  graph_traits<tGraph>::vertex_descriptor src,sink;
+ boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed);
+
+ std::vector<graph_traits<tGraph>::edge_descriptor> predecessor_vec(n_verts);
+  std::vector<default_color_type> color_vec(n_verts);
+ std::vector<graph_traits<tGraph>::vertices_size_type> distance_vec(n_verts);
+
+  long flow_overload_1 =
+    boykov_kolmogorov_max_flow(g,
+                               get(edge_capacity,g),
+                               get(edge_residual_capacity,g),
+                               get(edge_reverse,g),
+                               get(vertex_index,g),
+                               src, sink);
+
+  long flow_overload_2 =
+    boykov_kolmogorov_max_flow(g,
+                               get(edge_capacity,g),
+                               get(edge_residual_capacity,g),
+                               get(edge_reverse,g),
+                               &(color_vec[0]),
+                               get(vertex_index,g),
+                               src, sink);
+
+  BOOST_CHECK(flow_overload_1 == flow_overload_2);
+  return flow_overload_1;
+}
+
+template<class Graph,
+         class EdgeCapacityMap,
+         class ResidualCapacityEdgeMap,
+         class ReverseEdgeMap,
+         class PredecessorMap,
+         class ColorMap,
+         class DistanceMap,
+         class IndexMap>
+class boykov_kolmogorov_test
+  : public detail::bk_max_flow<
+      Graph, EdgeCapacityMap, ResidualCapacityEdgeMap, ReverseEdgeMap,
+      PredecessorMap, ColorMap, DistanceMap, IndexMap
+    >
+{
+
+  typedef typename graph_traits<Graph>::edge_descriptor tEdge;
+  typedef typename graph_traits<Graph>::vertex_descriptor tVertex;
+ typedef typename property_traits< typename property_map<Graph, edge_capacity_t>::const_type>::value_type tEdgeVal;
+  typedef typename graph_traits<Graph>::vertex_iterator tVertexIterator;
+  typedef typename graph_traits<Graph>::out_edge_iterator tOutEdgeIterator;
+  typedef typename property_traits<ColorMap>::value_type tColorValue;
+  typedef color_traits<tColorValue> tColorTraits;
+  typedef typename property_traits<DistanceMap>::value_type tDistanceVal;
+  typedef typename detail::bk_max_flow<
+    Graph, EdgeCapacityMap, ResidualCapacityEdgeMap, ReverseEdgeMap,
+    PredecessorMap, ColorMap, DistanceMap, IndexMap
+  > tSuper;
+  public:
+        boykov_kolmogorov_test(Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src, + typename graph_traits<Graph>::vertex_descriptor sink)
+          : tSuper(g, get(edge_capacity,g), get(edge_residual_capacity,g),
+                   get(edge_reverse, g), get(vertex_predecessor, g),
+                   get(vertex_color, g), get(vertex_distance, g),
+                   get(vertex_index, g), src, sink)
+          { }
+
+        void invariant_four(tVertex v) const{
+          //passive nodes in S or T
+          if(v == tSuper::m_source || v == tSuper::m_sink)
+            return;
+ typename std::list<tVertex>::const_iterator it = find(tSuper::m_orphans.begin(), tSuper::m_orphans.end(), v); + // a node is active, if its in the active_list AND (is has_a_parent, or its already in the orphans_list or its the sink, or its the source) + bool is_active = (tSuper::m_in_active_list_map[v] && (tSuper::has_parent(v) || it != tSuper::m_orphans.end() ));
+          if(this->get_tree(v) != tColorTraits::gray() && !is_active){
+            typename graph_traits<Graph>::out_edge_iterator ei,e_end;
+ for(boost::tie(ei, e_end) = out_edges(v, tSuper::m_g); ei != e_end; ++ei){
+              const tVertex& other_node = target(*ei, tSuper::m_g);
+              if(this->get_tree(other_node) != this->get_tree(v)){
+                if(this->get_tree(v) == tColorTraits::black())
+                  BOOST_CHECK(tSuper::m_res_cap_map[*ei] == 0);
+                else
+ BOOST_CHECK(tSuper::m_res_cap_map[tSuper::m_rev_edge_map[*ei]] == 0);
+              }
+             }
+          }
+        }
+
+        void invariant_five(const tVertex& v) const{
+ BOOST_CHECK(this->get_tree(v) != tColorTraits::gray() || tSuper::m_time_map[v] <= tSuper::m_time);
+        }
+
+        void invariant_six(const tVertex& v) const{
+ if(this->get_tree(v) == tColorTraits::gray() || tSuper::m_time_map[v] != tSuper::m_time)
+            return;
+          else{
+            tVertex current_node = v;
+            tDistanceVal distance = 0;
+            tColorValue color = this->get_tree(v);
+ tVertex terminal = (color == tColorTraits::black()) ? tSuper::m_source : tSuper::m_sink;
+            while(current_node != terminal){
+              BOOST_CHECK(tSuper::has_parent(current_node));
+              tEdge e = this->get_edge_to_parent(current_node);
+              ++distance;
+ current_node = (color == tColorTraits::black())? source(e, tSuper::m_g) : target(e, tSuper::m_g);
+              if(distance > tSuper::m_dist_map[v])
+                break;
+            }
+            BOOST_CHECK(distance == tSuper::m_dist_map[v]);
+          }
+        }
+
+        void invariant_seven(const tVertex& v) const{
+          if(this->get_tree(v) == tColorTraits::gray())
+            return;
+          else{
+            tColorValue color = this->get_tree(v);
+            long time = tSuper::m_time_map[v];
+            tVertex current_node = v;
+            while(tSuper::has_parent(current_node)){
+              tEdge e = this->get_edge_to_parent(current_node);
+ current_node = (color == tColorTraits::black()) ? source(e, tSuper::m_g) : target(e, tSuper::m_g);
+              BOOST_CHECK(tSuper::m_time_map[current_node] >= time);
+            }
+          }
+        }//invariant_seven
+
+        void invariant_eight(const tVertex& v) const{
+          if(this->get_tree(v) == tColorTraits::gray())
+             return;
+          else{
+            tColorValue color = this->get_tree(v);
+            long time = tSuper::m_time_map[v];
+            tDistanceVal distance = tSuper::m_dist_map[v];
+            tVertex current_node = v;
+            while(tSuper::has_parent(current_node)){
+              tEdge e = this->get_edge_to_parent(current_node);
+ current_node = (color == tColorTraits::black()) ? source(e, tSuper::m_g) : target(e, tSuper::m_g);
+              if(tSuper::m_time_map[current_node] == time)
+                BOOST_CHECK(tSuper::m_dist_map[current_node] < distance);
+            }
+          }
+        }//invariant_eight
+
+        void check_invariants(){
+          tVertexIterator vi, v_end;
+ for(boost::tie(vi, v_end) = vertices(tSuper::m_g); vi != v_end; ++vi){
+            invariant_four(*vi);
+            invariant_five(*vi);
+            invariant_six(*vi);
+            invariant_seven(*vi);
+            invariant_eight(*vi);
+          }
+        }
+
+        tEdgeVal test(){
+          this->add_active_node(this->m_sink);
+          this->augment_direct_paths();
+          check_invariants();
+          //start the main-loop
+          while(true){
+            bool path_found;
+            tEdge connecting_edge;
+ boost::tie(connecting_edge, path_found) = this->grow(); //find a path from source to sink
+            if(!path_found){
+                //we're finished, no more paths were found
+              break;
+            }
+            check_invariants();
+            this->m_time++;
+            this->augment(connecting_edge); //augment that path
+            check_invariants();
+            this->adopt(); //rebuild search tree structure
+            check_invariants();
+          }
+
+          //check if flow is the sum of outgoing edges of src
+          tOutEdgeIterator ei, e_end;
+          tEdgeVal src_sum = 0;
+ for(boost::tie(ei, e_end) = out_edges(this->m_source, this->m_g); ei != e_end; ++ei){
+            src_sum += this->m_cap_map[*ei] - this->m_res_cap_map[*ei];
+          }
+          BOOST_CHECK(this->m_flow == src_sum);
+          //check if flow is the sum of ingoing edges of sink
+          tEdgeVal sink_sum = 0;
+ for(boost::tie(ei, e_end) = out_edges(this->m_sink, this->m_g); ei != e_end; ++ei){
+            tEdge in_edge = this->m_rev_edge_map[*ei];
+ sink_sum += this->m_cap_map[in_edge] - this->m_res_cap_map[in_edge];
+          }
+          BOOST_CHECK(this->m_flow == sink_sum);
+          return this->m_flow;
+        }
+};
+
+long test_algorithms_invariant(int n_verts, int n_edges, std::size_t seed)
+{
+  typedef adjacency_list_traits<vecS, vecS, directedS> tVectorTraits;
+  typedef adjacency_list<vecS, vecS, directedS,
+  property<vertex_index_t, long,
+  property<vertex_predecessor_t, tVectorTraits::edge_descriptor,
+  property<vertex_color_t, default_color_type,
+  property<vertex_distance_t, long> > > >,
+  property<edge_capacity_t, long,
+  property<edge_residual_capacity_t, long,
+ property<edge_reverse_t, tVectorTraits::edge_descriptor > > > > tVectorGraph;
+
+  tVectorGraph g;
+
+  graph_traits<tVectorGraph>::vertex_descriptor src, sink;
+ boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed);
+
+  typedef property_map<tVectorGraph, edge_capacity_t>::type tEdgeCapMap;
+ typedef property_map<tVectorGraph, edge_residual_capacity_t>::type tEdgeResCapMap;
+  typedef property_map<tVectorGraph, edge_reverse_t>::type tRevEdgeMap;
+ typedef property_map<tVectorGraph, vertex_predecessor_t>::type tVertexPredMap;
+  typedef property_map<tVectorGraph, vertex_color_t>::type tVertexColorMap;
+  typedef property_map<tVectorGraph, vertex_distance_t>::type tDistanceMap;
+  typedef property_map<tVectorGraph, vertex_index_t>::type tIndexMap;
+  typedef boykov_kolmogorov_test<
+    tVectorGraph, tEdgeCapMap, tEdgeResCapMap, tRevEdgeMap, tVertexPredMap,
+    tVertexColorMap, tDistanceMap, tIndexMap
+  > tKolmo;
+  tKolmo instance(g, src, sink);
+  return instance.test();
+}
+
+int test_main(int argc, char* argv[])
+{
+  int n_verts = 10;
+  int n_edges = 500;
+  std::size_t seed = 1;
+
+  if (argc > 1) n_verts = lexical_cast<int>(argv[1]);
+  if (argc > 2) n_edges = lexical_cast<int>(argv[2]);
+  if (argc > 3) seed = lexical_cast<std::size_t>(argv[3]);
+
+  //we need at least 2 vertices to create src and sink in random graphs
+  //this case is also caught in boykov_kolmogorov_max_flow
+  if (n_verts<2)
+    n_verts = 2;
+
+ // below are checks for different calls to boykov_kolmogorov_max_flow and different graph-types
+
+  //checks support of vecS storage
+  long flow_vecS = test_adjacency_list_vecS(n_verts, n_edges, seed);
+  std::cout << "vecS flow: " << flow_vecS << std::endl;
+ //checks support of listS storage (especially problems with vertex indices)
+  long flow_listS = test_adjacency_list_listS(n_verts, n_edges, seed);
+  std::cout << "listS flow: " << flow_listS << std::endl;
+  BOOST_CHECK(flow_vecS == flow_listS);
+  //checks bundled properties
+  long flow_bundles = test_bundled_properties(n_verts, n_edges, seed);
+  std::cout << "bundles flow: " << flow_bundles << std::endl;
+  BOOST_CHECK(flow_listS == flow_bundles);
+  //checks overloads
+  long flow_overloads = test_overloads(n_verts, n_edges, seed);
+  std::cout << "overloads flow: " << flow_overloads << std::endl;
+  BOOST_CHECK(flow_bundles == flow_overloads);
+
+ // excessive test version where Boykov-Kolmogorov's algorithm invariants are
+  // checked
+  long flow_invariants = test_algorithms_invariant(n_verts, n_edges, seed);
+  std::cout << "invariants flow: " << flow_invariants << std::endl;
+  BOOST_CHECK(flow_overloads == flow_invariants);
+  return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/graph/test/random_spanning_tree_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,69 @@
+// Copyright 2010 The Trustees of Indiana University.
+
+// 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)
+
+//  Authors: Jeremiah Willcock
+//           Andrew Lumsdaine
+
+#include <boost/graph/random_spanning_tree.hpp>
+#include <boost/graph/grid_graph.hpp>
+#include <boost/array.hpp>
+#include <boost/random.hpp>
+#include <boost/property_map/shared_array_property_map.hpp>
+#include <boost/property_map/dynamic_property_map.hpp>
+#include <boost/graph/graphviz.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/graph/property_maps/constant_property_map.hpp>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <boost/graph/iteration_macros.hpp>
+
+using namespace boost;
+using namespace std;
+
+typedef grid_graph<2> graph_type;
+typedef graph_traits<graph_type> gt;
+
+template <typename Graph, typename PredMap, typename WeightMap>
+void write_spanning_tree(const Graph& g, PredMap pred, WeightMap weight, string filename) { + shared_array_property_map<string, typename property_map<Graph, edge_index_t>::const_type> edge_style(num_edges(g), get(edge_index, g)); + shared_array_property_map<string, typename property_map<Graph, vertex_index_t>::const_type> vertex_pos(num_vertices(g), get(vertex_index, g));
+  BGL_FORALL_EDGES_T(e, g, Graph) {
+ put(edge_style, e, (get(pred, target(e, g)) == source(e, g) || get(pred, source(e, g)) == target(e, g)) ? "bold" : "dotted");
+  }
+  BGL_FORALL_VERTICES_T(v, g, Graph) {
+ put(vertex_pos, v, lexical_cast<string>(v[0]) + "," + lexical_cast<string>(v[1]));
+  }
+  dynamic_properties dp;
+  dp.property("style", edge_style);
+  dp.property("pos", vertex_pos);
+  dp.property("len", weight);
+  dp.property("node_id", get(vertex_index, g));
+  ofstream out(filename.c_str());
+  write_graphviz_dp(out, g, dp);
+}
+
+int main(int, char**) {
+
+  array<size_t, 2> sizes = {{ 5, 5 }};
+  graph_type g(sizes);
+
+ shared_array_property_map<gt::vertex_descriptor, property_map<graph_type, vertex_index_t>::const_type> pred(num_vertices(g), get(vertex_index, g)); + shared_array_property_map<double, property_map<graph_type, edge_index_t>::const_type> weight(num_edges(g), get(edge_index, g));
+
+ BGL_FORALL_EDGES(e, g, graph_type) {put(weight, e, (1. + get(edge_index, g, e)) / num_edges(g));}
+
+  boost::mt19937 gen;
+  random_spanning_tree(g, gen, predecessor_map(pred));
+ // write_spanning_tree(g, pred, constant_property_map<gt::edge_descriptor, double>(1.), "unweight_random_st.dot");
+  random_spanning_tree(g, gen, predecessor_map(pred));
+ // write_spanning_tree(g, pred, constant_property_map<gt::edge_descriptor, double>(1.), "unweight_random_st2.dot");
+
+  random_spanning_tree(g, gen, predecessor_map(pred).weight_map(weight));
+  // write_spanning_tree(g, pred, weight, "weight_random_st.dot");
+
+  return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/Jamfile.v2       Mon Aug 23 23:00:26 2010
@@ -0,0 +1,33 @@
+# Boost Intrusive Library Test Jamfile
+#  (C) Copyright Ion Gaztanaga 2006.
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Adapted from John Maddock's TR1 Jamfile.v2
+# Copyright John Maddock 2005.
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# this rule enumerates through all the sources and invokes
+# the run rule for each source, the result is a list of all
+# the run rules, which we can pass on to the test_suite rule:
+
+rule test_all
+{
+   local all_rules = ;
+
+   for local fileb in [ glob *.cpp ]
+   {
+      all_rules += [ run $(fileb)
+      :  # additional args
+      :  # test-files
+      :  # requirements
+      ] ;
+   }
+
+   return $(all_rules) ;
+}
+
+test-suite intrusive_test : [ test_all r ] : <threading>multi ;
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/any_test.cpp     Mon Aug 23 23:00:26 2010
@@ -0,0 +1,191 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include<boost/intrusive/detail/config_begin.hpp>
+#include<boost/intrusive/any_hook.hpp>
+#include<boost/intrusive/slist.hpp>
+#include<boost/intrusive/rbtree.hpp>
+#include<boost/intrusive/list.hpp>
+#include<boost/intrusive/avltree.hpp>
+#include<boost/intrusive/sgtree.hpp>
+#include<boost/intrusive/splaytree.hpp>
+#include<boost/intrusive/treap.hpp>
+#include<boost/intrusive/hashtable.hpp>
+#include<boost/functional/hash.hpp>
+#include <vector>    //std::vector
+#include <cstddef>   //std::size_t
+
+using namespace boost::intrusive;
+
+class MyClass : public any_base_hook<>
+{
+   int int_;
+
+   public:
+   //This is a member hook
+   any_member_hook<> member_hook_;
+
+   MyClass(int i = 0)
+      :  int_(i)
+   {}
+
+   int get() const
+   {  return this->int_;  }
+
+   friend bool operator  < (const MyClass &l, const MyClass &r)
+   {  return l.int_ < r.int_; }
+
+   friend bool operator == (const MyClass &l, const MyClass &r)
+   {  return l.int_ == r.int_; }
+
+   friend std::size_t hash_value(const MyClass &o)
+   {  return boost::hash<int>()(o.get());  }
+
+   friend bool priority_order(const MyClass &a, const MyClass &b)
+   {  return a.int_ < b.int_;  }
+};
+
+
+void instantiation_test()
+{
+ typedef member_hook< MyClass, any_member_hook<>, &MyClass::member_hook_> MemberHook;
+   typedef base_hook< any_base_hook<> > BaseHook;
+
+   MyClass myclass;
+   {
+      slist < MyClass, any_to_slist_hook< BaseHook > > slist_base;
+      slist_base.push_front(myclass);
+   }
+   {
+      slist < MyClass, any_to_slist_hook< MemberHook > > slist_member;
+      slist_member.push_front(myclass);
+   }
+   {
+      list < MyClass, any_to_list_hook< BaseHook > > list_base;
+      list_base.push_front(myclass);
+   }
+   {
+      list < MyClass, any_to_list_hook< MemberHook > > list_member;
+      list_member.push_front(myclass);
+   }
+   {
+      rbtree < MyClass, any_to_set_hook< BaseHook > >  rbtree_base;
+      rbtree_base.insert_unique(myclass);
+   }
+   {
+      rbtree < MyClass, any_to_set_hook< MemberHook > > rbtree_member;
+      rbtree_member.insert_unique(myclass);
+   }
+   {
+      avltree < MyClass, any_to_avl_set_hook< BaseHook > > avltree_base;
+      avltree_base.insert_unique(myclass);
+   }
+   {
+ avltree < MyClass, any_to_avl_set_hook< MemberHook > > avltree_member;
+      avltree_member.insert_unique(myclass);
+   }
+   {
+      sgtree < MyClass, any_to_bs_set_hook< BaseHook > > sgtree_base;
+      sgtree_base.insert_unique(myclass);
+   }
+   {
+      sgtree < MyClass, any_to_bs_set_hook< MemberHook > > sgtree_member;
+      sgtree_member.insert_unique(myclass);
+   }
+   {
+      treap < MyClass, any_to_bs_set_hook< BaseHook > > treap_base;
+      treap_base.insert_unique(myclass);
+   }
+   {
+      treap < MyClass, any_to_bs_set_hook< MemberHook > > treap_member;
+      treap_member.insert_unique(myclass);
+   }
+   {
+      splaytree < MyClass, any_to_bs_set_hook< BaseHook > > splaytree_base;
+      splaytree_base.insert_unique(myclass);
+   }
+   {
+ splaytree < MyClass, any_to_bs_set_hook< MemberHook > > splaytree_member;
+      splaytree_member.insert_unique(myclass);
+   }
+ typedef unordered_bucket<any_to_unordered_set_hook< BaseHook > >::type bucket_type; + typedef unordered_default_bucket_traits<any_to_unordered_set_hook< BaseHook > >::type bucket_traits;
+   bucket_type buckets[2];
+   {
+      hashtable < MyClass, any_to_unordered_set_hook< BaseHook > >
+         hashtable_base(bucket_traits(&buckets[0], 1));
+      hashtable_base.insert_unique(myclass);
+   }
+   {
+      hashtable < MyClass, any_to_unordered_set_hook< MemberHook > >
+         hashtable_member(bucket_traits(&buckets[1], 1));
+      hashtable_member.insert_unique(myclass);
+   }
+}
+
+bool simple_slist_test()
+{
+   //Define an slist that will store MyClass using the public base hook
+   typedef any_to_slist_hook< base_hook< any_base_hook<> > >BaseOption;
+   typedef slist<MyClass, BaseOption, constant_time_size<false> > BaseList;
+
+   //Define an slist that will store MyClass using the public member hook
+ typedef any_to_slist_hook< member_hook<MyClass, any_member_hook<>, &MyClass::member_hook_> > MemberOption;
+   typedef slist<MyClass, MemberOption> MemberList;
+
+   typedef std::vector<MyClass>::iterator VectIt;
+   typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+   //Create several MyClass objects, each one with a different value
+   std::vector<MyClass> values;
+   for(int i = 0; i < 100; ++i)  values.push_back(MyClass(i));
+
+   BaseList baselist;
+   MemberList memberlist;
+
+   //Now insert them in the reverse order in the base hook list
+   for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
+      baselist.push_front(*it);
+
+   //Now insert them in the same order as in vector in the member hook list
+   for(BaseList::iterator it(baselist.begin()), itend(baselist.end())
+      ; it != itend; ++it){
+      memberlist.push_front(*it);
+   }
+
+   //Now test lists
+   {
+      BaseList::iterator bit(baselist.begin()), bitend(baselist.end());
+ MemberList::iterator mit(memberlist.begin()), mitend(memberlist.end());
+      VectRit rit(values.rbegin()), ritend(values.rend());
+      VectIt  it(values.begin()), itend(values.end());
+
+      //Test the objects inserted in the base hook list
+      for(; rit != ritend; ++rit, ++bit)
+         if(&*bit != &*rit)   return false;
+
+      //Test the objects inserted in the member hook list
+      for(; it != itend; ++it, ++mit)
+         if(&*mit != &*it)    return false;
+   }
+   return true;
+}
+
+int main()
+{
+   if(!simple_slist_test())
+      return 1;
+   instantiation_test();
+   return 0;
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/avl_multiset_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,158 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_multiset_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::avl_multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef avl_set_base_hook<void_pointer<VoidPointer> >    base_hook_type;
+   typedef avl_set_base_hook
+      <link_mode<auto_unlink>
+      , void_pointer<VoidPointer>
+      , tag<my_tag>
+ , optimize_size<true> > auto_base_hook_type;
+   typedef avl_set_member_hook
+ <void_pointer<VoidPointer> > member_hook_type;
+   typedef avl_set_member_hook
+      < link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::avl_multiset
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/avl_set_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,160 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_set_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::avl_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef avl_set_base_hook<void_pointer<VoidPointer> >    base_hook_type;
+   typedef avl_set_base_hook
+      <link_mode<auto_unlink>
+      , void_pointer<VoidPointer>
+      , tag<my_tag>
+ , optimize_size<true> > auto_base_hook_type;
+   typedef avl_set_member_hook
+ <void_pointer<VoidPointer> > member_hook_type;
+   typedef avl_set_member_hook
+      < link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::avl_set
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+
+   return boost::report_errors();
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/common_functors.hpp      Mon Aug 23 23:00:26 2010
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_TEST_COMMON_FUNCTORS_HPP
+#define BOOST_INTRUSIVE_TEST_COMMON_FUNCTORS_HPP
+
+#include<boost/intrusive/detail/utilities.hpp>
+#include<boost/intrusive/detail/mpl.hpp>
+
+namespace boost      {
+namespace intrusive  {
+namespace test       {
+
+template<class T>
+class delete_disposer
+{
+   public:
+   template <class Pointer>
+      void operator()(Pointer p)
+   {
+ typedef typename std::iterator_traits<Pointer>::value_type value_type; + BOOST_INTRUSIVE_INVARIANT_ASSERT(( detail::is_same<T, value_type>::value ));
+      delete detail::get_pointer(p);
+   }
+};
+
+template<class T>
+class new_cloner
+{
+   public:
+      T *operator()(const T &t)
+   {  return new T(t);  }
+};
+
+template<class T>
+class new_default_factory
+{
+   public:
+      T *operator()()
+   {  return new T();  }
+};
+
+}  //namespace test       {
+}  //namespace intrusive  {
+}  //namespace boost      {
+
+#endif
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/custom_bucket_traits_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,127 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/functional/hash.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass : public unordered_set_base_hook<>
+{
+   int int_;
+
+   public:
+   MyClass(int i = 0) : int_(i)
+   {}
+   unordered_set_member_hook<> member_hook_;
+
+   friend bool operator==(const MyClass &l, const MyClass &r)
+   {  return l.int_ == r.int_;   }
+
+   friend std::size_t hash_value(const MyClass &v)
+   {  return boost::hash_value(v.int_); }
+};
+
+struct uset_value_traits
+{
+   typedef slist_node_traits<void*>          node_traits;
+   typedef node_traits::node_ptr             node_ptr;
+   typedef node_traits::const_node_ptr       const_node_ptr;
+   typedef MyClass                           value_type;
+   typedef MyClass *                         pointer;
+   typedef const MyClass *                   const_pointer;
+   static const link_mode_type link_mode =   normal_link;
+
+   static node_ptr to_node_ptr (value_type &value)
+      {  return node_ptr(&value); }
+   static const_node_ptr to_node_ptr (const value_type &value)
+      {  return const_node_ptr(&value); }
+   static pointer to_value_ptr(node_ptr n)
+      {  return static_cast<value_type*>(n); }
+   static const_pointer to_value_ptr(const_node_ptr n)
+      {  return static_cast<const value_type*>(n); }
+};
+
+//Base
+typedef base_hook< unordered_set_base_hook<> >  BaseHook;
+typedef unordered_bucket<BaseHook>::type        BaseBucketType;
+typedef unordered_set<MyClass, BaseHook>        BaseUset;
+//Member
+typedef member_hook
+   < MyClass, unordered_set_member_hook<>
+   , &MyClass::member_hook_ >                   MemberHook;
+typedef unordered_bucket<MemberHook>::type      MemberBucketType;
+typedef unordered_set<MyClass, MemberHook>      MemberUset;
+//Explicit
+typedef value_traits< uset_value_traits >       Traits;
+typedef unordered_bucket<Traits>::type          TraitsBucketType;
+typedef unordered_set<MyClass, Traits>          TraitsUset;
+
+struct uset_bucket_traits
+{
+   //Power of two bucket length
+   static const std::size_t NumBuckets = 128;
+
+   uset_bucket_traits(BaseBucketType *buckets)
+      :  buckets_(buckets)
+   {}
+
+   uset_bucket_traits(const uset_bucket_traits &other)
+      :  buckets_(other.buckets_)
+   {}
+
+   BaseBucketType * bucket_begin() const
+   {  return buckets_;  }
+
+   std::size_t bucket_count() const
+   {  return NumBuckets;  }
+
+   BaseBucketType *buckets_;
+};
+
+typedef unordered_set
+   <MyClass, bucket_traits<uset_bucket_traits>, power_2_buckets<true> >
+      BucketTraitsUset;
+
+int main()
+{
+   if(!detail::is_same<BaseUset::bucket_type, BaseBucketType>::value)
+      return 1;
+   if(!detail::is_same<MemberUset::bucket_type, MemberBucketType>::value)
+      return 1;
+   if(!detail::is_same<TraitsUset::bucket_type, TraitsBucketType>::value)
+      return 1;
+   if(!detail::is_same<BaseBucketType, MemberBucketType>::value)
+      return 1;
+   if(!detail::is_same<BaseBucketType, TraitsBucketType>::value)
+      return 1;
+
+   typedef std::vector<MyClass>::iterator VectIt;
+   typedef std::vector<MyClass>::reverse_iterator VectRit;
+   std::vector<MyClass> values;
+
+   for(int i = 0; i < 100; ++i)  values.push_back(MyClass(i));
+
+   BaseBucketType buckets[uset_bucket_traits::NumBuckets];
+   uset_bucket_traits btraits(buckets);
+   BucketTraitsUset uset(btraits);
+
+   for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
+      uset.insert(*it);
+
+ for( VectRit it(values.rbegin()), itend(values.rend()); it != itend; ++it){
+      if(uset.find(*it) == uset.cend())  return 1;
+   }
+
+   return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/default_hook_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,126 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include "smart_ptr.hpp"
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+
+:  public list_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+,  public slist_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+,  public set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+,  public unordered_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+,  public avl_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+,  public splay_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+,  public bs_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+{
+   int int_;
+
+   public:
+   MyClass(int i)
+      :  int_(i)
+   {}
+
+   friend bool operator<(const MyClass &l, const MyClass &r)
+   {  return l.int_ < r.int_; }
+
+   friend bool operator==(const MyClass &l, const MyClass &r)
+   {  return l.int_ == r.int_; }
+
+   friend std::size_t hash_value(const MyClass &v)
+   {  return boost::hash_value(v.int_); }
+};
+
+//Define a list that will store MyClass using the public base hook
+typedef list<MyClass>            List;
+typedef slist<MyClass>           Slist;
+typedef set<MyClass>             Set;
+typedef unordered_set<MyClass>   USet;
+typedef avl_set<MyClass>         AvlSet;
+typedef splay_set<MyClass>       SplaySet;
+typedef sg_set<MyClass>          SgSet;
+
+int main()
+{
+   typedef std::vector<MyClass>::iterator VectIt;
+   typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+   //Create several MyClass objects, each one with a different value
+   std::vector<MyClass> values;
+   for(int i = 0; i < 100; ++i)  values.push_back(MyClass(i));
+
+   USet::bucket_type buckets[100];
+
+   List  my_list;
+   Slist my_slist;
+   Set   my_set;
+   USet  my_uset(USet::bucket_traits(buckets, 100));
+   AvlSet   my_avlset;
+   SplaySet my_splayset;
+   SgSet    my_sgset;
+
+   //Now insert them in the reverse order
+   //in the base hook intrusive list
+   for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
+      my_list.push_front(*it);
+      my_slist.push_front(*it);
+      my_set.insert(*it);
+      my_uset.insert(*it);
+      my_avlset.insert(*it);
+      my_splayset.insert(*it);
+      my_sgset.insert(*it);
+   }
+
+   //Now test lists
+   {
+      List::const_iterator  list_it(my_list.cbegin());
+      Slist::const_iterator slist_it(my_slist.cbegin());
+      Set::const_reverse_iterator set_rit(my_set.crbegin());
+      AvlSet::const_reverse_iterator avl_set_rit(my_avlset.crbegin());
+ SplaySet::const_reverse_iterator splay_set_rit(my_splayset.crbegin());
+      SgSet::const_reverse_iterator sg_set_rit(my_sgset.crbegin());
+
+      VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+
+      //Test the objects inserted in the base hook list
+      for(; vect_it != vect_itend
+          ; ++vect_it, ++list_it
+          , ++slist_it, ++set_rit
+          , ++avl_set_rit, ++splay_set_rit
+          , ++sg_set_rit){
+         if(&*list_it  != &*vect_it)      return 1;
+         if(&*slist_it != &*vect_it)      return 1;
+         if(&*set_rit  != &*vect_it)      return 1;
+         if(&*avl_set_rit  != &*vect_it)  return 1;
+         if(&*splay_set_rit  != &*vect_it)return 1;
+         if(&*sg_set_rit  != &*vect_it)   return 1;
+         if(my_uset.find(*set_rit) == my_uset.cend())  return 1;
+      }
+   }
+
+   return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/external_value_traits_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,239 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/rbtree.hpp>
+#include <boost/intrusive/hashtable.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <functional>
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+{
+   public:
+   int int_;
+
+   MyClass(int i = 0)
+      :  int_(i)
+   {}
+   friend bool operator > (const MyClass &l, const MyClass &r)
+   {  return l.int_ > r.int_; }
+   friend bool operator == (const MyClass &l, const MyClass &r)
+   {  return l.int_ == r.int_; }
+   friend std::size_t hash_value(const MyClass &v)
+   {  return boost::hash_value(v.int_); }
+};
+
+const int NumElements = 100;
+
+template<class NodeTraits>
+struct external_traits
+{
+   typedef NodeTraits                           node_traits;
+   typedef typename node_traits::node           node;
+   typedef typename node_traits::node_ptr       node_ptr;
+   typedef typename node_traits::const_node_ptr const_node_ptr;
+   typedef MyClass                              value_type;
+   typedef typename boost::pointer_to_other
+      <node_ptr, MyClass>::type                 pointer;
+   typedef typename boost::pointer_to_other
+      <node_ptr, const MyClass>::type           const_pointer;
+   static const link_mode_type link_mode =      normal_link;
+
+   external_traits(pointer values, std::size_t NumElem)
+      :  values_(values),  node_array_(NumElem)
+   {}
+
+   node_ptr to_node_ptr (value_type &value)
+   {  return (&node_array_[0]) + (&value - values_); }
+
+   const_node_ptr to_node_ptr (const value_type &value) const
+   {  return &node_array_[0] + (&value - values_); }
+
+   pointer to_value_ptr(node_ptr n)
+   {  return values_ + (n - &node_array_[0]); }
+
+   const_pointer to_value_ptr(const_node_ptr n) const
+   {  return values_ + (n - &node_array_[0]); }
+
+   pointer  values_;
+   std::vector<node> node_array_;
+};
+
+template<class NodeTraits>
+struct value_traits_proxy;
+
+template<class T>
+struct traits_holder
+   :  public T
+{};
+
+typedef value_traits_proxy<list_node_traits<void*> > list_value_traits_proxy; +typedef value_traits_proxy<slist_node_traits<void*> > slist_value_traits_proxy; +typedef value_traits_proxy<rbtree_node_traits<void*> > rbtree_value_traits_proxy; +typedef value_traits_proxy<traits_holder<slist_node_traits<void*> > > hash_value_traits_proxy;
+
+struct uset_bucket_traits
+{
+   private:
+   typedef unordered_bucket<value_traits<external_traits
+ <traits_holder<slist_node_traits<void*> > > > >::type bucket_type;
+
+   //Non-copyable
+   uset_bucket_traits(const uset_bucket_traits &other);
+   uset_bucket_traits & operator=(const uset_bucket_traits &other);
+
+   public:
+   static const std::size_t NumBuckets = 100;
+
+   uset_bucket_traits(){}
+
+   bucket_type * bucket_begin() const
+   {  return buckets_;  }
+
+   std::size_t bucket_count() const
+   {  return NumBuckets;  }
+
+   mutable bucket_type buckets_[NumBuckets];
+};
+
+struct bucket_traits_proxy
+{
+   static const bool external_bucket_traits =   true;
+   typedef uset_bucket_traits                   bucket_traits;
+
+   template<class Container>
+   bucket_traits &get_bucket_traits(Container &cont);
+
+   template<class Container>
+   const bucket_traits &get_bucket_traits(const Container &cont) const;
+};
+
+//Define a list that will store MyClass using the external hook
+typedef list<MyClass, value_traits<list_value_traits_proxy> >        List;
+//Define a slist that will store MyClass using the external hook
+typedef slist<MyClass, value_traits<slist_value_traits_proxy> >      Slist;
+//Define a rbtree that will store MyClass using the external hook
+typedef rbtree< MyClass
+              , value_traits<rbtree_value_traits_proxy>
+              , compare<std::greater<MyClass> > > Rbtree;
+//Define a hashtable that will store MyClass using the external hook
+typedef hashtable< MyClass
+                 , value_traits<hash_value_traits_proxy>
+                 , bucket_traits<bucket_traits_proxy>
+                 > Hash;
+
+template<class NodeTraits>
+struct value_traits_proxy
+{
+   static const bool external_value_traits = true;
+   typedef external_traits<NodeTraits> value_traits;
+
+   template<class Container>
+   const value_traits &get_value_traits(const Container &cont) const;
+
+   template<class Container>
+   value_traits &get_value_traits(Container &cont);
+};
+
+struct ContainerHolder
+   : public uset_bucket_traits
+   , public List
+   , public external_traits<list_node_traits<void*> >
+   , public Slist
+   , public external_traits<slist_node_traits<void*> >
+   , public Rbtree
+   , public external_traits<rbtree_node_traits<void*> >
+   , public Hash
+   , public external_traits<traits_holder<slist_node_traits<void*> > >
+{
+   static const std::size_t NumBucket = 100;
+   ContainerHolder(MyClass *values, std::size_t num_elem)
+      : uset_bucket_traits()
+      , List()
+      , external_traits<list_node_traits<void*> >(values, num_elem)
+      , Slist()
+      , external_traits<slist_node_traits<void*> >(values, num_elem)
+      , Rbtree()
+      , external_traits<rbtree_node_traits<void*> >(values, num_elem)
+      , Hash(Hash::bucket_traits())
+ , external_traits<traits_holder<slist_node_traits<void*> > >(values, num_elem)
+   {}
+};
+
+template<class NodeTraits>
+template<class Container>
+typename value_traits_proxy<NodeTraits>::value_traits &
+   value_traits_proxy<NodeTraits>::get_value_traits(Container &cont)
+{ return static_cast<value_traits&>(static_cast<ContainerHolder&>(cont)); }
+
+template<class NodeTraits>
+template<class Container>
+const typename value_traits_proxy<NodeTraits>::value_traits &
+ value_traits_proxy<NodeTraits>::get_value_traits(const Container &cont) const +{ return static_cast<const value_traits&>(static_cast<const ContainerHolder&>(cont)); }
+
+template<class Container>
+typename bucket_traits_proxy::bucket_traits &
+   bucket_traits_proxy::get_bucket_traits(Container &cont)
+{ return static_cast<bucket_traits&>(static_cast<ContainerHolder&>(cont)); }
+
+template<class Container>
+const typename bucket_traits_proxy::bucket_traits &
+   bucket_traits_proxy::get_bucket_traits(const Container &cont) const
+{ return static_cast<const bucket_traits&>(static_cast<const ContainerHolder&>(cont)); }
+
+int main()
+{
+   MyClass  values    [NumElements];
+   //Create several MyClass objects, each one with a different value
+   for(int i = 0; i < NumElements; ++i)
+      values[i].int_ = i;
+
+   ContainerHolder cont_holder(values, NumElements);
+   List &my_list     = static_cast<List &>   (cont_holder);
+   Slist &my_slist   = static_cast<Slist &>  (cont_holder);
+   Rbtree &my_rbtree = static_cast<Rbtree &> (cont_holder);
+   Hash     &my_hash = static_cast<Hash &>   (cont_holder);
+
+   //Now insert them in containers
+   for(MyClass * it(&values[0]), *itend(&values[NumElements])
+      ; it != itend; ++it){
+      my_list.push_front(*it);
+      my_slist.push_front(*it);
+      my_rbtree.insert_unique(*it);
+      my_hash.insert_unique(*it);
+   }
+
+   //Now test containers
+   {
+      List::const_iterator   list_it   (my_list.cbegin());
+      Slist::const_iterator  slist_it  (my_slist.cbegin());
+      Rbtree::const_iterator rbtree_it (my_rbtree.cbegin());
+      Hash::const_iterator   hash_it   (my_hash.cbegin());
+ MyClass *it_val(&values[NumElements] - 1), *it_rbeg_val(&values[0]-1);
+
+      //Test inserted objects
+ for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++rbtree_it){
+         if(&*list_it   != &*it_val)   return 1;
+         if(&*slist_it  != &*it_val)   return 1;
+         if(&*rbtree_it != &*it_val)   return 1;
+         hash_it = my_hash.find(*it_val);
+         if(hash_it == my_hash.cend() || &*hash_it != &*it_val)
+            return 1;
+      }
+   }
+
+   return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/generic_assoc_test.hpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,449 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <vector> //vector
+#include <algorithm> //sort, random_shuffle
+#include <boost/intrusive/detail/config_begin.hpp>
+#include "common_functors.hpp"
+#include <boost/intrusive/options.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+template<class T>
+struct has_splay
+{
+   static const bool value = false;
+};
+
+template<class T>
+struct has_rebalance
+{
+   static const bool value = false;
+};
+
+template<class T>
+struct has_insert_before
+{
+   static const bool value = false;
+};
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+struct test_generic_assoc
+{
+   typedef typename ValueTraits::value_type value_type;
+   static void test_all(std::vector<value_type>& values);
+   static void test_clone(std::vector<value_type>& values);
+   static void test_insert_erase_burst();
+   static void test_container_from_end(std::vector<value_type>& values);
+   static void test_splay_up(std::vector<value_type>& values);
+ static void test_splay_up(std::vector<value_type>& values, boost::intrusive::detail::true_type); + static void test_splay_up(std::vector<value_type>& values, boost::intrusive::detail::false_type);
+   static void test_splay_down(std::vector<value_type>& values);
+ static void test_splay_down(std::vector<value_type>& values, boost::intrusive::detail::true_type); + static void test_splay_down(std::vector<value_type>& values, boost::intrusive::detail::false_type);
+   static void test_rebalance(std::vector<value_type>& values);
+ static void test_rebalance(std::vector<value_type>& values, boost::intrusive::detail::true_type); + static void test_rebalance(std::vector<value_type>& values, boost::intrusive::detail::false_type);
+   static void test_insert_before(std::vector<value_type>& values);
+ static void test_insert_before(std::vector<value_type>& values, boost::intrusive::detail::true_type); + static void test_insert_before(std::vector<value_type>& values, boost::intrusive::detail::false_type); + static void test_container_from_iterator(std::vector<value_type>& values);
+};
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::
+   test_container_from_iterator(std::vector<value_type>& values)
+{
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+
+   assoc_type testset(values.begin(), values.end());
+   typedef typename assoc_type::iterator        it_type;
+   typedef typename assoc_type::const_iterator  cit_type;
+   typedef typename assoc_type::size_type       sz_type;
+   sz_type sz = testset.size();
+   for(it_type b(testset.begin()), e(testset.end()); b != e; ++b)
+   {
+      assoc_type &s = assoc_type::container_from_iterator(b);
+ const assoc_type &cs = assoc_type::container_from_iterator(cit_type(b));
+      BOOST_TEST(&s == &cs);
+      BOOST_TEST(&s == &testset);
+      s.erase(b);
+      BOOST_TEST(testset.size() == (sz-1));
+      s.insert(*b);
+      BOOST_TEST(testset.size() == sz);
+   }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_erase_burst()
+{
+   typedef typename ValueTraits::value_type value_type;
+
+   std::vector<value_type> values;
+   const int MaxValues = 100;
+   for(int i = 0; i != MaxValues; ++i){
+      values.push_back(value_type(i));
+   }
+
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef typename assoc_type::iterator iterator;
+
+   //First ordered insertions
+   assoc_type testset (&values[0], &values[0] + values.size());
+   TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin());
+
+   //Ordered erasure
+   iterator it(testset.begin()), itend(testset.end());
+   for(int i = 0; it != itend; ++i){
+      BOOST_TEST(&*it == &values[i]);
+      it = testset.erase(it);
+   }
+
+   BOOST_TEST(testset.empty());
+
+   //Now random insertions
+   std::random_shuffle(values.begin(), values.end());
+   testset.insert(&values[0], &values[0] + values.size());
+   std::vector<value_type> values_ordered(values);
+   std::sort(values_ordered.begin(), values_ordered.end());
+   TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin());
+
+   {
+ typedef typename std::vector<value_type>::const_iterator cvec_iterator;
+      //Random erasure
+      std::vector<cvec_iterator> it_vector;
+
+      for(cvec_iterator it(values.begin()), itend(values.end())
+         ; it != itend
+         ; ++it){
+         it_vector.push_back(it);
+      }
+      std::random_shuffle(it_vector.begin(), it_vector.end());
+      for(int i = 0; i != MaxValues; ++i){
+         testset.erase(testset.iterator_to(*it_vector[i]));
+      }
+
+      BOOST_TEST(testset.empty());
+   }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_assoc<ValueTraits, ContainerDefiner>::test_all(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   test_clone(values);
+   test_container_from_end(values);
+   test_splay_up(values);
+   test_splay_down(values);
+   test_rebalance(values);
+   test_insert_before(values);
+   test_insert_erase_burst();
+   test_container_from_iterator(values);
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>
+   ::test_clone(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+
+   assoc_type testset1 (&values[0], &values[0] + values.size());
+   assoc_type testset2;
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+   BOOST_TEST (testset2 == testset1);
+   testset2.clear_and_dispose(test::delete_disposer<value_type>());
+   BOOST_TEST (testset2.empty());
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   assoc_type testset (&values[0], &values[0] + values.size());
+ BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.end())); + BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.cend()));
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_splay_up
+(std::vector<typename ValueTraits::value_type>& values, boost::intrusive::detail::true_type)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef typename assoc_type::iterator iterator;
+   typedef std::vector<value_type> orig_set_t;
+   std::size_t num_values;
+   orig_set_t original_testset;
+   {
+      assoc_type testset (values.begin(), values.end());
+      num_values = testset.size();
+ original_testset.insert(original_testset.end(), testset.begin(), testset.end());
+   }
+
+   for(std::size_t i = 0; i != num_values; ++i){
+      assoc_type testset (values.begin(), values.end());
+      {
+         iterator it = testset.begin();
+         for(std::size_t j = 0; j != i; ++j, ++it){}
+         testset.splay_up(it);
+      }
+      BOOST_TEST (testset.size() == num_values);
+      iterator it = testset.begin();
+ for( typename orig_set_t::const_iterator origit = original_testset.begin()
+         , origitend = original_testset.end()
+         ; origit != origitend
+         ; ++origit, ++it){
+         BOOST_TEST(*origit == *it);
+      }
+   }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_splay_up
+(std::vector<typename ValueTraits::value_type>&, boost::intrusive::detail::false_type)
+{}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_splay_up
+(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef typename detail::remove_const<assoc_type>::type Type;
+   typedef detail::bool_<has_splay<Type>::value> enabler;
+   test_splay_up(values, enabler());
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_splay_down
+(std::vector<typename ValueTraits::value_type>& values, boost::intrusive::detail::true_type)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef typename assoc_type::iterator iterator;
+   typedef std::vector<value_type> orig_set_t;
+   std::size_t num_values;
+   orig_set_t original_testset;
+   {
+      assoc_type testset (values.begin(), values.end());
+      num_values = testset.size();
+ original_testset.insert(original_testset.end(), testset.begin(), testset.end());
+   }
+
+   for(std::size_t i = 0; i != num_values; ++i){
+      assoc_type testset (values.begin(), values.end());
+      BOOST_TEST(testset.size() == num_values);
+      {
+         iterator it = testset.begin();
+         for(std::size_t j = 0; j != i; ++j, ++it){}
+         BOOST_TEST(*it == *testset.splay_down(*it));
+      }
+      BOOST_TEST (testset.size() == num_values);
+      iterator it = testset.begin();
+ for( typename orig_set_t::const_iterator origit = original_testset.begin()
+         , origitend = original_testset.end()
+         ; origit != origitend
+         ; ++origit, ++it){
+         BOOST_TEST(*origit == *it);
+      }
+   }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_splay_down
+(std::vector<typename ValueTraits::value_type>&, boost::intrusive::detail::false_type)
+{}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_splay_down
+(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef typename detail::remove_const<assoc_type>::type Type;
+   typedef detail::bool_<has_splay<Type>::value> enabler;
+   test_splay_down(values, enabler());
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_rebalance
+(std::vector<typename ValueTraits::value_type>& values, boost::intrusive::detail::true_type)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef std::vector<value_type> orig_set_t;
+   typedef typename orig_set_t::iterator iterator_t;
+   std::size_t num_values;
+   orig_set_t original_testset;
+   {
+      assoc_type testset (values.begin(), values.end());
+      num_values = testset.size();
+ original_testset.insert(original_testset.end(), testset.begin(), testset.end());
+   }
+   {
+      assoc_type testset(values.begin(), values.end());
+      testset.rebalance();
+      iterator_t it = original_testset.begin();
+      TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin());
+   }
+
+   {
+      std::size_t numdata;
+      {
+         assoc_type testset(values.begin(), values.end());
+         numdata = testset.size();
+      }
+
+      for(int i = 0; i != (int)numdata; ++i){
+         assoc_type testset(values.begin(), values.end());
+         typename assoc_type::iterator it = testset.begin();
+         for(int j = 0; j  != i; ++j)  ++it;
+         testset.rebalance_subtree(it);
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin());
+      }
+   }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_rebalance
+(std::vector<typename ValueTraits::value_type>&, boost::intrusive::detail::false_type)
+{}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_rebalance
+(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef typename detail::remove_const<assoc_type>::type Type;
+   typedef detail::bool_<has_rebalance<Type>::value> enabler;
+   test_rebalance(values, enabler());
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_before
+(std::vector<typename ValueTraits::value_type>& values, boost::intrusive::detail::true_type)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   {
+      assoc_type testset;
+      typedef typename std::vector<value_type>::iterator vec_iterator;
+      for(vec_iterator it(values.begin()), itend(values.end())
+         ; it != itend
+         ; ++it){
+         testset.push_back(*it);
+      }
+      BOOST_TEST(testset.size() == values.size());
+      TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin());
+   }
+   {
+      assoc_type testset;
+      typedef typename std::vector<value_type>::iterator vec_iterator;
+
+      for(vec_iterator it(--values.end()); true; --it){
+         testset.push_front(*it);
+         if(it == values.begin()){
+            break;
+         }
+      }
+      BOOST_TEST(testset.size() == values.size());
+      TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin());
+   }
+   {
+      assoc_type testset;
+      typedef typename std::vector<value_type>::iterator vec_iterator;
+      typename assoc_type::iterator it_pos =
+         testset.insert_before(testset.end(), *values.rbegin());
+      testset.insert_before(testset.begin(), *values.begin());
+      for(vec_iterator it(++values.begin()), itend(--values.end())
+         ; it != itend
+         ; ++it){
+         testset.insert_before(it_pos, *it);
+      }
+      BOOST_TEST(testset.size() == values.size());
+      TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin());
+   }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_before
+(std::vector<typename ValueTraits::value_type>&, boost::intrusive::detail::false_type)
+{}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_before
+(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type assoc_type;
+   typedef typename detail::remove_const<assoc_type>::type Type;
+   typedef detail::bool_<has_insert_before<Type>::value> enabler;
+   test_insert_before(values, enabler());
+}
+
+}}}   //namespace boost::intrusive::test
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/generic_multiset_test.hpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,227 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <vector>
+#include <boost/intrusive/detail/config_begin.hpp>
+#include "common_functors.hpp"
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/intrusive/options.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include "generic_assoc_test.hpp"
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+struct test_generic_multiset
+{
+   typedef typename ValueTraits::value_type value_type;
+   static void test_all ();
+   static void test_sort(std::vector<value_type>& values);
+   static void test_insert(std::vector<value_type>& values);
+   static void test_swap(std::vector<value_type>& values);
+   static void test_find(std::vector<value_type>& values);
+   static void test_impl();
+};
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_multiset<ValueTraits, ContainerDefiner>::test_all ()
+{
+   typedef typename ValueTraits::value_type value_type;
+   static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+   std::vector<value_type> values (6);
+   for (int i = 0; i < 6; ++i)
+      values[i].value_ = random_init[i];
+
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type multiset_type;
+   {
+      multiset_type testset(values.begin(), values.end());
+      test::test_container(testset);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+ test::test_common_unordered_and_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_non_unique_container(testset, values);
+   }
+   test_sort(values);
+   test_insert(values);
+   test_swap(values);
+   test_find(values);
+   test_impl();
+   test_generic_assoc<ValueTraits, ContainerDefiner>::test_all(values);
+}
+
+//test case due to an error in tree implementation:
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_multiset<ValueTraits, ContainerDefiner>::test_impl()
+{
+   typedef typename ValueTraits::value_type value_type;
+   std::vector<value_type> values (5);
+   for (int i = 0; i < 5; ++i)
+      values[i].value_ = i;
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type multiset_type;
+
+   multiset_type testset;
+   for (int i = 0; i < 5; ++i)
+      testset.insert (values[i]);
+
+   testset.erase (testset.iterator_to (values[0]));
+   testset.erase (testset.iterator_to (values[1]));
+   testset.insert (values[1]);
+
+   testset.erase (testset.iterator_to (values[2]));
+   testset.erase (testset.iterator_to (values[3]));
+}
+
+//test: constructor, iterator, clear, reverse_iterator, front, back, size:
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_multiset<ValueTraits, ContainerDefiner>::test_sort(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type multiset_type;
+
+   multiset_type testset1 (values.begin(), values.end());
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   testset1.clear();
+   BOOST_TEST (testset1.empty());
+
+   typedef typename ContainerDefiner
+      <value_type
+      , compare<even_odd>
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type multiset_type2;
+   multiset_type2 testset2 (&values[0], &values[0] + 6);
+   {  int init_values [] = { 5, 3, 1, 4, 2, 2 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() );  }
+
+   BOOST_TEST (testset2.begin()->value_ == 2);
+   BOOST_TEST (testset2.rbegin()->value_ == 5);
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_multiset<ValueTraits, ContainerDefiner>::test_insert(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      >::type multiset_type;
+
+   multiset_type testset;
+   testset.insert(&values[0] + 2, &values[0] + 5);
+   {  int init_values [] = { 1, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() );  }
+
+   typename multiset_type::iterator i = testset.begin();
+   BOOST_TEST (i->value_ == 1);
+
+   i = testset.insert (i, values[0]);
+   BOOST_TEST (&*i == &values[0]);
+
+   {  int init_values [] = { 5, 4, 3, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() );  }
+
+   i = testset.iterator_to (values[2]);
+   BOOST_TEST (&*i == &values[2]);
+
+   i = multiset_type::s_iterator_to (values[2]);
+   BOOST_TEST (&*i == &values[2]);
+
+   testset.erase(i);
+
+   {  int init_values [] = { 1, 3, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() );  }
+}
+
+//test: insert (seq-version), swap, erase (seq-version), size:
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_multiset<ValueTraits, ContainerDefiner>::test_swap(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      >::type multiset_type;
+   multiset_type testset1 (&values[0], &values[0] + 2);
+   multiset_type testset2;
+   testset2.insert (&values[0] + 2, &values[0] + 6);
+   testset1.swap (testset2);
+
+   {  int init_values [] = { 1, 2, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   {  int init_values [] = { 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() );  }
+
+   testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+   BOOST_TEST (testset1.size() == 1);
+   BOOST_TEST (&*testset1.begin() == &values[3]);
+}
+
+//test: find, equal_range (lower_bound, upper_bound):
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_multiset<ValueTraits, ContainerDefiner>::test_find(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      >::type multiset_type;
+   multiset_type testset (values.begin(), values.end());
+   typedef typename multiset_type::iterator iterator;
+
+   value_type cmp_val;
+   cmp_val.value_ = 2;
+   iterator i = testset.find (cmp_val);
+   BOOST_TEST (i->value_ == 2);
+   BOOST_TEST ((++i)->value_ == 2);
+   std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
+
+   BOOST_TEST (range.first->value_ == 2);
+   BOOST_TEST (range.second->value_ == 3);
+   BOOST_TEST (std::distance (range.first, range.second) == 2);
+
+   cmp_val.value_ = 7;
+   BOOST_TEST (testset.find (cmp_val) == testset.end());
+}
+
+}}}   //namespace boost::intrusive::test
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/generic_set_test.hpp     Mon Aug 23 23:00:26 2010
@@ -0,0 +1,298 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <vector>
+#include <boost/intrusive/detail/config_begin.hpp>
+#include "common_functors.hpp"
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/intrusive/options.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include "generic_assoc_test.hpp"
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+template<class T>
+struct is_treap
+{
+   static const bool value = false;
+};
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+struct test_generic_set
+{
+   typedef typename ValueTraits::value_type value_type;
+   static void test_all();
+   static void test_sort(std::vector<value_type>& values);
+   static void test_insert(std::vector<value_type>& values);
+ static void test_insert_advanced(std::vector<value_type>& values, boost::intrusive::detail::true_type); + static void test_insert_advanced(std::vector<value_type>& values, boost::intrusive::detail::false_type);
+   static void test_insert_advanced(std::vector<value_type>& values);
+   static void test_swap(std::vector<value_type>& values);
+   static void test_find(std::vector<value_type>& values);
+   static void test_impl();
+};
+
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_set<ValueTraits, ContainerDefiner>::test_all()
+{
+   typedef typename ValueTraits::value_type value_type;
+   static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+   std::vector<value_type> values (6);
+   for (int i = 0; i < 6; ++i)
+      values[i].value_ = random_init[i];
+
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   {
+      set_type testset(values.begin(), values.end());
+      test::test_container(testset);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+ test::test_common_unordered_and_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_unique_container(testset, values);
+   }
+   test_sort(values);
+   test_insert(values);
+   test_insert_advanced(values);
+   test_swap(values);
+   test_find(values);
+   test_impl();
+   test_generic_assoc<ValueTraits, ContainerDefiner>::test_all(values);
+}
+
+//test case due to an error in tree implementation:
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_set<ValueTraits, ContainerDefiner>::test_impl()
+{
+   typedef typename ValueTraits::value_type value_type;
+   std::vector<value_type> values (5);
+   for (int i = 0; i < 5; ++i)
+      values[i].value_ = i;
+
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   set_type testset;
+   for (int i = 0; i < 5; ++i)
+      testset.insert (values[i]);
+
+   testset.erase (testset.iterator_to (values[0]));
+   testset.erase (testset.iterator_to (values[1]));
+   testset.insert (values[1]);
+
+   testset.erase (testset.iterator_to (values[2]));
+   testset.erase (testset.iterator_to (values[3]));
+}
+
+//test: constructor, iterator, clear, reverse_iterator, front, back, size:
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_set<ValueTraits, ContainerDefiner>::test_sort(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   set_type testset1 (values.begin(), values.end());
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   testset1.clear();
+   BOOST_TEST (testset1.empty());
+
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , compare<even_odd>
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type2;
+   set_type2 testset2 (&values[0], &values[0] + 6);
+   {  int init_values [] = { 5, 3, 1, 4, 2 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() );  }
+   BOOST_TEST (testset2.begin()->value_ == 2);
+   BOOST_TEST (testset2.rbegin()->value_ == 5);
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: +template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_set<ValueTraits, ContainerDefiner>::test_insert(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   {
+      set_type testset;
+      testset.insert(&values[0] + 2, &values[0] + 5);
+
+      const set_type& const_testset = testset;
+      {  int init_values [] = { 1, 4, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() );  }
+
+      typename set_type::iterator i = testset.begin();
+      BOOST_TEST (i->value_ == 1);
+
+      i = testset.insert (i, values[0]);
+      BOOST_TEST (&*i == &values[0]);
+
+      {  int init_values [] = { 5, 4, 3, 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() );  }
+
+      i = testset.iterator_to (values[2]);
+      BOOST_TEST (&*i == &values[2]);
+
+      i = set_type::s_iterator_to(values[2]);
+      BOOST_TEST (&*i == &values[2]);
+
+      testset.erase (i);
+      {  int init_values [] = { 1, 3, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() );  }
+   }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_set<ValueTraits, ContainerDefiner>::test_insert_advanced
+(std::vector<typename ValueTraits::value_type>& values, boost::intrusive::detail::true_type)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   {
+      set_type testset;
+      testset.insert(&values[0], &values[0] + values.size());
+      value_type v(1);
+      typename set_type::insert_commit_data data;
+ BOOST_TEST (!testset.insert_check(v, testset.value_comp(), testset.priority_comp(), data).second); + BOOST_TEST (!testset.insert_check(testset.begin(), v, testset.value_comp(), testset.priority_comp(), data).second);
+   }
+}
+
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_set<ValueTraits, ContainerDefiner>::test_insert_advanced
+(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   typedef typename detail::remove_const<set_type>::type Type;
+   typedef detail::bool_<is_treap<Type>::value> enabler;
+   test_insert_advanced(values, enabler());
+}
+
+
+//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: +template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_set<ValueTraits, ContainerDefiner>::test_insert_advanced
+   ( std::vector<typename ValueTraits::value_type>& values
+   , boost::intrusive::detail::false_type)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   {
+      set_type testset;
+      testset.insert(&values[0], &values[0] + values.size());
+      value_type v(1);
+      typename set_type::insert_commit_data data;
+ BOOST_TEST (!testset.insert_check(v, testset.value_comp(), data).second); + BOOST_TEST (!testset.insert_check(testset.begin(), v, testset.value_comp(), data).second);
+   }
+}
+
+
+//test: insert (seq-version), swap, erase (seq-version), size:
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_set<ValueTraits, ContainerDefiner>::test_swap(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   set_type testset1 (&values[0], &values[0] + 2);
+   set_type testset2;
+   testset2.insert (&values[0] + 2, &values[0] + 6);
+   testset1.swap (testset2);
+
+   {  int init_values [] = { 1, 2, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   {  int init_values [] = { 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() );  }
+
+   testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+   BOOST_TEST (testset1.size() == 1);
+   //  BOOST_TEST (&testset1.front() == &values[3]);
+   BOOST_TEST (&*testset1.begin() == &values[3]);
+}
+
+//test: find, equal_range (lower_bound, upper_bound):
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner> +void test_generic_set<ValueTraits, ContainerDefiner>::test_find(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef typename ContainerDefiner
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      >::type set_type;
+   set_type testset (values.begin(), values.end());
+   typedef typename set_type::iterator iterator;
+
+   value_type cmp_val;
+   cmp_val.value_ = 2;
+   iterator i = testset.find (cmp_val);
+   BOOST_TEST (i->value_ == 2);
+   BOOST_TEST ((++i)->value_ != 2);
+   std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
+
+   BOOST_TEST (range.first->value_ == 2);
+   BOOST_TEST (range.second->value_ == 3);
+   BOOST_TEST (std::distance (range.first, range.second) == 1);
+
+   cmp_val.value_ = 7;
+   BOOST_TEST (testset.find (cmp_val) == testset.end());
+}
+
+}}}   //namespace boost::intrusive::test
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/itestvalue.hpp   Mon Aug 23 23:00:26 2010
@@ -0,0 +1,183 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP
+#define BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP
+
+#include <iostream>
+#include <boost/intrusive/options.hpp>
+#include <boost/functional/hash.hpp>
+
+namespace boost{
+namespace intrusive{
+
+struct testvalue_filler
+{
+   void *dummy_[3];
+};
+
+template<class Hooks, bool ConstantTimeSize>
+struct testvalue
+   :  testvalue_filler
+   ,  Hooks::base_hook_type
+   ,  Hooks::auto_base_hook_type
+{
+   typename Hooks::member_hook_type        node_;
+   typename Hooks::auto_member_hook_type   auto_node_;
+   int value_;
+
+   static const bool constant_time_size = ConstantTimeSize;
+
+   testvalue()
+   {}
+
+   testvalue(int i)
+      :  value_(i)
+   {}
+
+   testvalue (const testvalue& src)
+      :  value_ (src.value_)
+   {}
+
+   // testvalue is used in std::vector and thus prev and next
+   // have to be handled appropriately when copied:
+   testvalue & operator= (const testvalue& src)
+   {
+      Hooks::base_hook_type::operator=(src);
+      Hooks::auto_base_hook_type::operator=(src);
+      this->node_       = src.node_;
+      this->auto_node_  = src.auto_node_;
+      value_ = src.value_;
+      return *this;
+   }
+
+   void swap_nodes(testvalue &other)
+   {
+      Hooks::base_hook_type::swap_nodes(other);
+      Hooks::auto_base_hook_type::swap_nodes(other);
+      node_.swap_nodes(other.node_);
+      auto_node_.swap_nodes(other.auto_node_);
+   }
+
+   bool is_linked() const
+   {
+      return Hooks::base_hook_type::is_linked() ||
+      Hooks::auto_base_hook_type::is_linked() ||
+      node_.is_linked() ||
+      auto_node_.is_linked();
+   }
+
+   ~testvalue()
+   {}
+
+   bool operator< (const testvalue &other) const
+   {  return value_ < other.value_;  }
+
+   bool operator==(const testvalue &other) const
+   {  return value_ == other.value_;  }
+
+   bool operator!=(const testvalue &other) const
+   {  return value_ != other.value_;  }
+
+   friend bool operator< (int other1, const testvalue &other2)
+   {  return other1 < other2.value_;  }
+
+   friend bool operator< (const testvalue &other1, int other2)
+   {  return other1.value_ < other2;  }
+
+   friend bool operator== (int other1, const testvalue &other2)
+   {  return other1 == other2.value_;  }
+
+   friend bool operator== (const testvalue &other1, int other2)
+   {  return other1.value_ == other2;  }
+
+   friend bool operator!= (int other1, const testvalue &other2)
+   {  return other1 != other2.value_;  }
+
+   friend bool operator!= (const testvalue &other1, int other2)
+   {  return other1.value_ != other2;  }
+};
+
+template<class Hooks, bool ConstantTimeSize>
+std::size_t hash_value(const testvalue<Hooks, ConstantTimeSize> &t)
+{
+   boost::hash<int> hasher;
+   return hasher(t.value_);
+}
+
+template<class Hooks, bool ConstantTimeSize>
+bool priority_order( const testvalue<Hooks, ConstantTimeSize> &t1
+                   , const testvalue<Hooks, ConstantTimeSize> &t2)
+{
+   std::size_t hash1 = hash_value(t1);
+   boost::hash_combine(hash1, &t1);
+   std::size_t hash2 = hash_value(t2);
+   boost::hash_combine(hash2, &t2);
+   return hash1 < hash2;
+}
+
+template<class Hooks, bool constant_time_size>
+std::ostream& operator<<
+   (std::ostream& s, const testvalue<Hooks, constant_time_size>& t)
+{  return s << t.value_;   }
+
+struct even_odd
+{
+   template<class Hooks, bool constant_time_size>
+   bool operator()
+      (const testvalue<Hooks, constant_time_size>& v1
+      ,const testvalue<Hooks, constant_time_size>& v2) const
+   {
+      if ((v1.value_ & 1) == (v2.value_ & 1))
+         return v1.value_ < v2.value_;
+      else
+         return v2.value_ & 1;
+   }
+};
+
+struct is_even
+{
+   template<class Hooks, bool constant_time_size>
+   bool operator()
+      (const testvalue<Hooks, constant_time_size>& v1) const
+   {  return (v1.value_ & 1) == 0;  }
+};
+/*
+struct int_testvalue_comp
+{
+   template<class Hooks, bool constant_time_size>
+   bool operator()
+      (const testvalue<Hooks, constant_time_size>& v1, const int &i) const
+   {  return v1.value_ < i; }
+   template<class Hooks, bool constant_time_size>
+   bool operator()
+      (const int &i, const testvalue<Hooks, constant_time_size>& v1) const
+   {  return i < v1.value_; }
+};
+
+struct int_testvalue_pcomp
+{
+   template<class Hooks, bool constant_time_size>
+   bool operator()
+      (const testvalue<Hooks, constant_time_size>& v1, const int &i) const
+   {  return v1.value_ < i; }
+   template<class Hooks, bool constant_time_size>
+   bool operator()
+      (const int &i, const testvalue<Hooks, constant_time_size>& v1) const
+   {  return i < v1.value_; }
+};
+*/
+
+}  //namespace boost{
+}  //namespace intrusive{
+
+#endif
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/list_test.cpp    Mon Aug 23 23:00:26 2010
@@ -0,0 +1,503 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/list.hpp>
+
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+
+using namespace boost::intrusive;
+
+class my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef list_base_hook<void_pointer<VoidPointer> > base_hook_type;
+   typedef list_base_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer>, tag<my_tag> > auto_base_hook_type; + typedef list_member_hook<void_pointer<VoidPointer>, tag<my_tag> > member_hook_type;
+   typedef list_member_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template<class ValueTraits>
+struct test_list
+{
+   typedef typename ValueTraits::value_type value_type;
+   static void test_all(std::vector<value_type>& values);
+   static void test_front_back(std::vector<value_type>& values);
+   static void test_sort(std::vector<value_type>& values);
+   static void test_merge(std::vector<value_type>& values);
+   static void test_remove_unique(std::vector<value_type>& values);
+   static void test_insert(std::vector<value_type>& values);
+   static void test_shift(std::vector<value_type>& values);
+   static void test_swap(std::vector<value_type>& values);
+   static void test_clone(std::vector<value_type>& values);
+   static void test_container_from_end(std::vector<value_type>& values);
+};
+
+template<class ValueTraits>
+void test_list<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   {
+      list_type list(values.begin(), values.end());
+      test::test_container(list);
+      list.clear();
+      list.insert(list.end(), values.begin(), values.end());
+      test::test_sequence_container(list, values);
+   }
+
+   test_front_back(values);
+   test_sort(values);
+   test_merge(values);
+   test_remove_unique(values);
+   test_insert(values);
+   test_shift(values);
+   test_swap(values);
+   test_clone(values);
+   test_container_from_end(values);
+}
+
+//test: push_front, pop_front, push_back, pop_back, front, back, size, empty:
+template<class ValueTraits>
+void test_list<ValueTraits>
+   ::test_front_back(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   list_type testlist;
+   BOOST_TEST (testlist.empty());
+
+   testlist.push_back (values[0]);
+   BOOST_TEST (testlist.size() == 1);
+   BOOST_TEST (&testlist.front() == &values[0]);
+   BOOST_TEST (&testlist.back() == &values[0]);
+
+   testlist.push_front (values[1]);
+   BOOST_TEST (testlist.size() == 2);
+   BOOST_TEST (&testlist.front() == &values[1]);
+   BOOST_TEST (&testlist.back() == &values[0]);
+
+   testlist.pop_back();
+   BOOST_TEST (testlist.size() == 1);
+   const list_type &const_testlist = testlist;
+   BOOST_TEST (&const_testlist.front() == &values[1]);
+   BOOST_TEST (&const_testlist.back() == &values[1]);
+
+   testlist.pop_front();
+   BOOST_TEST (testlist.empty());
+}
+
+
+//test: constructor, iterator, reverse_iterator, sort, reverse:
+template<class ValueTraits>
+void test_list<ValueTraits>
+   ::test_sort(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   list_type testlist(values.begin(), values.end());
+
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
+
+   testlist.sort (even_odd());
+   {  int init_values [] = { 5, 3, 1, 4, 2 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testlist.rbegin() );  }
+
+   testlist.reverse();
+   {  int init_values [] = { 5, 3, 1, 4, 2 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
+}
+
+//test: merge due to error in merge implementation:
+template<class ValueTraits>
+void test_list<ValueTraits>
+ ::test_remove_unique (std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   {
+      list_type list(values.begin(), values.end());
+      list.remove_if(is_even());
+      int init_values [] = { 1, 3, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+   }
+   {
+      std::vector<typename ValueTraits::value_type> values2(values);
+      list_type list(values.begin(), values.end());
+      list.insert(list.end(), values2.begin(), values2.end());
+      list.sort();
+      int init_values [] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+      list.unique();
+      int init_values2 [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values2, list.begin() );
+   }
+}
+
+//test: merge due to error in merge implementation:
+template<class ValueTraits>
+void test_list<ValueTraits>
+   ::test_merge (std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   list_type testlist1, testlist2;
+   testlist1.push_front (values[0]);
+   testlist2.push_front (values[4]);
+   testlist2.push_front (values[3]);
+   testlist2.push_front (values[2]);
+   testlist1.merge (testlist2);
+
+   int init_values [] = { 1, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
+}
+
+//test: assign, insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
+template<class ValueTraits>
+void test_list<ValueTraits>
+   ::test_insert(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   list_type testlist;
+   testlist.assign (&values[0] + 2, &values[0] + 5);
+
+   const list_type& const_testlist = testlist;
+   {  int init_values [] = { 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+
+   typename list_type::iterator i = ++testlist.begin();
+   BOOST_TEST (i->value_ == 4);
+
+   {
+   typename list_type::const_iterator ci = typename list_type::iterator();
+   //typename list_type::iterator i = typename list_type::const_iterator();
+   }
+
+   testlist.insert (i, values[0]);
+   {  int init_values [] = { 5, 4, 1, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.rbegin() );  }
+
+   i = testlist.iterator_to (values[4]);
+   BOOST_TEST (&*i == &values[4]);
+
+   i = list_type::s_iterator_to (values[4]);
+   BOOST_TEST (&*i == &values[4]);
+
+   i = testlist.erase (i);
+   BOOST_TEST (i == testlist.end());
+
+   {  int init_values [] = { 3, 1, 4 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+}
+
+
+template<class ValueTraits>
+void test_list<ValueTraits>
+   ::test_shift(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   list_type testlist;
+   const int num_values = (int)values.size();
+   std::vector<int> expected_values(num_values);
+
+   for(int s = 1; s <= num_values; ++s){
+      expected_values.resize(s);
+      //Shift forward all possible positions 3 times
+      for(int i = 0; i < s*3; ++i){
+         testlist.insert(testlist.begin(), &values[0], &values[0] + s);
+         testlist.shift_forward(i);
+         for(int j = 0; j < s; ++j){
+            expected_values[(j + s - i%s) % s] = (j + 1);
+         }
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
+         testlist.clear();
+      }
+
+      //Shift backwards all possible positions
+      for(int i = 0; i < s*3; ++i){
+         testlist.insert(testlist.begin(), &values[0], &values[0] + s);
+         testlist.shift_backwards(i);
+         for(int j = 0; j < s; ++j){
+            expected_values[(j + i) % s] = (j + 1);
+         }
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
+         testlist.clear();
+      }
+   }
+}
+
+//test: insert (seq-version), swap, splice, erase (seq-version):
+template<class ValueTraits>
+void test_list<ValueTraits>
+   ::test_swap(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   {
+      list_type testlist1 (&values[0], &values[0] + 2);
+      list_type testlist2;
+      testlist2.insert (testlist2.end(), &values[0] + 2, &values[0] + 5);
+      testlist1.swap (testlist2);
+
+      {  int init_values [] = { 3, 4, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+      {  int init_values [] = { 1, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+
+      testlist2.splice (++testlist2.begin(), testlist1);
+      {  int init_values [] = { 1, 3, 4, 5, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+
+      BOOST_TEST (testlist1.empty());
+
+ testlist1.splice (testlist1.end(), testlist2, ++(++testlist2.begin()));
+      {  int init_values [] = { 4 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      {  int init_values [] = { 1, 3, 5, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+
+      testlist1.splice (testlist1.end(), testlist2,
+                        testlist2.begin(), ----testlist2.end());
+      {  int init_values [] = { 4, 1, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+      {  int init_values [] = { 5, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+
+      testlist1.erase (testlist1.iterator_to(values[0]), testlist1.end());
+      BOOST_TEST (testlist1.size() == 1);
+      BOOST_TEST (&testlist1.front() == &values[3]);
+   }
+   {
+      list_type testlist1 (&values[0], &values[0] + 2);
+      list_type testlist2 (&values[0] + 3, &values[0] + 5);
+
+      values[0].swap_nodes(values[2]);
+      {  int init_values [] = { 3, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[2].swap_nodes(values[4]);
+      {  int init_values [] = { 5, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+      {  int init_values [] = { 4, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+   }
+   {
+      list_type testlist1 (&values[0], &values[1]);
+
+      {  int init_values [] = { 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[1].swap_nodes(values[2]);
+
+      {  int init_values [] = { 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[0].swap_nodes(values[2]);
+
+      {  int init_values [] = { 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[0].swap_nodes(values[2]);
+
+      {  int init_values [] = { 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+   }
+
+}
+
+template<class ValueTraits>
+void test_list<ValueTraits>
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+   list_type testlist1 (&values[0], &values[0] + values.size());
+ BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end())); + BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend()));
+}
+
+
+template<class ValueTraits>
+void test_list<ValueTraits>
+   ::test_clone(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef list
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      > list_type;
+      list_type testlist1 (&values[0], &values[0] + values.size());
+      list_type testlist2;
+
+ testlist2.clone_from(testlist1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+      BOOST_TEST (testlist2 == testlist1);
+      testlist2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testlist2.empty());
+}
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      typedef testvalue<hooks<VoidPointer>, constant_time_size> value_type;
+      std::vector<value_type> data (5);
+      for (int i = 0; i < 5; ++i)
+         data[i].value_ = i + 1;
+
+      test_list < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                >::test_all(data);
+      test_list < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                >::test_all(data);
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      typedef testvalue<hooks<VoidPointer>, false> value_type;
+      std::vector<value_type> data (5);
+      for (int i = 0; i < 5; ++i)
+         data[i].value_ = i + 1;
+
+      test_list < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                >::test_all(data);
+
+      test_list < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                >::test_all(data);
+
+//      test_list<stateful_value_traits
+//                  < value_type
+//                  , list_node_traits<VoidPointer>
+//                  , safe_link>
+//               >::test_all(data);
+      test_list < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                >::test_all(data);
+
+      test_list < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                >::test_all(data);
+
+//      test_list<stateful_value_traits
+//                  < value_type
+//                  , list_node_traits<VoidPointer>
+//                  , auto_unlink>
+//               >::test_all(data);
+
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<smart_ptr<void>, true>()();
+
+   return boost::report_errors();
+}
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/make_functions_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,231 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "smart_ptr.hpp"
+#include <vector>
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+typedef make_bs_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link>
+   , tag<my_tag> >::type TreapHook;
+
+class MyClass
+:  public make_list_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+,  public make_slist_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+,  public make_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+,  public make_unordered_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+,  public make_avl_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+,  public make_splay_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+,  public make_bs_set_base_hook
+   < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+,  public TreapHook
+{
+   int int_;
+
+   public:
+   MyClass(int i)
+      :  int_(i)
+   {}
+
+   friend bool operator<(const MyClass &l, const MyClass &r)
+   {  return l.int_ < r.int_; }
+
+   friend bool operator==(const MyClass &l, const MyClass &r)
+   {  return l.int_ == r.int_; }
+
+   friend std::size_t hash_value(const MyClass &v)
+   {  return boost::hash_value(v.int_); }
+
+   friend bool priority_order(const MyClass &l, const MyClass &r)
+   {  return l.int_ < r.int_; }
+};
+
+//Define a list that will store MyClass using the public base hook
+typedef make_list<MyClass>::type          List;
+typedef make_slist<MyClass>::type         Slist;
+typedef make_set<MyClass>::type           Set;
+typedef make_unordered_set<MyClass>::type USet;
+
+typedef make_avl_set<MyClass>::type       AvlSet;
+typedef make_splay_set<MyClass>::type     SplaySet;
+typedef make_sg_set<MyClass>::type        SgSet;
+typedef make_treap_set<MyClass
+   , base_hook<TreapHook> >::type         TreapSet;
+
+int main()
+{
+   typedef std::vector<MyClass>::iterator VectIt;
+   typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+   //Create several MyClass objects, each one with a different value
+   std::vector<MyClass> values;
+   for(int i = 0; i < 100; ++i)  values.push_back(MyClass(i));
+
+   USet::bucket_type buckets[100];
+
+   List  my_list;
+   Slist my_slist;
+   Set   my_set;
+   USet  my_uset(USet::bucket_traits(buckets, 100));
+
+   AvlSet      my_avlset;
+   SplaySet    my_splayset;
+   SgSet       my_sgset;
+   TreapSet    my_treapset;
+
+   //Now insert them in containers
+   for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
+      my_list.push_front(*it);
+      my_slist.push_front(*it);
+      my_set.insert(*it);
+      my_uset.insert(*it);
+      my_avlset.insert(*it);
+      my_splayset.insert(*it);
+      my_sgset.insert(*it);
+      my_treapset.insert(*it);
+   }
+
+   //Now test lists
+   {
+      List::const_iterator  list_it(my_list.cbegin());
+      Slist::const_iterator slist_it(my_slist.cbegin());
+      Set::const_reverse_iterator set_rit(my_set.crbegin());
+
+      AvlSet::const_reverse_iterator avlset_rit(my_avlset.crbegin());
+      SplaySet::const_reverse_iterator splayset_rit(my_splayset.crbegin());
+      SgSet::const_reverse_iterator sgset_rit(my_sgset.crbegin());
+      TreapSet::const_reverse_iterator treapset_rit(my_treapset.crbegin());
+
+      VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+
+      //Test the objects inserted in the base hook list
+      for( ; vect_it != vect_itend
+         ; ++vect_it, ++list_it, ++slist_it, ++set_rit
+         , ++avlset_rit, ++splayset_rit, ++sgset_rit, ++treapset_rit
+         ){
+         if(&*list_it  != &*vect_it)   return 1;
+         if(&*slist_it != &*vect_it)   return 1;
+         if(&*set_rit  != &*vect_it)   return 1;
+         if(my_uset.find(*set_rit) == my_uset.cend())  return 1;
+         if(&*avlset_rit   != &*vect_it)  return 1;
+         if(&*splayset_rit != &*vect_it)  return 1;
+         if(&*sgset_rit    != &*vect_it)  return 1;
+         if(&*treapset_rit != &*vect_it)  return 1;
+      }
+   }
+
+   //Check defined types and implicitly defined types are equal
+ if(detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+                     ,make_list_base_hook<>::type
+                     >::value == false){
+      return 1;
+   }
+
+ if(detail::is_same<make_slist_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+                     ,make_slist_base_hook<>::type
+                     >::value == false){
+      return 1;
+   }
+
+ if(detail::is_same<make_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+                     ,make_set_base_hook<>::type
+                     >::value == false){
+      return 1;
+   }
+
+ if(detail::is_same<make_unordered_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+                     ,make_unordered_set_base_hook<>::type
+                     >::value == false){
+      return 1;
+   }
+
+ if(detail::is_same<make_avl_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+                     ,make_avl_set_base_hook<>::type
+                     >::value == false){
+      return 1;
+   }
+
+ if(detail::is_same<make_bs_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+                     ,make_bs_set_base_hook<>::type
+                     >::value == false){
+      return 1;
+   }
+
+ if(detail::is_same<make_splay_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+                     ,make_splay_set_base_hook<>::type
+                     >::value == false){
+      return 1;
+   }
+
+   //Check defined types and implicitly defined types are unequal
+ if(detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+                     ,make_list_base_hook<>::type
+                     >::value == true){
+      return 1;
+   }
+
+ if(detail::is_same<make_slist_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+                     ,make_slist_base_hook<>::type
+                     >::value == true){
+      return 1;
+   }
+
+ if(detail::is_same<make_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+                     ,make_set_base_hook<>::type
+                     >::value == true){
+      return 1;
+   }
+
+ if(detail::is_same<make_unordered_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+                     ,make_unordered_set_base_hook<>::type
+                     >::value == true){
+      return 1;
+   }
+
+ if(detail::is_same<make_avl_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+                     ,make_avl_set_base_hook<>::type
+                     >::value == true){
+      return 1;
+   }
+
+ if(detail::is_same<make_splay_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+                     ,make_splay_set_base_hook<>::type
+                     >::value == true){
+      return 1;
+   }
+
+ if(detail::is_same<make_bs_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+                     ,make_bs_set_base_hook<>::type
+                     >::value == true){
+      return 1;
+   }
+
+
+   return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/multiset_test.cpp        Mon Aug 23 23:00:26 2010
@@ -0,0 +1,157 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_multiset_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef set_base_hook
+            <void_pointer<VoidPointer> >                    base_hook_type;
+   typedef set_base_hook
+           <link_mode<auto_unlink>
+           , void_pointer<VoidPointer>
+           , tag<my_tag>
+ , optimize_size<true> > auto_base_hook_type;
+   typedef set_member_hook<void_pointer
+ <VoidPointer>, optimize_size<true> > member_hook_type;
+   typedef set_member_hook
+ <link_mode<auto_unlink>, void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::multiset
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/set_test.cpp     Mon Aug 23 23:00:26 2010
@@ -0,0 +1,159 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+
+#include <boost/intrusive/set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_set_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+struct my_tag;
+
+using namespace boost::intrusive;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef set_base_hook
+            <void_pointer<VoidPointer> >                    base_hook_type;
+   typedef set_base_hook
+           <link_mode<auto_unlink>
+           , void_pointer<VoidPointer>
+           , tag<my_tag>
+ , optimize_size<true> > auto_base_hook_type;
+   typedef set_member_hook<void_pointer
+ <VoidPointer>, optimize_size<true> > member_hook_type;
+   typedef set_member_hook
+ <link_mode<auto_unlink>, void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::set
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/sg_multiset_test.cpp     Mon Aug 23 23:00:26 2010
@@ -0,0 +1,151 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_multiset_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::sg_multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::sg_multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef bs_set_base_hook<void_pointer<VoidPointer> >     base_hook_type;
+ typedef bs_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
+   typedef member_hook_type   auto_member_hook_type;
+   struct auto_base_hook_type
+      :  bs_set_base_hook<void_pointer<VoidPointer>, tag<my_tag> >
+   {};
+};
+
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::sg_multiset
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainerFixedAlpha
+{
+   typedef boost::intrusive::sg_multiset
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      , boost::intrusive::floating_point<false>
+      > type;
+};
+
+template<class VoidPointer>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , true> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+               , GetContainer
+               >::test_all();
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                              , &value_type::node_
+                              >
+                  >::type
+               , GetContainer
+               >::test_all();
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+               , GetContainerFixedAlpha
+               >::test_all();
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                              , &value_type::node_
+                              >
+                  >::type
+               , GetContainerFixedAlpha
+               >::test_all();
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*>()();
+   test_main_template<boost::intrusive::smart_ptr<void> >()();
+   return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/sg_set_test.cpp  Mon Aug 23 23:00:26 2010
@@ -0,0 +1,151 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_set_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::sg_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::sg_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef bs_set_base_hook<void_pointer<VoidPointer> >     base_hook_type;
+ typedef bs_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
+   typedef member_hook_type   auto_member_hook_type;
+   struct auto_base_hook_type
+      :  bs_set_base_hook<void_pointer<VoidPointer>, tag<my_tag> >
+   {};
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::sg_set
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainerFixedAlpha
+{
+   typedef boost::intrusive::sg_set
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      , boost::intrusive::floating_point<false>
+      > type;
+};
+
+template<class VoidPointer>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , true> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainerFixedAlpha
+                >::test_all();
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainerFixedAlpha
+                >::test_all();
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*>()();
+   test_main_template<boost::intrusive::smart_ptr<void> >()();
+   return boost::report_errors();
+}
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/slist_test.cpp   Mon Aug 23 23:00:26 2010
@@ -0,0 +1,732 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef slist_base_hook<void_pointer<VoidPointer> > base_hook_type;
+   typedef slist_base_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer>, tag<my_tag> > auto_base_hook_type; + typedef slist_member_hook<void_pointer<VoidPointer>, tag<my_tag> > member_hook_type;
+   typedef slist_member_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template<class ValueTraits, bool Linear, bool CacheLast>
+struct test_slist
+{
+   typedef typename ValueTraits::value_type value_type;
+   static void test_all(std::vector<value_type>& values);
+   static void test_front(std::vector<value_type>& values);
+ static void test_back(std::vector<value_type>& values, detail::bool_<true>); + static void test_back(std::vector<value_type>& values, detail::bool_<false>);
+   static void test_sort(std::vector<value_type>& values);
+   static void test_merge(std::vector<value_type>& values);
+   static void test_remove_unique(std::vector<value_type>& values);
+   static void test_insert(std::vector<value_type>& values);
+   static void test_shift(std::vector<value_type>& values);
+   static void test_swap(std::vector<value_type>& values);
+   static void test_slow_insert(std::vector<value_type>& values);
+   static void test_clone(std::vector<value_type>& values);
+ static void test_container_from_end(std::vector<value_type> &, detail::bool_<true>){} + static void test_container_from_end(std::vector<value_type> &values, detail::bool_<false>);
+};
+
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_all (std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   {
+      list_type list(values.begin(), values.end());
+      test::test_container(list);
+      list.clear();
+      list.insert(list.end(), values.begin(), values.end());
+      test::test_sequence_container(list, values);
+   }
+   test_front(values);
+   test_back(values, detail::bool_<CacheLast>());
+   test_sort(values);
+   test_merge (values);
+   test_remove_unique(values);
+   test_insert(values);
+   test_shift(values);
+   test_slow_insert (values);
+   test_swap(values);
+   test_clone(values);
+   test_container_from_end(values, detail::bool_<Linear>());
+}
+
+//test: push_front, pop_front, front, size, empty:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_front(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist;
+   BOOST_TEST (testlist.empty());
+
+   testlist.push_front (values[0]);
+   BOOST_TEST (testlist.size() == 1);
+   BOOST_TEST (&testlist.front() == &values[0]);
+
+   testlist.push_front (values[1]);
+   BOOST_TEST (testlist.size() == 2);
+   BOOST_TEST (&testlist.front() == &values[1]);
+
+   testlist.pop_front();
+   BOOST_TEST (testlist.size() == 1);
+   BOOST_TEST (&testlist.front() == &values[0]);
+
+   testlist.pop_front();
+   BOOST_TEST (testlist.empty());
+}
+
+//test: push_front, pop_front, front, size, empty:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_back(std::vector<typename ValueTraits::value_type>& values, detail::bool_<true>)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist;
+   BOOST_TEST (testlist.empty());
+
+   testlist.push_back (values[0]);
+   BOOST_TEST (testlist.size() == 1);
+   BOOST_TEST (&testlist.front() == &values[0]);
+   BOOST_TEST (&testlist.back() == &values[0]);
+   testlist.push_back(values[1]);
+   BOOST_TEST(*testlist.previous(testlist.end()) == values[1]);
+   BOOST_TEST (&testlist.front() == &values[0]);
+   BOOST_TEST (&testlist.back() == &values[1]);
+}
+
+//test: push_front, pop_front, front, size, empty:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_back(std::vector<typename ValueTraits::value_type>&, detail::bool_<false>)
+{}
+
+
+//test: merge due to error in merge implementation:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_merge (std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist1, testlist2;
+   testlist1.push_front (values[0]);
+   testlist2.push_front (values[4]);
+   testlist2.push_front (values[3]);
+   testlist2.push_front (values[2]);
+   testlist1.merge (testlist2);
+
+   int init_values [] = { 1, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
+}
+
+//test: merge due to error in merge implementation:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_remove_unique (std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   {
+      list_type list(values.begin(), values.end());
+      list.remove_if(is_even());
+      int init_values [] = { 1, 3, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+   }
+   {
+      std::vector<typename ValueTraits::value_type> values2(values);
+      list_type list(values.begin(), values.end());
+ list.insert_after(list.before_begin(), values2.begin(), values2.end());
+      list.sort();
+      int init_values [] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+      list.unique();
+      int init_values2 [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values2, list.begin() );
+   }
+}
+
+//test: constructor, iterator, sort, reverse:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_sort(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist (values.begin(), values.end());
+
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
+
+   testlist.sort (even_odd());
+   {  int init_values [] = { 2, 4, 1, 3, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
+
+   testlist.reverse();
+   {  int init_values [] = { 5, 3, 1, 4, 2 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
+}
+
+//test: assign, insert_after, const_iterator, erase_after, s_iterator_to, previous:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_insert(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist;
+   testlist.assign (&values[0] + 2, &values[0] + 5);
+
+   const list_type& const_testlist = testlist;
+   {  int init_values [] = { 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+
+   typename list_type::iterator i = ++testlist.begin();
+   BOOST_TEST (i->value_ == 4);
+
+   testlist.insert_after (i, values[0]);
+   {  int init_values [] = { 3, 4, 1, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+
+   i = testlist.iterator_to (values[4]);
+   BOOST_TEST (&*i == &values[4]);
+   i = list_type::s_iterator_to (values[4]);
+   BOOST_TEST (&*i == &values[4]);
+   i = testlist.previous (i);
+   BOOST_TEST (&*i == &values[0]);
+
+   testlist.erase_after (i);
+   BOOST_TEST (&*i == &values[0]);
+   {  int init_values [] = { 3, 4, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+}
+
+//test: insert, const_iterator, erase, siterator_to:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_slow_insert (std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist;
+   testlist.push_front (values[4]);
+   testlist.insert (testlist.begin(), &values[0] + 2, &values[0] + 4);
+
+   const list_type& const_testlist = testlist;
+   {  int init_values [] = { 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+
+   typename list_type::iterator i = ++testlist.begin();
+   BOOST_TEST (i->value_ == 4);
+
+   testlist.insert (i, values[0]);
+   {  int init_values [] = { 3, 1, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+
+   i = testlist.iterator_to (values[4]);
+   BOOST_TEST (&*i == &values[4]);
+
+   i = list_type::s_iterator_to (values[4]);
+   BOOST_TEST (&*i == &values[4]);
+
+   i = testlist.erase (i);
+   BOOST_TEST (i == testlist.end());
+
+   {  int init_values [] = { 3, 1, 4 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
+
+   testlist.erase (++testlist.begin(), testlist.end());
+   BOOST_TEST (testlist.size() == 1);
+   BOOST_TEST (testlist.front().value_ == 3);
+}
+
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_shift(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist;
+
+   const int num_values = (int)values.size();
+   std::vector<int> expected_values(num_values);
+
+   //Shift forward all possible positions 3 times
+   for(int s = 1; s <= num_values; ++s){
+      expected_values.resize(s);
+      for(int i = 0; i < s*3; ++i){
+ testlist.insert_after(testlist.before_begin(), &values[0], &values[0] + s);
+         testlist.shift_forward(i);
+         for(int j = 0; j < s; ++j){
+            expected_values[(j + s - i%s) % s] = (j + 1);
+         }
+
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
+         testlist.clear();
+      }
+
+      //Shift backwards all possible positions
+      for(int i = 0; i < s*3; ++i){
+ testlist.insert_after(testlist.before_begin(), &values[0], &values[0] + s);
+         testlist.shift_backwards(i);
+         for(int j = 0; j < s; ++j){
+            expected_values[(j + i) % s] = (j + 1);
+         }
+
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
+         testlist.clear();
+      }
+   }
+}
+
+//test: insert_after (seq-version), swap, splice_after:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_swap(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   {
+      list_type testlist1 (&values[0], &values[0] + 2);
+      list_type testlist2;
+ testlist2.insert_after (testlist2.before_begin(), &values[0] + 2, &values[0] + 5);
+      testlist1.swap(testlist2);
+      {  int init_values [] = { 3, 4, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+      {  int init_values [] = { 1, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+         testlist2.splice_after (testlist2.begin(), testlist1);
+      {  int init_values [] = { 1, 3, 4, 5, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+      BOOST_TEST (testlist1.empty());
+
+ testlist1.splice_after (testlist1.before_begin(), testlist2, ++testlist2.begin());
+      {  int init_values [] = { 4 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+      {  int init_values [] = { 1, 3, 5, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+
+      testlist1.splice_after (testlist1.begin(), testlist2,
+ testlist2.before_begin(), ++++testlist2.begin());
+      {  int init_values [] = { 4, 1, 3, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+      {  int init_values [] = { 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+   }
+   {  //Now test swap when testlist2 is empty
+      list_type testlist1 (&values[0], &values[0] + 2);
+      list_type testlist2;
+      testlist1.swap(testlist2);
+      BOOST_TEST (testlist1.empty());
+      {  int init_values [] = { 1, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+   }
+   {  //Now test swap when testlist1 is empty
+      list_type testlist2 (&values[0], &values[0] + 2);
+      list_type testlist1;
+      testlist1.swap(testlist2);
+      BOOST_TEST (testlist2.empty());
+      {  int init_values [] = { 1, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+   }
+   {  //Now test when both are empty
+      list_type testlist1, testlist2;
+      testlist2.swap(testlist1);
+      BOOST_TEST (testlist1.empty() && testlist2.empty());
+   }
+
+   if(!list_type::linear)
+   {
+      list_type testlist1 (&values[0], &values[0] + 2);
+      list_type testlist2 (&values[0] + 3, &values[0] + 5);
+
+      values[0].swap_nodes(values[2]);
+      {  int init_values [] = { 3, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[2].swap_nodes(values[4]);
+      {  int init_values [] = { 5, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+      {  int init_values [] = { 4, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
+   }
+   if(!list_type::linear)
+   {
+      list_type testlist1 (&values[0], &values[1]);
+
+      {  int init_values [] = { 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[1].swap_nodes(values[2]);
+
+      {  int init_values [] = { 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[0].swap_nodes(values[2]);
+
+      {  int init_values [] = { 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+
+      values[0].swap_nodes(values[2]);
+
+      {  int init_values [] = { 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
+   }
+}
+
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+   ::test_clone(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+
+      list_type testlist1 (&values[0], &values[0] + values.size());
+      list_type testlist2;
+
+ testlist2.clone_from(testlist1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+      BOOST_TEST (testlist2 == testlist1);
+      testlist2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testlist2.empty());
+}
+
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values
+                            ,detail::bool_<false>)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef slist
+      < value_type
+      , value_traits<ValueTraits>
+      , size_type<std::size_t>
+      , constant_time_size<value_type::constant_time_size>
+      , linear<Linear>
+      , cache_last<CacheLast>
+      > list_type;
+   list_type testlist1 (&values[0], &values[0] + values.size());
+ BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end())); + BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend()));
+}
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+      std::vector<value_type> data (5);
+      for (int i = 0; i < 5; ++i)
+         data[i].value_ = i + 1;
+
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , false
+                 , false
+                >::test_all(data);
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , false
+                 , false
+                >::test_all(data);
+
+      //Now linear slists
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , true
+                 , false
+                >::test_all(data);
+
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , true
+                 , false
+                >::test_all(data);
+
+      //Now the same but caching the last node
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , false
+                 , true
+                >::test_all(data);
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , false
+                 , true
+                >::test_all(data);
+
+      //Now linear slists
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , true
+                 , true
+                >::test_all(data);
+
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , true
+                 , true
+                >::test_all(data);
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+      std::vector<value_type> data (5);
+      for (int i = 0; i < 5; ++i)
+         data[i].value_ = i + 1;
+
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , false
+                 , false
+                >::test_all(data);
+
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , false
+                 , false
+                >::test_all(data);
+
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                 , false
+                 , false
+                >::test_all(data);
+
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                 , false
+                 , false
+                >::test_all(data);
+
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , true
+                 , false
+                >::test_all(data);
+
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , true
+                 , false
+                >::test_all(data);
+
+      //Now cache last
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , false
+                 , true
+                >::test_all(data);
+
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , false
+                 , true
+                >::test_all(data);
+
+      test_slist < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                 , true
+                 , true
+                >::test_all(data);
+
+      test_slist < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                 , true
+                 , true
+                >::test_all(data);
+      return 0;
+   }
+};
+
+int main(int, char* [])
+{
+   test_main_template<void*, false>()();
+   test_main_template<smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/smart_ptr.hpp    Mon Aug 23 23:00:26 2010
@@ -0,0 +1,388 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006. 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/intrusive for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP
+#define BOOST_INTRUSIVE_SMART_PTR_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/intrusive/pointer_plus_bits.hpp>
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+namespace boost{
+namespace intrusive{
+
+namespace detail {
+
+struct static_cast_tag {};
+struct const_cast_tag {};
+struct dynamic_cast_tag {};
+struct reinterpret_cast_tag {};
+
+}  //namespace detail {
+
+//Empty class
+struct empty_type{};
+
+template<class T>
+struct random_it
+: public boost::iterator<std::random_access_iterator_tag,
+                         T, std::ptrdiff_t, T*, T&>
+{
+   typedef const T*           const_pointer;
+   typedef const T&           const_reference;
+};
+
+template<> struct random_it<void>
+{
+   typedef const void *       const_pointer;
+   typedef empty_type&        reference;
+   typedef const empty_type&  const_reference;
+   typedef empty_type         difference_type;
+   typedef empty_type         iterator_category;
+};
+
+template<> struct random_it<const void>
+{
+   typedef const void *       const_pointer;
+   typedef const empty_type & reference;
+   typedef const empty_type & const_reference;
+   typedef empty_type         difference_type;
+   typedef empty_type         iterator_category;
+};
+
+template<> struct random_it<volatile void>
+{
+   typedef const volatile void * const_pointer;
+   typedef empty_type&           reference;
+   typedef const empty_type&     const_reference;
+   typedef empty_type            difference_type;
+   typedef empty_type            iterator_category;
+};
+
+template<> struct random_it<const volatile void>
+{
+   typedef const volatile void *    const_pointer;
+   typedef const empty_type &       reference;
+   typedef const empty_type &       const_reference;
+   typedef empty_type               difference_type;
+   typedef empty_type               iterator_category;
+};
+
+}  //namespace intrusive {
+}  //namespace boost {
+
+
+namespace boost {
+namespace intrusive {
+
+template <class PointedType>
+class smart_ptr
+{
+   typedef random_it<PointedType> random_it_t;
+   typedef smart_ptr<PointedType>                           self_t;
+ typedef typename random_it_t::const_pointer const_pointer_t; + typedef typename random_it_t::const_reference const_reference_t;
+
+   void unspecified_bool_type_func() const {}
+   typedef void (self_t::*unspecified_bool_type)() const;
+
+   public:
+   typedef PointedType *                           pointer;
+   typedef typename random_it_t::reference         reference;
+   typedef PointedType                             value_type;
+   typedef typename random_it_t::difference_type   difference_type;
+   typedef typename random_it_t::iterator_category iterator_category;
+
+   PointedType *m_ptr;
+
+   public:   //Public Functions
+
+ //!Constructor from raw pointer (allows "0" pointer conversion). Never throws.
+   explicit smart_ptr(pointer ptr = 0)
+      :  m_ptr(ptr)
+   {}
+
+   //!Constructor from other pointer. Never throws.
+   template <class T>
+   smart_ptr(T *ptr)
+      :  m_ptr(ptr)
+   {}
+
+   //!Constructor from other smart_ptr
+   smart_ptr(const smart_ptr& ptr)
+      :  m_ptr(ptr.m_ptr)
+   {}
+
+   //!Constructor from other smart_ptr. If pointers of pointee types are
+   //!convertible, offset_ptrs will be convertibles. Never throws.
+   template<class T2>
+   smart_ptr(const smart_ptr<T2> &ptr)
+      :  m_ptr(ptr.m_ptr)
+   {}
+
+   //!Emulates static_cast operator. Never throws.
+   template<class Y>
+   smart_ptr(const smart_ptr<Y> & r, detail::static_cast_tag)
+      :  m_ptr(static_cast<PointedType*>(r.get()))
+   {}
+
+   //!Emulates const_cast operator. Never throws.
+   template<class Y>
+   smart_ptr(const smart_ptr<Y> & r, detail::const_cast_tag)
+      :  m_ptr(const_cast<PointedType*>(r.get()))
+   {}
+
+   //!Emulates dynamic_cast operator. Never throws.
+   template<class Y>
+   smart_ptr(const smart_ptr<Y> & r, detail::dynamic_cast_tag)
+      :  m_ptr(dynamic_cast<PointedType*>(r.get()))
+   {}
+
+   //!Emulates reinterpret_cast operator. Never throws.
+   template<class Y>
+   smart_ptr(const smart_ptr<Y> & r, detail::reinterpret_cast_tag)
+      :  m_ptr(reinterpret_cast<PointedType*>(r.get()))
+   {}
+
+   //!Obtains raw pointer from offset. Never throws.
+   pointer get() const
+   {  return m_ptr;   }
+
+   //!Pointer-like -> operator. It can return 0 pointer. Never throws.
+   pointer operator->() const
+   {  return this->get(); }
+
+   //!Dereferencing operator, if it is a null smart_ptr behavior
+   //!   is undefined. Never throws.
+   reference operator* () const
+   {  return *(this->get());   }
+
+   //!Indexing operator. Never throws.
+   reference operator[](std::ptrdiff_t idx) const
+   {  return this->get()[idx];  }
+
+   //!Assignment from pointer (saves extra conversion). Never throws.
+   smart_ptr& operator= (pointer from)
+   {  m_ptr = from;  return *this;  }
+
+   //!Assignment from other smart_ptr. Never throws.
+   smart_ptr& operator= (const smart_ptr & pt)
+   {  m_ptr = pt.m_ptr;  return *this;  }
+
+   //!Assignment from related smart_ptr. If pointers of pointee types
+   //!   are assignable, offset_ptrs will be assignable. Never throws.
+   template <class T2>
+   smart_ptr& operator= (const smart_ptr<T2> & pt)
+   {  m_ptr = pt.m_ptr;  return *this;  }
+
+   //!smart_ptr + std::ptrdiff_t. Never throws.
+   smart_ptr operator+ (std::ptrdiff_t offset) const
+   {  return smart_ptr(this->get()+offset);   }
+
+   //!smart_ptr - std::ptrdiff_t. Never throws.
+   smart_ptr operator- (std::ptrdiff_t offset) const
+   {  return smart_ptr(this->get()-offset);   }
+
+   //!smart_ptr += std::ptrdiff_t. Never throws.
+   smart_ptr &operator+= (std::ptrdiff_t offset)
+   {  m_ptr += offset;   return *this;  }
+
+   //!smart_ptr -= std::ptrdiff_t. Never throws.
+   smart_ptr &operator-= (std::ptrdiff_t offset)
+   {  m_ptr -= offset;  return *this;  }
+
+   //!++smart_ptr. Never throws.
+   smart_ptr& operator++ (void)
+   {  ++m_ptr;   return *this;  }
+
+   //!smart_ptr++. Never throws.
+   smart_ptr operator++ (int)
+   {  smart_ptr temp(*this); ++*this; return temp; }
+
+   //!--smart_ptr. Never throws.
+   smart_ptr& operator-- (void)
+   {  --m_ptr;   return *this;  }
+
+   //!smart_ptr--. Never throws.
+   smart_ptr operator-- (int)
+   {  smart_ptr temp(*this); --*this; return temp; }
+
+   //!safe bool conversion operator. Never throws.
+   operator unspecified_bool_type() const
+   {  return this->get()? &self_t::unspecified_bool_type_func : 0;   }
+
+   //!Not operator. Not needed in theory, but improves portability.
+   //!Never throws.
+   bool operator! () const
+   {  return this->get() == 0;   }
+/*
+   friend void swap (smart_ptr &pt, smart_ptr &pt2)
+   {
+      value_type *ptr = pt.get();
+      pt = pt2;
+      pt2 = ptr;
+   }
+*/
+};
+
+//!smart_ptr<T1> == smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator== (const smart_ptr<T1> &pt1,
+                        const smart_ptr<T2> &pt2)
+{  return pt1.get() == pt2.get();  }
+
+//!smart_ptr<T1> != smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator!= (const smart_ptr<T1> &pt1,
+                        const smart_ptr<T2> &pt2)
+{  return pt1.get() != pt2.get();  }
+
+//!smart_ptr<T1> < smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator< (const smart_ptr<T1> &pt1,
+                       const smart_ptr<T2> &pt2)
+{  return pt1.get() < pt2.get();  }
+
+//!smart_ptr<T1> <= smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator<= (const smart_ptr<T1> &pt1,
+                        const smart_ptr<T2> &pt2)
+{  return pt1.get() <= pt2.get();  }
+
+//!smart_ptr<T1> > smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator> (const smart_ptr<T1> &pt1,
+                       const smart_ptr<T2> &pt2)
+{  return pt1.get() > pt2.get();  }
+
+//!smart_ptr<T1> >= smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator>= (const smart_ptr<T1> &pt1,
+                        const smart_ptr<T2> &pt2)
+{  return pt1.get() >= pt2.get();  }
+
+//!operator<<
+template<class E, class T, class Y>
+inline std::basic_ostream<E, T> & operator<<
+   (std::basic_ostream<E, T> & os, smart_ptr<Y> const & p)
+{  return os << p.get();   }
+
+//!operator>>
+template<class E, class T, class Y>
+inline std::basic_istream<E, T> & operator>>
+   (std::basic_istream<E, T> & os, smart_ptr<Y> & p)
+{  Y * tmp; return os >> tmp; p = tmp;   }
+
+//!std::ptrdiff_t + smart_ptr
+template<class T>
+inline smart_ptr<T> operator+(std::ptrdiff_t diff, const smart_ptr<T>& right)
+{  return right + diff;  }
+
+//!smart_ptr - smart_ptr
+template<class T, class T2>
+inline std::ptrdiff_t operator- (const smart_ptr<T> &pt, const smart_ptr<T2> &pt2)
+{  return pt.get()- pt2.get();   }
+
+//!swap specialization
+template<class T>
+inline void swap (smart_ptr<T> &pt,
+                  smart_ptr<T> &pt2)
+{
+   typename smart_ptr<T>::value_type *ptr = pt.get();
+   pt = pt2;
+   pt2 = ptr;
+}
+
+//!detail::get_pointer() enables boost::mem_fn to recognize smart_ptr.
+//!Never throws.
+template<class T>
+inline T* get_pointer(const smart_ptr<T>  & p)
+{  return p.get();   }
+
+//!Simulation of static_cast between pointers. Never throws.
+template<class T, class U>
+inline smart_ptr<T>
+   static_pointer_cast(smart_ptr<U> const & r)
+{
+   return smart_ptr<T>(r, detail::static_cast_tag());
+}
+
+//!Simulation of const_cast between pointers. Never throws.
+template<class T, class U>
+inline smart_ptr<T>const_pointer_cast(smart_ptr<U> const & r)
+{
+   return smart_ptr<T>(r, detail::const_cast_tag());
+}
+
+//!Simulation of dynamic_cast between pointers. Never throws.
+template<class T, class U>
+inline smart_ptr<T>
+   dynamic_pointer_cast(smart_ptr<U> const & r)
+{
+   return smart_ptr<T>
+            (r, detail::dynamic_cast_tag());
+}
+
+//!Simulation of reinterpret_cast between pointers. Never throws.
+template<class T, class U>
+inline smart_ptr<T>
+   reinterpret_pointer_cast(smart_ptr<U> const & r)
+{
+   return smart_ptr<T>(r, detail::reinterpret_cast_tag());
+}
+
+}  //namespace intrusive {
+}  //namespace boost {
+
+namespace boost{
+
+//This is to support embedding a bit in the pointer
+//for intrusive containers, saving space
+namespace intrusive {
+
+template<std::size_t Alignment>
+struct max_pointer_plus_bits<smart_ptr<void>, Alignment>
+{
+ static const std::size_t value = max_pointer_plus_bits<void*, Alignment>::value;
+};
+
+template<class T, std::size_t NumBits>
+struct pointer_plus_bits<smart_ptr<T>, NumBits>
+{
+   typedef smart_ptr<T>         pointer;
+
+   static pointer get_pointer(const pointer &n)
+   {  return pointer_plus_bits<T*, NumBits>::get_pointer(n.get());  }
+
+   static void set_pointer(pointer &n, pointer p)
+   {
+      T *raw_n = n.get();
+      pointer_plus_bits<T*, NumBits>::set_pointer(raw_n, p.get());
+      n = raw_n;
+   }
+
+   static std::size_t get_bits(const pointer &n)
+   {  return pointer_plus_bits<T*, NumBits>::get_bits(n.get());  }
+
+   static void set_bits(pointer &n, std::size_t c)
+   {
+      T *raw_n = n.get();
+      pointer_plus_bits<T*, NumBits>::set_bits(raw_n, c);
+      n = raw_n;
+   }
+};
+
+}  //namespace intrusive
+}  //namespace boost{
+
+#endif //#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/splay_multiset_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,187 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_multiset_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_const_overloads<boost::intrusive::splay_multiset<
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+T, O1, O2, O3, O4
+#else
+T, Options...
+#endif
+>
+>
+{
+   static const bool value = false;
+};
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_splay<boost::intrusive::splay_multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::splay_multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef splay_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+   typedef splay_set_base_hook
+      < link_mode<auto_unlink>
+      , void_pointer<VoidPointer>
+ , tag<my_tag> > auto_base_hook_type; + typedef splay_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
+   typedef splay_set_member_hook
+      < link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::splay_multiset
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+               , GetContainer
+               >::test_all();
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                              , &value_type::node_
+                              >
+                  >::type
+               , GetContainer
+               >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+               , GetContainer
+               >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                              , &value_type::node_
+                              >
+                  >::type
+               , GetContainer
+               >::test_all();
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+               , GetContainer
+               >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                              , &value_type::auto_node_
+                              >
+                  >::type
+               , GetContainer
+               >::test_all();
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/splay_set_test.cpp       Mon Aug 23 23:00:26 2010
@@ -0,0 +1,186 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_set_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_const_overloads<boost::intrusive::splay_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = false;
+};
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_splay<boost::intrusive::splay_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::splay_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef splay_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+   typedef splay_set_base_hook
+      < link_mode<auto_unlink>
+      , void_pointer<VoidPointer>
+ , tag<my_tag> > auto_base_hook_type; + typedef splay_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
+   typedef splay_set_member_hook
+      < link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::splay_set
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/stateful_value_traits_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+{
+   public:
+   int int_;
+
+   MyClass(int i = 0)
+      :  int_(i)
+   {}
+
+   friend bool operator<(const MyClass &l, const MyClass &r)
+   {  return l.int_ < r.int_; }
+
+   friend bool operator==(const MyClass &l, const MyClass &r)
+   {  return l.int_ == r.int_; }
+
+   friend std::size_t hash_value(const MyClass &v)
+   {  return boost::hash_value(v.int_); }
+};
+
+template<class T, class NodeTraits>
+struct stateful_value_traits
+{
+   typedef NodeTraits                                          node_traits;
+   typedef typename node_traits::node                          node;
+   typedef typename node_traits::node_ptr                      node_ptr;
+ typedef typename node_traits::const_node_ptr const_node_ptr;
+   typedef T                                                   value_type;
+   typedef typename boost::pointer_to_other
+      <node_ptr, T>::type                                      pointer;
+   typedef typename boost::pointer_to_other
+ <node_ptr, const T>::type const_pointer;
+   static const link_mode_type link_mode = normal_link;
+
+   stateful_value_traits(pointer values, node_ptr node_array)
+      :  values_(values),  node_array_(node_array)
+   {}
+
+   node_ptr to_node_ptr (value_type &value)
+   {  return node_array_ + (&value - values_); }
+
+   const_node_ptr to_node_ptr (const value_type &value) const
+   {  return node_array_ + (&value - values_); }
+
+   pointer to_value_ptr(node_ptr n)
+   {  return values_ + (n - node_array_); }
+
+   const_pointer to_value_ptr(const_node_ptr n) const
+   {  return values_ + (n - node_array_); }
+
+   pointer  values_;
+   node_ptr node_array_;
+};
+
+//Define a list that will store MyClass using the external hook
+typedef stateful_value_traits< MyClass, list_node_traits<void*> > list_traits;
+typedef list<MyClass, value_traits<list_traits> > List;
+
+//Define a slist that will store MyClass using the external hook
+typedef stateful_value_traits< MyClass, slist_node_traits<void*> > slist_traits;
+typedef slist<MyClass, value_traits<slist_traits> > Slist;
+
+//Define a set that will store MyClass using the external hook
+typedef stateful_value_traits< MyClass, rbtree_node_traits<void*> > rbtree_traits;
+typedef set<MyClass, value_traits<rbtree_traits> > Set;
+
+//uset uses the same traits as slist
+typedef unordered_set<MyClass, value_traits<slist_traits> > Uset;
+
+
+typedef list_traits::node     list_node_t;
+typedef slist_traits::node    slist_node_t;
+typedef rbtree_traits::node   rbtree_node_t;
+
+const int NumElements = 100;
+
+MyClass        values    [NumElements];
+list_node_t    list_hook_array   [NumElements];
+slist_node_t   slist_hook_array  [NumElements];
+rbtree_node_t  rbtree_hook_array [NumElements];
+slist_node_t   uset_hook_array   [NumElements];
+
+int main()
+{
+   //Create several MyClass objects, each one with a different value
+   for(int i = 0; i < NumElements; ++i)
+      values[i].int_ = i;
+
+   Uset::bucket_type buckets[NumElements];
+
+   List  my_list (list_traits (values, list_hook_array));
+   Slist my_slist(slist_traits(values, slist_hook_array));
+ Set my_set (std::less<MyClass>(), rbtree_traits(values, rbtree_hook_array));
+   Uset  my_uset ( Uset::bucket_traits(buckets, NumElements)
+                 , boost::hash<MyClass>()
+                 , std::equal_to<MyClass>()
+                 , slist_traits(values, uset_hook_array)
+                 );
+
+   //Now insert them in containers
+   for(MyClass * it(&values[0]), *itend(&values[NumElements])
+      ; it != itend
+      ; ++it){
+      my_list.push_front(*it);
+      my_slist.push_front(*it);
+      my_set.insert(*it);
+      my_uset.insert(*it);
+   }
+
+   //Now test lists
+   {
+      List::const_iterator   list_it (my_list.cbegin());
+      Slist::const_iterator  slist_it(my_slist.cbegin());
+      Set::const_reverse_iterator set_rit(my_set.crbegin());
+      MyClass *it_val(&values[NumElements-1]), *it_rbeg_val(&values[0]-1);
+
+      //Test the objects inserted in the base hook list
+ for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++set_rit){
+         if(&*list_it  != &*it_val)   return 1;
+         if(&*slist_it != &*it_val)   return 1;
+         if(&*set_rit  != &*it_val)   return 1;
+         if(my_uset.find(*it_val) == my_uset.cend())  return 1;
+      }
+   }
+
+   return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/test_container.hpp       Mon Aug 23 23:00:26 2010
@@ -0,0 +1,397 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_TEST_CONTAINER_HPP
+#define BOOST_INTRUSIVE_TEST_CONTAINER_HPP
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+
+namespace boost {
+namespace intrusive {
+namespace test {
+
+template<class T>
+struct is_unordered
+{
+   static const bool value = false;
+};
+
+template<class T>
+struct has_const_overloads
+{
+   static const bool value = true;
+};
+
+template< class Container >
+void test_container( Container & c )
+{
+   typedef typename Container::value_type       value_type;
+   typedef typename Container::iterator         iterator;
+   typedef typename Container::const_iterator   const_iterator;
+   typedef typename Container::reference        reference;
+   typedef typename Container::const_reference  const_reference;
+   typedef typename Container::pointer          pointer;
+   typedef typename Container::const_pointer    const_pointer;
+   typedef typename Container::difference_type  difference_type;
+   typedef typename Container::size_type        size_type;
+   typedef typename Container::difference_type  difference_type;
+   typedef typename Container::size_type        size_type;
+   typedef typename Container::value_traits     value_traits;
+
+   const size_type num_elem = c.size();
+   BOOST_TEST( c.empty() == (num_elem == 0) );
+   {
+      iterator it(c.begin()), itend(c.end());
+      size_type i;
+      for(i = 0; i < num_elem; ++i){
+         ++it;
+      }
+      BOOST_TEST( it == c.end() );
+      BOOST_TEST( c.size() == i );
+   }
+
+   //Check iterator conversion
+   BOOST_TEST( const_iterator(c.begin()) == c.cbegin() );
+   {
+      const_iterator it(c.cbegin()), itend(c.cend());
+      size_type i;
+      for(i = 0; i < num_elem; ++i){
+         ++it;
+      }
+      BOOST_TEST( it == c.cend() );
+      BOOST_TEST( c.size() == i );
+   }
+}
+
+
+template< class Container, class Data >
+void test_sequence_container(Container & c, Data & d)
+{
+   assert( d.size() > 2 );
+
+   c.clear();
+
+   BOOST_TEST( c.size() == 0 );
+   BOOST_TEST( c.empty() );
+
+
+   {
+   typename Data::iterator i = d.begin();
+   c.insert( c.begin(), *i );
+   c.insert( c.end(), *(++i) );
+   }
+
+   BOOST_TEST( c.size() == 2 );
+   BOOST_TEST( !c.empty() );
+
+   typename Container::iterator i;
+   i = c.erase( c.begin() );
+
+   BOOST_TEST( c.size() == 1 );
+
+   {
+   typename Data::iterator i = d.begin();
+   ++++i;
+   c.insert( c.begin(), *(i) );
+   }
+
+   i = c.erase( c.begin(), c.end() );
+   BOOST_TEST( i == c.end() );
+
+   BOOST_TEST( c.empty() );
+
+   c.insert( c.begin(), *d.begin() );
+
+   BOOST_TEST( c.size() == 1 );
+
+   BOOST_TEST( c.begin() != c.end() );
+
+   i = c.erase_and_dispose( c.begin(), detail::null_disposer() );
+   BOOST_TEST( i == c.begin() );
+
+   c.assign(d.begin(), d.end());
+
+   BOOST_TEST( c.size() == d.size() );
+
+   c.clear();
+
+   BOOST_TEST( c.size() == 0 );
+   BOOST_TEST( c.empty() );
+}
+
+template< class Container, class Data >
+void test_common_unordered_and_associative_container(Container & c, Data & d, boost::intrusive::detail::true_ unordered)
+{
+   (void)unordered;
+   typedef typename Container::size_type  size_type;
+
+   assert( d.size() > 2 );
+
+   c.clear();
+   c.insert(d.begin(), d.end());
+
+   for( typename Data::const_iterator di = d.begin(), de = d.end();
+      di != de; ++di )
+   {
+      BOOST_TEST( c.find(*di) != c.end() );
+   }
+
+   typename Data::const_iterator db = d.begin();
+   typename Data::const_iterator da = db++;
+
+   size_type old_size = c.size();
+
+   c.erase(*da, c.hash_function(), c.key_eq());
+   BOOST_TEST( c.size() == old_size-1 );
+   //This should not eras anyone
+   size_type second_erase = c.erase_and_dispose
+      ( *da, c.hash_function(), c.key_eq(), detail::null_disposer() );
+   BOOST_TEST( second_erase == 0 );
+
+   BOOST_TEST( c.count(*da, c.hash_function(), c.key_eq()) == 0 );
+   BOOST_TEST( c.count(*db, c.hash_function(), c.key_eq()) != 0 );
+
+   BOOST_TEST( c.find(*da, c.hash_function(), c.key_eq()) == c.end() );
+   BOOST_TEST( c.find(*db, c.hash_function(), c.key_eq()) != c.end() );
+
+ BOOST_TEST( c.equal_range(*db, c.hash_function(), c.key_eq()).first != c.end() );
+
+   c.clear();
+
+ BOOST_TEST( c.equal_range(*da, c.hash_function(), c.key_eq()).first == c.end() );
+}
+
+template< class Container, class Data >
+void test_common_unordered_and_associative_container(Container & c, Data & d, boost::intrusive::detail::false_ unordered)
+{
+   (void)unordered;
+   typedef typename Container::size_type  size_type;
+
+   assert( d.size() > 2 );
+
+   c.clear();
+   c.insert(d.begin(), d.end());
+
+   for( typename Data::const_iterator di = d.begin(), de = d.end();
+      di != de; ++di )
+   {
+      BOOST_TEST( c.find(*di, c.key_comp()) != c.end() );
+   }
+
+   typename Data::const_iterator db = d.begin();
+   typename Data::const_iterator da = db++;
+
+   size_type old_size = c.size();
+
+   c.erase(*da, c.key_comp());
+   BOOST_TEST( c.size() == old_size-1 );
+   //This should not eras anyone
+ size_type second_erase = c.erase_and_dispose( *da, c.key_comp(), detail::null_disposer() );
+   BOOST_TEST( second_erase == 0 );
+
+   BOOST_TEST( c.count(*da, c.key_comp()) == 0 );
+   BOOST_TEST( c.count(*db, c.key_comp()) != 0 );
+   BOOST_TEST( c.find(*da, c.key_comp()) == c.end() );
+   BOOST_TEST( c.find(*db, c.key_comp()) != c.end() );
+   BOOST_TEST( c.equal_range(*db, c.key_comp()).first != c.end() );
+   c.clear();
+   BOOST_TEST( c.equal_range(*da, c.key_comp()).first == c.end() );
+}
+
+
+template< class Container, class Data >
+void test_common_unordered_and_associative_container(Container & c, Data & d)
+{
+   {
+   typedef typename Container::size_type  size_type;
+
+   assert( d.size() > 2 );
+
+   c.clear();
+   c.insert(d.begin(), d.end());
+
+   for( typename Data::const_iterator di = d.begin(), de = d.end();
+      di != de; ++di )
+   {
+      BOOST_TEST( c.find(*di) != c.end() );
+   }
+
+   typename Data::const_iterator db = d.begin();
+   typename Data::const_iterator da = db++;
+
+   size_type old_size = c.size();
+
+   c.erase(*da);
+   BOOST_TEST( c.size() == old_size-1 );
+   //This should not eras anyone
+ size_type second_erase = c.erase_and_dispose( *da, detail::null_disposer() );
+   BOOST_TEST( second_erase == 0 );
+
+   BOOST_TEST( c.count(*da) == 0 );
+   BOOST_TEST( c.count(*db) != 0 );
+
+   BOOST_TEST( c.find(*da) == c.end() );
+   BOOST_TEST( c.find(*db) != c.end() );
+
+   BOOST_TEST( c.equal_range(*db).first != c.end() );
+
+   c.clear();
+
+   BOOST_TEST( c.equal_range(*da).first == c.end() );
+   }
+   typedef detail::bool_<is_unordered<Container>::value> enabler;
+   test_common_unordered_and_associative_container(c, d, enabler());
+}
+
+template< class Container, class Data >
+void test_associative_container_invariants(Container & c, Data & d, boost::intrusive::detail::true_type)
+{
+   typedef typename Container::const_iterator const_iterator;
+   for( typename Data::const_iterator di = d.begin(), de = d.end();
+      di != de; ++di)
+   {
+      const_iterator ci = c.find(*di);
+      BOOST_TEST( ci != c.end() );
+      BOOST_TEST( ! c.value_comp()(*ci, *di) );
+      const_iterator cil = c.lower_bound(*di);
+      const_iterator ciu = c.upper_bound(*di);
+      std::pair<const_iterator, const_iterator> er = c.equal_range(*di);
+      BOOST_TEST( cil == er.first );
+      BOOST_TEST( ciu == er.second );
+      if(ciu != c.end()){
+         BOOST_TEST( c.value_comp()(*cil, *ciu) );
+      }
+      if(c.count(*di) > 1){
+         const_iterator ci_next = cil; ++ci_next;
+         for( ; ci_next != ciu; ++cil, ++ci_next){
+            BOOST_TEST( !c.value_comp()(*ci_next, *cil) );
+         }
+      }
+   }
+}
+
+template< class Container, class Data >
+void test_associative_container_invariants(Container &, Data &, boost::intrusive::detail::false_type)
+{}
+
+template< class Container, class Data >
+void test_associative_container_invariants(Container & c, Data & d)
+{
+   using namespace boost::intrusive;
+   typedef typename detail::remove_const<Container>::type Type;
+   typedef detail::bool_<has_const_overloads<Type>::value> enabler;
+   test_associative_container_invariants(c, d, enabler());
+}
+
+template< class Container, class Data >
+void test_associative_container(Container & c, Data & d)
+{
+   typedef typename Container::const_iterator const_iterator;
+   assert( d.size() > 2 );
+
+   c.clear();
+   c.insert(d.begin(),d.end());
+
+   test_associative_container_invariants(c, d);
+
+   const Container & cr = c;
+
+   test_associative_container_invariants(cr, d);
+}
+
+template< class Container, class Data >
+void test_unordered_associative_container_invariants(Container & c, Data & d, boost::intrusive::detail::true_type)
+{
+   typedef typename Container::size_type size_type;
+   typedef typename Container::const_iterator const_iterator;
+
+   for( typename Data::const_iterator di = d.begin(), de = d.end() ;
+      di != de ; ++di ){
+      const_iterator i = c.find(*di);
+      size_type nb = c.bucket(*i);
+      size_type bucket_elem = std::distance(c.begin(nb), c.end(nb));
+      BOOST_TEST( bucket_elem ==  c.bucket_size(nb) );
+      BOOST_TEST( &*c.local_iterator_to(*c.find(*di)) == &*i );
+      std::pair<const_iterator, const_iterator> er = c.equal_range(*di);
+      size_type cnt = std::distance(er.first, er.second);
+      BOOST_TEST( cnt == c.count(*di));
+      if(cnt > 1)
+ for(const_iterator n = er.first, i = n++, e = er.second; n != e; ++i, ++n){
+         BOOST_TEST( c.key_eq()(*i, *n) );
+         BOOST_TEST( c.hash_function()(*i) == c.hash_function()(*n) );
+      }
+   }
+
+   size_type blen = c.bucket_count();
+   size_type total_objects = 0;
+   for(size_type i = 0; i < blen; ++i){
+      total_objects += c.bucket_size(i);
+   }
+   BOOST_TEST( total_objects ==  c.size() );
+}
+
+template< class Container, class Data >
+void test_unordered_associative_container_invariants(Container &, Data &, boost::intrusive::detail::false_type)
+{}
+
+template< class Container, class Data >
+void test_unordered_associative_container_invariants(Container & c, Data & d)
+{
+   using namespace boost::intrusive;
+   typedef typename detail::remove_const<Container>::type Type;
+   typedef detail::bool_<has_const_overloads<Type>::value> enabler;
+   test_unordered_associative_container_invariants(c, d, enabler());
+}
+
+template< class Container, class Data >
+void test_unordered_associative_container(Container & c, Data & d)
+{
+   c.clear();
+   c.insert( d.begin(), d.end() );
+
+   test_unordered_associative_container_invariants(c, d);
+
+   const Container & cr = c;
+
+   test_unordered_associative_container_invariants(cr, d);
+}
+
+template< class Container, class Data >
+void test_unique_container(Container & c, Data & d)
+{
+   typedef typename Container::value_type value_type;
+   c.clear();
+   c.insert(d.begin(),d.end());
+   typename Container::size_type old_size = c.size();
+   value_type v(*d.begin());
+   c.insert(v);
+   BOOST_TEST( c.size() == old_size );
+   c.clear();
+}
+
+template< class Container, class Data >
+void test_non_unique_container(Container & c, Data & d)
+{
+   typedef typename Container::value_type value_type;
+   c.clear();
+   c.insert(d.begin(),d.end());
+   typename Container::size_type old_size = c.size();
+   value_type v(*d.begin());
+   c.insert(v);
+   BOOST_TEST( c.size() == (old_size+1) );
+   c.clear();
+}
+
+}}}
+
+#endif   //#ifndef BOOST_INTRUSIVE_TEST_CONTAINER_HPP
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/test_macros.hpp  Mon Aug 23 23:00:26 2010
@@ -0,0 +1,26 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_TEST_TEST_MACROS_HPP
+#define BOOST_INTRUSIVE_TEST_TEST_MACROS_HPP
+
+#define TEST_INTRUSIVE_SEQUENCE( INTVALUES, ITERATOR )\
+{  \
+ BOOST_TEST (std::equal(&INTVALUES[0], &INTVALUES[0] + sizeof(INTVALUES)/sizeof(INTVALUES[0]), ITERATOR) ); \
+}
+
+#define TEST_INTRUSIVE_SEQUENCE_EXPECTED( EXPECTEDVECTOR, ITERATOR )\
+{  \
+ BOOST_TEST (std::equal(EXPECTEDVECTOR.begin(), EXPECTEDVECTOR.end(), ITERATOR) ); \
+}
+
+#endif
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/treap_multiset_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_multiset_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::treap_multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef bs_set_base_hook<void_pointer<VoidPointer> >     base_hook_type;
+   typedef bs_set_base_hook
+      < void_pointer<VoidPointer>
+ , tag<my_tag> > auto_base_hook_type;
+   typedef bs_set_member_hook
+ < void_pointer<VoidPointer> > member_hook_type;
+   typedef bs_set_member_hook
+ < void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::treap_multiset
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+ test::test_generic_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/treap_set_test.cpp       Mon Aug 23 23:00:26 2010
@@ -0,0 +1,171 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "generic_set_test.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct has_insert_before<boost::intrusive::treap_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
+struct is_treap<boost::intrusive::treap_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+   typedef bs_set_base_hook<void_pointer<VoidPointer> >     base_hook_type;
+   typedef bs_set_base_hook
+      < void_pointer<VoidPointer>
+ , tag<my_tag> > auto_base_hook_type;
+   typedef bs_set_member_hook
+ < void_pointer<VoidPointer> > member_hook_type;
+   typedef bs_set_member_hook
+ < void_pointer<VoidPointer> > auto_member_hook_type;
+};
+
+template< class ValueType
+        , class Option1 = boost::intrusive::none
+        , class Option2 = boost::intrusive::none
+        , class Option3 = boost::intrusive::none
+        >
+struct GetContainer
+{
+   typedef boost::intrusive::treap_set
+      < ValueType
+      , Option1
+      , Option2
+      , Option3
+      > type;
+};
+
+template<class VoidPointer, bool constant_time_size>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+      return 0;
+   }
+};
+
+template<class VoidPointer>
+class test_main_template<VoidPointer, false>
+{
+   public:
+   int operator()()
+   {
+      using namespace boost::intrusive;
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      test::test_generic_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , GetContainer
+                >::test_all();
+
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+   test_main_template<void*, true>()();
+   test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+   return boost::report_errors();
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/unordered_multiset_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,816 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <algorithm> //std::sort std::find
+#include <set>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
+#else
+template<class T, class ...Options>
+#endif
+struct is_unordered<boost::intrusive::unordered_multiset<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4, O5, O6
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef unordered_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+   typedef unordered_set_base_hook
+      < link_mode<auto_unlink>
+      , void_pointer<VoidPointer>
+      , tag<my_tag>
+      , store_hash<true>
+ > auto_base_hook_type;
+
+   typedef unordered_set_member_hook
+      < void_pointer<VoidPointer>
+      , optimize_multikey<true>
+ > member_hook_type;
+   typedef unordered_set_member_hook
+      < link_mode<auto_unlink>, void_pointer<VoidPointer>
+      , store_hash<true>
+      , optimize_multikey<true>
+ > auto_member_hook_type;
+};
+
+static const std::size_t BucketSize = 8;
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+struct test_unordered_multiset
+{
+   typedef typename ValueTraits::value_type value_type;
+   static void test_all (std::vector<value_type>& values);
+   static void test_sort(std::vector<value_type>& values);
+   static void test_insert(std::vector<value_type>& values);
+   static void test_swap(std::vector<value_type>& values);
+   static void test_rehash(std::vector<value_type>& values, detail::true_);
+ static void test_rehash(std::vector<value_type>& values, detail::false_);
+   static void test_find(std::vector<value_type>& values);
+   static void test_impl();
+   static void test_clone(std::vector<value_type>& values);
+};
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_all (std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      < value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   {
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+      typename unordered_multiset_type::bucket_type buckets [BucketSize];
+      unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
+      testset.insert(values.begin(), values.end());
+      test::test_container(testset);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+ test::test_common_unordered_and_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_unordered_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_non_unique_container(testset, values);
+   }
+   test_sort(values);
+   test_insert(values);
+   test_swap(values);
+   test_rehash(values, detail::bool_<Incremental>());
+   test_find(values);
+   test_impl();
+   test_clone(values);
+}
+
+//test case due to an error in tree implementation:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+   ::test_impl()
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
+   std::vector<value_type> values (5);
+   for (int i = 0; i < 5; ++i)
+      values[i].value_ = i;
+
+   typename unordered_multiset_type::bucket_type buckets [BucketSize];
+   unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
+
+   for (int i = 0; i < 5; ++i)
+      testset.insert (values[i]);
+
+   testset.erase (testset.iterator_to (values[0]));
+   testset.erase (testset.iterator_to (values[1]));
+   testset.insert (values[1]);
+
+   testset.erase (testset.iterator_to (values[2]));
+   testset.erase (testset.iterator_to (values[3]));
+}
+
+//test: constructor, iterator, clear, reverse_iterator, front, back, size:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+   ::test_sort(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
+   typename unordered_multiset_type::bucket_type buckets [BucketSize];
+ unordered_multiset_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
+
+   if(Incremental){
+      {  int init_values [] = { 4, 5, 1, 2, 2, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+   else{
+      {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+   testset1.clear();
+   BOOST_TEST (testset1.empty());
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+   ::test_insert(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+   typedef typename unordered_multiset_type::iterator iterator;
+   typename unordered_multiset_type::bucket_type buckets [BucketSize];
+   unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
+
+   testset.insert(&values[0] + 2, &values[0] + 5);
+
+   const unordered_multiset_type& const_testset = testset;
+
+   if(Incremental){
+      {
+         {  int init_values [] = { 4, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+         typename unordered_multiset_type::iterator i = testset.begin();
+         BOOST_TEST (i->value_ == 4);
+
+         i = testset.insert (values[0]);
+         BOOST_TEST (&*i == &values[0]);
+
+         i = testset.iterator_to (values[2]);
+         BOOST_TEST (&*i == &values[2]);
+         testset.erase(i);
+
+         {  int init_values [] = { 5, 1, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+         testset.clear();
+         testset.insert(&values[0], &values[0] + values.size());
+
+         {  int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+         BOOST_TEST (testset.erase(1) == 1);
+         BOOST_TEST (testset.erase(2) == 2);
+         BOOST_TEST (testset.erase(3) == 1);
+         BOOST_TEST (testset.erase(4) == 1);
+         BOOST_TEST (testset.erase(5) == 1);
+         BOOST_TEST (testset.empty() == true);
+
+         //Now with a single bucket
+         typename unordered_multiset_type::bucket_type single_bucket[1];
+         unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
+         testset2.insert(&values[0], &values[0] + values.size());
+         BOOST_TEST (testset2.erase(5) == 1);
+         BOOST_TEST (testset2.erase(2) == 2);
+         BOOST_TEST (testset2.erase(1) == 1);
+         BOOST_TEST (testset2.erase(4) == 1);
+         BOOST_TEST (testset2.erase(3) == 1);
+         BOOST_TEST (testset2.empty() == true);
+      }
+   }
+   else{
+      {
+         {  int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+         typename unordered_multiset_type::iterator i = testset.begin();
+         BOOST_TEST (i->value_ == 1);
+
+         i = testset.insert (values[0]);
+         BOOST_TEST (&*i == &values[0]);
+
+         i = testset.iterator_to (values[2]);
+         BOOST_TEST (&*i == &values[2]);
+         testset.erase(i);
+
+         {  int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+         testset.clear();
+         testset.insert(&values[0], &values[0] + values.size());
+
+         {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+         BOOST_TEST (testset.erase(1) == 1);
+         BOOST_TEST (testset.erase(2) == 2);
+         BOOST_TEST (testset.erase(3) == 1);
+         BOOST_TEST (testset.erase(4) == 1);
+         BOOST_TEST (testset.erase(5) == 1);
+         BOOST_TEST (testset.empty() == true);
+
+         //Now with a single bucket
+         typename unordered_multiset_type::bucket_type single_bucket[1];
+         unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
+         testset2.insert(&values[0], &values[0] + values.size());
+         BOOST_TEST (testset2.erase(5) == 1);
+         BOOST_TEST (testset2.erase(2) == 2);
+         BOOST_TEST (testset2.erase(1) == 1);
+         BOOST_TEST (testset2.erase(4) == 1);
+         BOOST_TEST (testset2.erase(3) == 1);
+         BOOST_TEST (testset2.empty() == true);
+      }
+   }
+   {
+      //Now erase just one per loop
+      const int random_init[] = { 3, 2, 4, 1, 5, 2, 2 };
+ const unsigned int random_size = sizeof(random_init)/sizeof(random_init[0]);
+      typename unordered_multiset_type::bucket_type single_bucket[1];
+      for(unsigned int i = 0, max = random_size; i != max; ++i){
+         std::vector<typename ValueTraits::value_type> data (random_size);
+         for (unsigned int j = 0; j < random_size; ++j)
+            data[j].value_ = random_init[j];
+ unordered_multiset_type testset_new(bucket_traits(single_bucket, 1));
+         testset_new.insert(&data[0], &data[0]+max);
+         testset_new.erase(testset_new.iterator_to(data[i]));
+         BOOST_TEST (testset_new.size() == (max -1));
+      }
+   }
+   {
+      typename unordered_multiset_type::bucket_type buckets [BucketSize];
+      const unsigned int NumBucketSize = BucketSize;
+      const unsigned int LoadFactor    = 3;
+      const unsigned int NumIterations = NumBucketSize*LoadFactor;
+      std::vector<value_type> random_init(NumIterations);//Preserve memory
+      std::vector<value_type> set_tester;
+      set_tester.reserve(NumIterations);
+
+      //Initialize values
+      for (unsigned int i = 0; i < NumIterations; ++i){
+         random_init[i].value_ = i*2;//(i/LoadFactor)*LoadFactor;
+      }
+
+ for(unsigned int initial_pos = 0; initial_pos != (NumIterations+1); ++initial_pos){ + for(unsigned int final_pos = initial_pos; final_pos != (NumIterations+1); ++final_pos){
+
+            //Create intrusive container inserting values
+            unordered_multiset_type testset
+               ( &random_init[0]
+               , &random_init[0] + random_init.size()
+               , bucket_traits(buckets, NumBucketSize));
+
+            BOOST_TEST (testset.size() == random_init.size());
+
+            //Obtain the iterator range to erase
+            iterator it_beg_pos = testset.begin();
+ for(unsigned int it_beg_pos_num = 0; it_beg_pos_num != initial_pos; ++it_beg_pos_num){
+               ++it_beg_pos;
+            }
+            iterator it_end_pos(it_beg_pos);
+ for(unsigned int it_end_pos_num = 0; it_end_pos_num != (final_pos - initial_pos); ++it_end_pos_num){
+               ++it_end_pos;
+            }
+
+ //Erase the same values in both the intrusive and original vector
+            std::size_t erased_cnt = std::distance(it_beg_pos, it_end_pos);
+
+            //Erase values from the intrusive container
+            testset.erase(it_beg_pos, it_end_pos);
+
+ BOOST_TEST (testset.size() == (random_init.size()-(final_pos - initial_pos)));
+
+            //Now test...
+ BOOST_TEST ((random_init.size() - erased_cnt) == testset.size());
+
+            //Create an ordered copy of the intrusive container
+ set_tester.insert(set_tester.end(), testset.begin(), testset.end());
+            std::sort(set_tester.begin(), set_tester.end());
+            {
+ typename std::vector<value_type>::iterator it = set_tester.begin(), itend = set_tester.end(); + typename std::vector<value_type>::iterator random_init_it(random_init.begin());
+               for( ; it != itend; ++it){
+                  while(!random_init_it->is_linked())
+                     ++random_init_it;
+                  BOOST_TEST(*it == *random_init_it);
+                  ++random_init_it;
+               }
+            }
+            set_tester.clear();
+         }
+      }
+   }
+}
+
+//test: insert (seq-version), swap, erase (seq-version), size:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_swap(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+   typename unordered_multiset_type::bucket_type buckets [BucketSize];
+
+   typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
+ unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
+   unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
+
+   testset2.insert (&values[0] + 2, &values[0] + 6);
+   testset1.swap (testset2);
+
+   if(Incremental){
+      {  int init_values [] = { 4, 5, 1, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+      {  int init_values [] = { 2, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() );  }
+      testset1.erase (testset1.iterator_to(values[4]), testset1.end());
+      BOOST_TEST (testset1.size() == 1);
+      //  BOOST_TEST (&testset1.front() == &values[3]);
+      BOOST_TEST (&*testset1.begin() == &values[2]);
+   }
+   else{
+      {  int init_values [] = { 1, 2, 4, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+      {  int init_values [] = { 2, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() );  }
+      testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+      BOOST_TEST (testset1.size() == 1);
+      //  BOOST_TEST (&testset1.front() == &values[3]);
+      BOOST_TEST (&*testset1.begin() == &values[3]);
+   }
+}
+
+
+
+//test: rehash:
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental> + ::test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::true_)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+   //Build a uset
+   typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
+   typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
+ unordered_multiset_type testset1(&values[0], &values[0] + values.size(), bucket_traits(buckets1, BucketSize));
+   //Test current state
+   BOOST_TEST(testset1.split_count() == BucketSize/2);
+   {  int init_values [] = { 4, 5, 1, 2, 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Incremental rehash step
+   BOOST_TEST (testset1.incremental_rehash() == true);
+   BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+   {  int init_values [] = { 5, 1, 2, 2, 3, 4 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Rest of incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket != BucketSize; ++split_bucket){
+      BOOST_TEST (testset1.incremental_rehash() == true);
+      BOOST_TEST(testset1.split_count() == (split_bucket+1));
+      {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+ //This incremental rehash should fail because we've reached the end of the bucket array
+   BOOST_TEST (testset1.incremental_rehash() == false);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+   //
+ //This incremental rehash should fail because the new size is not twice the original + BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should success because the new size is twice the original
+   //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should also success because the new size is half the original
+   //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+   //
+ //This incremental rehash should fail because the new size is not twice the original + BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should success because the new size is twice the original
+   //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should also success because the new size is half the original
+   //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //Full shrink rehash
+   testset1.rehash(bucket_traits(buckets1, 4));
+   BOOST_TEST (testset1.size() == values.size());
+   BOOST_TEST (testset1.incremental_rehash() == false);
+   {  int init_values [] = { 4, 5, 1, 2, 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Full shrink rehash again
+   testset1.rehash(bucket_traits(buckets1, 2));
+   BOOST_TEST (testset1.size() == values.size());
+   BOOST_TEST (testset1.incremental_rehash() == false);
+   {  int init_values [] = { 2, 2, 4, 3, 5, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Full growing rehash
+   testset1.rehash(bucket_traits(buckets1, BucketSize));
+   BOOST_TEST (testset1.size() == values.size());
+   BOOST_TEST (testset1.incremental_rehash() == false);
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Incremental rehash shrinking
+   //First incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket > 6; --split_bucket){
+      BOOST_TEST (testset1.incremental_rehash(false) == true);
+      BOOST_TEST(testset1.split_count() == (split_bucket-1));
+      {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+   //Incremental rehash step
+   BOOST_TEST (testset1.incremental_rehash(false) == true);
+   BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+   {  int init_values [] = { 5, 1, 2, 2, 3, 4 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Incremental rehash step 2
+   BOOST_TEST (testset1.incremental_rehash(false) == true);
+   BOOST_TEST(testset1.split_count() == (BucketSize/2));
+   {  int init_values [] = { 4, 5, 1, 2, 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+ //This incremental rehash should fail because we've reached the half of the bucket array
+   BOOST_TEST(testset1.incremental_rehash(false) == false);
+   BOOST_TEST(testset1.split_count() == BucketSize/2);
+   {  int init_values [] = { 4, 5, 1, 2, 2, 3 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+}
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental> + ::test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::false_)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
+   typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
+   typename unordered_multiset_type::bucket_type buckets2 [2];
+   typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
+
+ unordered_multiset_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
+   BOOST_TEST (testset1.size() == values.size());
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   testset1.rehash(bucket_traits(buckets2, 2));
+   BOOST_TEST (testset1.size() == values.size());
+   {  int init_values [] = { 4, 2, 2, 5, 3, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   testset1.rehash(bucket_traits(buckets3, BucketSize*2));
+   BOOST_TEST (testset1.size() == values.size());
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //Now rehash reducing the buckets
+   testset1.rehash(bucket_traits(buckets3, 2));
+   BOOST_TEST (testset1.size() == values.size());
+   {  int init_values [] = { 4, 2, 2, 5, 3, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //Now rehash increasing the buckets
+   testset1.rehash(bucket_traits(buckets3, BucketSize*2));
+   BOOST_TEST (testset1.size() == values.size());
+   {  int init_values [] = { 1, 2, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+}
+
+//test: find, equal_range (lower_bound, upper_bound):
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_find(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
+   typename unordered_multiset_type::bucket_type buckets[BucketSize];
+ unordered_multiset_type testset(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
+
+   typedef typename unordered_multiset_type::iterator iterator;
+
+   value_type cmp_val;
+   cmp_val.value_ = 2;
+   iterator i = testset.find (cmp_val);
+   BOOST_TEST (i->value_ == 2);
+   BOOST_TEST ((++i)->value_ == 2);
+   std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
+
+   BOOST_TEST (range.first->value_ == 2);
+   BOOST_TEST (range.second->value_ == 3);
+   BOOST_TEST (std::distance (range.first, range.second) == 2);
+
+   cmp_val.value_ = 7;
+   BOOST_TEST (testset.find (cmp_val) == testset.end());
+}
+
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+   ::test_clone(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_multiset
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_multiset_type;
+   typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+   {
+      //Test with equal bucket arrays
+      typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
+      typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
+ unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize)); + unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>()); + //Ordering is not guarantee in the cloning so insert data in a set and test
+      std::multiset<typename ValueTraits::value_type>
+         src(testset1.begin(), testset1.end());
+      std::multiset<typename ValueTraits::value_type>
+         dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+      testset2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testset2.empty());
+   }
+   {
+      //Test with bigger source bucket arrays
+ typename unordered_multiset_type::bucket_type buckets1 [BucketSize*2];
+      typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
+ unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize*2)); + unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>()); + //Ordering is not guarantee in the cloning so insert data in a set and test
+      std::multiset<typename ValueTraits::value_type>
+         src(testset1.begin(), testset1.end());
+      std::multiset<typename ValueTraits::value_type>
+         dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+      testset2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testset2.empty());
+   }
+   {
+      //Test with smaller source bucket arrays
+      typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
+ typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2]; + unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize)); + unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize*2));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>()); + //Ordering is not guaranteed in the cloning so insert data in a set and test
+      std::multiset<typename ValueTraits::value_type>
+         src(testset1.begin(), testset1.end());
+      std::multiset<typename ValueTraits::value_type>
+         dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+      testset2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testset2.empty());
+   }
+}
+
+template<class VoidPointer, bool constant_time_size, bool Incremental>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+      static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ std::vector<testvalue<hooks<VoidPointer> , constant_time_size> > data (6);
+      for (int i = 0; i < 6; ++i)
+         data[i].value_ = random_init[i];
+
+      test_unordered_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , true
+                , false
+                , Incremental
+                >::test_all(data);
+
+      test_unordered_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , false
+                , false
+                , Incremental
+                >::test_all(data);
+      return 0;
+   }
+};
+
+template<class VoidPointer, bool Incremental>
+class test_main_template<VoidPointer, false, Incremental>
+{
+   public:
+   int operator()()
+   {
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+      static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+      std::vector<testvalue<hooks<VoidPointer> , false> > data (6);
+      for (int i = 0; i < 6; ++i)
+         data[i].value_ = random_init[i];
+
+      test_unordered_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , false
+                , false
+                , Incremental
+                >::test_all(data);
+
+      test_unordered_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , true
+                , false
+                , Incremental
+                >::test_all(data);
+
+      test_unordered_multiset < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , false
+                , false
+                , Incremental
+                >::test_all(data);
+
+      test_unordered_multiset < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , false
+                , true
+                , Incremental
+                >::test_all(data);
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false, true>()();
+   test_main_template<smart_ptr<void>, false, true>()();
+   test_main_template<void*, true, true>()();
+   test_main_template<smart_ptr<void>, true, true>()();
+   test_main_template<void*, false, false>()();
+   test_main_template<smart_ptr<void>, false, false>()();
+   test_main_template<void*, true, true>()();
+   test_main_template<smart_ptr<void>, true, false>()();
+   return boost::report_errors();
+}
+
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/unordered_set_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,678 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <set>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+
+namespace boost { namespace intrusive { namespace test {
+
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
+#else
+template<class T, class ...Options>
+#endif
+struct is_unordered<boost::intrusive::unordered_set<T,
+   #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   O1, O2, O3, O4, O5, O6
+   #else
+   Options...
+   #endif
+> >
+{
+   static const bool value = true;
+};
+
+}}}
+
+using namespace boost::intrusive;
+
+struct my_tag;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef unordered_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+   typedef unordered_set_base_hook
+      < link_mode<auto_unlink>
+      , void_pointer<VoidPointer>
+      , tag<my_tag>
+      , store_hash<true>
+ > auto_base_hook_type;
+
+   typedef unordered_set_member_hook
+      < void_pointer<VoidPointer>
+      , optimize_multikey<true>
+ > member_hook_type;
+   typedef unordered_set_member_hook
+      < link_mode<auto_unlink>, void_pointer<VoidPointer>
+      , store_hash<true>
+      , optimize_multikey<true>
+ > auto_member_hook_type;
+};
+
+static const std::size_t BucketSize = 8;
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+struct test_unordered_set
+{
+   typedef typename ValueTraits::value_type value_type;
+   static void test_all(std::vector<value_type>& values);
+   static void test_sort(std::vector<value_type>& values);
+   static void test_insert(std::vector<value_type>& values);
+   static void test_swap(std::vector<value_type>& values);
+   static void test_rehash(std::vector<value_type>& values, detail::true_);
+ static void test_rehash(std::vector<value_type>& values, detail::false_);
+   static void test_find(std::vector<value_type>& values);
+   static void test_impl();
+   static void test_clone(std::vector<value_type>& values);
+};
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_all(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+   {
+      typename unordered_set_type::bucket_type buckets [BucketSize];
+      unordered_set_type testset(bucket_traits(buckets, BucketSize));
+      testset.insert(values.begin(), values.end());
+      test::test_container(testset);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+ test::test_common_unordered_and_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_unordered_associative_container(testset, values);
+      testset.clear();
+      testset.insert(values.begin(), values.end());
+      test::test_unique_container(testset, values);
+   }
+   test_sort(values);
+   test_insert(values);
+   test_swap(values);
+   test_rehash(values, detail::bool_<Incremental>());
+   test_find(values);
+   test_impl();
+   test_clone(values);
+}
+
+//test case due to an error in tree implementation:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::test_impl()
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+
+   std::vector<value_type> values (5);
+   for (int i = 0; i < 5; ++i)
+      values[i].value_ = i;
+
+   typename unordered_set_type::bucket_type buckets [BucketSize];
+   unordered_set_type testset(bucket_traits(buckets, BucketSize));
+   for (int i = 0; i < 5; ++i)
+      testset.insert (values[i]);
+
+   testset.erase (testset.iterator_to (values[0]));
+   testset.erase (testset.iterator_to (values[1]));
+   testset.insert (values[1]);
+   testset.erase (testset.iterator_to (values[2]));
+   testset.erase (testset.iterator_to (values[3]));
+}
+
+//test: constructor, iterator, clear, reverse_iterator, front, back, size:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_sort(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+
+   typename unordered_set_type::bucket_type buckets [BucketSize];
+ unordered_set_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
+   BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));
+
+   if(Incremental){
+      {  int init_values [] = { 4, 5, 1, 2, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+   else{
+      {  int init_values [] = { 1, 2, 3, 4, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+
+   testset1.clear();
+   BOOST_TEST (testset1.empty());
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_insert(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+
+   typename unordered_set_type::bucket_type buckets [BucketSize];
+   unordered_set_type testset(bucket_traits(buckets, BucketSize));
+   testset.insert(&values[0] + 2, &values[0] + 5);
+
+   const unordered_set_type& const_testset = testset;
+   if(Incremental)
+   {
+      {  int init_values [] = { 4, 5, 1 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() );  }
+      typename unordered_set_type::iterator i = testset.begin();
+      BOOST_TEST (i->value_ == 4);
+
+      i = testset.insert(values[0]).first;
+      BOOST_TEST (&*i == &values[0]);
+
+      i = testset.iterator_to (values[2]);
+      BOOST_TEST (&*i == &values[2]);
+
+      testset.erase (i);
+
+      {  int init_values [] = { 5, 1, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() );  }
+   }
+   else{
+      {  int init_values [] = { 1, 4, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() );  }
+      typename unordered_set_type::iterator i = testset.begin();
+      BOOST_TEST (i->value_ == 1);
+
+      i = testset.insert(values[0]).first;
+      BOOST_TEST (&*i == &values[0]);
+
+      i = testset.iterator_to (values[2]);
+      BOOST_TEST (&*i == &values[2]);
+
+      testset.erase (i);
+
+      {  int init_values [] = { 1, 3, 5 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() );  }
+   }
+}
+
+//test: insert (seq-version), swap, erase (seq-version), size:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_swap(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+
+   typename unordered_set_type::bucket_type buckets1 [BucketSize];
+   typename unordered_set_type::bucket_type buckets2 [BucketSize];
+ unordered_set_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets1, BucketSize));
+   unordered_set_type testset2(bucket_traits(buckets2, BucketSize));
+
+   testset2.insert (&values[0] + 2, &values[0] + 6);
+   testset1.swap (testset2);
+
+   if(Incremental){
+      {  int init_values [] = { 4, 5, 1, 2 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+      {  int init_values [] = { 2, 3 };
+         TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() );  }
+      testset1.erase (testset1.iterator_to(values[4]), testset1.end());
+      BOOST_TEST (testset1.size() == 1);
+      BOOST_TEST (&*testset1.begin() == &values[2]);
+   }
+   else{
+      {  int init_values [] = { 1, 2, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+      {  int init_values [] = { 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() );  }
+      testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+      BOOST_TEST (testset1.size() == 1);
+      BOOST_TEST (&*testset1.begin() == &values[3]);
+   }
+}
+
+//test: rehash:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>:: + test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::true_)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+   //Build a uset
+   typename unordered_set_type::bucket_type buckets1 [BucketSize];
+   typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
+ unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
+   //Test current state
+   BOOST_TEST(testset1.split_count() == BucketSize/2);
+   {  int init_values [] = { 4, 5, 1, 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Incremental rehash step
+   BOOST_TEST (testset1.incremental_rehash() == true);
+   BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+   {  int init_values [] = { 5, 1, 2, 3, 4 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Rest of incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket != BucketSize; ++split_bucket){
+      BOOST_TEST (testset1.incremental_rehash() == true);
+      BOOST_TEST(testset1.split_count() == (split_bucket+1));
+      {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+ //This incremental rehash should fail because we've reached the end of the bucket array
+   BOOST_TEST(testset1.incremental_rehash() == false);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+   //
+ //This incremental rehash should fail because the new size is not twice the original + BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should success because the new size is twice the original
+   //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should also success because the new size is half the original
+   //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+   //
+ //This incremental rehash should fail because the new size is not twice the original + BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should success because the new size is twice the original
+   //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+ //This incremental rehash should also success because the new size is half the original
+   //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+   BOOST_TEST(testset1.split_count() == BucketSize);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //Full shrink rehash
+   testset1.rehash(bucket_traits(buckets1, 4));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   BOOST_TEST (testset1.incremental_rehash() == false);
+   {  int init_values [] = { 4, 5, 1, 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Full shrink rehash again
+   testset1.rehash(bucket_traits(buckets1, 2));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   BOOST_TEST (testset1.incremental_rehash() == false);
+   {  int init_values [] = { 2, 4, 3, 5, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Full growing rehash
+   testset1.rehash(bucket_traits(buckets1, BucketSize));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   BOOST_TEST (testset1.incremental_rehash() == false);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Incremental rehash shrinking
+   //First incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket > 6; --split_bucket){
+      BOOST_TEST (testset1.incremental_rehash(false) == true);
+      BOOST_TEST(testset1.split_count() == (split_bucket-1));
+      {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   }
+   //Incremental rehash step
+   BOOST_TEST (testset1.incremental_rehash(false) == true);
+   BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+   {  int init_values [] = { 5, 1, 2, 3, 4 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+   //Incremental rehash step 2
+   BOOST_TEST (testset1.incremental_rehash(false) == true);
+   BOOST_TEST(testset1.split_count() == (BucketSize/2));
+   {  int init_values [] = { 4, 5, 1, 2, 3 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+ //This incremental rehash should fail because we've reached the half of the bucket array
+   BOOST_TEST(testset1.incremental_rehash(false) == false);
+   BOOST_TEST(testset1.split_count() == BucketSize/2);
+   {  int init_values [] = { 4, 5, 1, 2, 3 };
+   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+}
+
+//test: rehash:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>:: + test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::false_)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+
+   typename unordered_set_type::bucket_type buckets1 [BucketSize];
+   typename unordered_set_type::bucket_type buckets2 [2];
+   typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
+
+ unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   testset1.rehash(bucket_traits(buckets2, 2));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   {  int init_values [] = { 4, 2, 5, 3, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   testset1.rehash(bucket_traits(buckets3, BucketSize*2));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //Now rehash reducing the buckets
+   testset1.rehash(bucket_traits(buckets3, 2));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   {  int init_values [] = { 4, 2, 5, 3, 1 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+
+   //Now rehash increasing the buckets
+   testset1.rehash(bucket_traits(buckets3, BucketSize*2));
+   BOOST_TEST (testset1.size() == values.size()-1);
+   {  int init_values [] = { 1, 2, 3, 4, 5 };
+      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }
+}
+
+
+//test: find, equal_range (lower_bound, upper_bound):
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental> +void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+   test_find(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+
+   typename unordered_set_type::bucket_type buckets [BucketSize];
+ unordered_set_type testset (values.begin(), values.end(), bucket_traits(buckets, BucketSize));
+   typedef typename unordered_set_type::iterator iterator;
+
+   value_type cmp_val;
+   cmp_val.value_ = 2;
+   iterator i = testset.find (cmp_val);
+   BOOST_TEST (i->value_ == 2);
+   BOOST_TEST ((++i)->value_ != 2);
+   std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
+
+   BOOST_TEST (range.first->value_ == 2);
+   BOOST_TEST (range.second->value_ == 3);
+   BOOST_TEST (std::distance (range.first, range.second) == 1);
+
+   cmp_val.value_ = 7;
+   BOOST_TEST (testset.find (cmp_val) == testset.end());
+}
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>
+   ::test_clone(std::vector<typename ValueTraits::value_type>& values)
+{
+   typedef typename ValueTraits::value_type value_type;
+   typedef unordered_set
+      <value_type
+      , value_traits<ValueTraits>
+      , constant_time_size<value_type::constant_time_size>
+      , cache_begin<CacheBegin>
+      , compare_hash<CompareHash>
+      , incremental<Incremental>
+      > unordered_set_type;
+   typedef typename unordered_set_type::bucket_traits bucket_traits;
+   {
+      //Test with equal bucket arrays
+      typename unordered_set_type::bucket_type buckets1 [BucketSize];
+      typename unordered_set_type::bucket_type buckets2 [BucketSize];
+ unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
+      unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>()); + //Ordering is not guarantee in the cloning so insert data in a set and test
+      std::set<typename ValueTraits::value_type>
+         src(testset1.begin(), testset1.end());
+      std::set<typename ValueTraits::value_type>
+         dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+      testset2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testset2.empty());
+   }
+   {
+      //Test with bigger source bucket arrays
+      typename unordered_set_type::bucket_type buckets1 [BucketSize*2];
+      typename unordered_set_type::bucket_type buckets2 [BucketSize];
+ unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize*2));
+      unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>()); + //Ordering is not guaranteed in the cloning so insert data in a set and test
+      std::set<typename ValueTraits::value_type>
+         src(testset1.begin(), testset1.end());
+      std::set<typename ValueTraits::value_type>
+         dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+      testset2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testset2.empty());
+   }
+   {
+      //Test with smaller source bucket arrays
+      typename unordered_set_type::bucket_type buckets1 [BucketSize];
+      typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
+ unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
+      unordered_set_type testset2 (bucket_traits(buckets2, BucketSize*2));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>()); + //Ordering is not guarantee in the cloning so insert data in a set and test
+      std::set<typename ValueTraits::value_type>
+         src(testset1.begin(), testset1.end());
+      std::set<typename ValueTraits::value_type>
+         dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+      testset2.clear_and_dispose(test::delete_disposer<value_type>());
+      BOOST_TEST (testset2.empty());
+   }
+}
+
+template<class VoidPointer, bool constant_time_size, bool incremental>
+class test_main_template
+{
+   public:
+   int operator()()
+   {
+ typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
+      static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ std::vector<testvalue<hooks<VoidPointer> , constant_time_size> > data (6);
+      for (int i = 0; i < 6; ++i)
+         data[i].value_ = random_init[i];
+
+      test_unordered_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , true
+                , false
+                , incremental
+                >::test_all(data);
+      test_unordered_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , false
+                , false
+                , incremental
+                >::test_all(data);
+
+      return 0;
+   }
+};
+
+template<class VoidPointer, bool incremental>
+class test_main_template<VoidPointer, false, incremental>
+{
+   public:
+   int operator()()
+   {
+      typedef testvalue<hooks<VoidPointer> , false> value_type;
+      static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+      std::vector<testvalue<hooks<VoidPointer> , false> > data (6);
+      for (int i = 0; i < 6; ++i)
+         data[i].value_ = random_init[i];
+
+      test_unordered_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::base_hook_type
+                  >::type
+                , true
+                , false
+                , incremental
+                >::test_all(data);
+
+      test_unordered_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+                               , &value_type::node_
+                               >
+                  >::type
+                , false
+                , false
+                , incremental
+                >::test_all(data);
+
+      test_unordered_set < typename detail::get_base_value_traits
+                  < value_type
+                  , typename hooks<VoidPointer>::auto_base_hook_type
+                  >::type
+                , false
+                , true
+                , incremental
+                >::test_all(data);
+
+      test_unordered_set < typename detail::get_member_value_traits
+                  < value_type
+                  , member_hook< value_type
+ , typename hooks<VoidPointer>::auto_member_hook_type
+                               , &value_type::auto_node_
+                               >
+                  >::type
+                , false
+                , true
+                , incremental
+                >::test_all(data);
+      return 0;
+   }
+};
+
+int main( int, char* [] )
+{
+   test_main_template<void*, false, true>()();
+   test_main_template<smart_ptr<void>, false, true>()();
+   test_main_template<void*, true, true>()();
+   test_main_template<smart_ptr<void>, true, true>()();
+   test_main_template<void*, false, false>()();
+   test_main_template<smart_ptr<void>, false, false>()();
+   test_main_template<void*, true, true>()();
+   test_main_template<smart_ptr<void>, true, false>()();
+   return boost::report_errors();
+}
+#include <boost/intrusive/detail/config_end.hpp>
=======================================
--- /dev/null
+++ /trunk/libs/intrusive/test/virtual_base_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,85 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+struct VirtualBase
+{
+   virtual ~VirtualBase(){}
+};
+
+struct VirtualBase2
+{
+   virtual ~VirtualBase2(){}
+};
+
+struct VirtualBase3
+{
+};
+
+class NonVirtualBase
+   :  public virtual VirtualBase
+   ,  public virtual VirtualBase2
+{
+   public:
+   int dummy[10];
+};
+
+class MyClass
+   :  public NonVirtualBase
+   ,  public virtual VirtualBase3
+{
+   int int_;
+   public:
+   list_member_hook<> list_hook_;
+   MyClass(int i = 0)
+      :  int_(i)
+   {}
+};
+
+//Define a list that will store MyClass using the public base hook
+typedef member_hook< MyClass, list_member_hook<>, &MyClass::list_hook_ > MemberHook;
+typedef list<MyClass, MemberHook> List;
+
+int main()
+{
+   typedef std::vector<MyClass>::iterator VectIt;
+   typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+   //Create several MyClass objects, each one with a different value
+   std::vector<MyClass> values;
+   for(int i = 0; i < 100; ++i)  values.push_back(MyClass(i));
+
+   List  my_list;
+
+   //Now insert them in the reverse order
+   //in the base hook intrusive list
+   for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
+      my_list.push_front(*it);
+
+   //Now test lists
+   {
+      List::const_iterator  list_it(my_list.cbegin());
+      VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+
+      //Test the objects inserted in the base hook list
+      for(; vect_it != vect_itend; ++vect_it, ++list_it)
+         if(&*list_it  != &*vect_it)   return 1;
+   }
+
+   return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/iostreams/test/deprecated_file_descriptor_test.cpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,243 @@
+// (C) Copyright 2010 Daniel James
+// 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.)
+
+#include <boost/iostreams/device/file_descriptor.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/test/unit_test.hpp>
+#include "detail/temp_file.hpp"
+#include "detail/verification.hpp"
+#include "detail/file_handle.hpp"
+
+// Test file_descriptor with the depreacted constructors.
+
+namespace boost_ios = boost::iostreams;
+namespace ios_test = boost::iostreams::test;
+
+template <class FileDescriptor>
+void file_handle_test_impl(FileDescriptor*)
+{
+    ios_test::test_file  test1;
+    ios_test::test_file  test2;
+
+ //--------------Deprecated file descriptor constructor--------------------//
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        {
+            FileDescriptor device1(handle);
+            BOOST_CHECK(device1.handle() == handle);
+        }
+        BOOST_CHECK_HANDLE_OPEN(handle);
+        ios_test::close_file_handle(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        {
+            FileDescriptor device1(handle, false);
+            BOOST_CHECK(device1.handle() == handle);
+        }
+        BOOST_CHECK_HANDLE_OPEN(handle);
+        ios_test::close_file_handle(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        {
+            FileDescriptor device1(handle, true);
+            BOOST_CHECK(device1.handle() == handle);
+        }
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        FileDescriptor device1(handle);
+        BOOST_CHECK(device1.handle() == handle);
+        device1.close();
+        BOOST_CHECK(!device1.is_open());
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        FileDescriptor device1(handle, false);
+        BOOST_CHECK(device1.handle() == handle);
+        device1.close();
+        BOOST_CHECK(!device1.is_open());
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        FileDescriptor device1(handle, true);
+        BOOST_CHECK(device1.handle() == handle);
+        device1.close();
+        BOOST_CHECK(!device1.is_open());
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+ //--------------Deprecated file descriptor open---------------------------//
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        {
+            FileDescriptor device1;
+            device1.open(handle);
+            BOOST_CHECK(device1.handle() == handle);
+        }
+        BOOST_CHECK_HANDLE_OPEN(handle);
+        ios_test::close_file_handle(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        {
+            FileDescriptor device1;
+            device1.open(handle, false);
+            BOOST_CHECK(device1.handle() == handle);
+        }
+        BOOST_CHECK_HANDLE_OPEN(handle);
+        ios_test::close_file_handle(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        {
+            FileDescriptor device1;
+            device1.open(handle, true);
+            BOOST_CHECK(device1.handle() == handle);
+        }
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        FileDescriptor device1;
+        device1.open(handle);
+        BOOST_CHECK(device1.handle() == handle);
+        device1.close();
+        BOOST_CHECK(!device1.is_open());
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        FileDescriptor device1;
+        device1.open(handle, false);
+        BOOST_CHECK(device1.handle() == handle);
+        device1.close();
+        BOOST_CHECK(!device1.is_open());
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+    {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+        FileDescriptor device1;
+        device1.open(handle, true);
+        BOOST_CHECK(device1.handle() == handle);
+        device1.close();
+        BOOST_CHECK(!device1.is_open());
+        BOOST_CHECK_HANDLE_CLOSED(handle);
+    }
+
+ //--------------Deprecated open with existing descriptor------------------//
+
+    {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name()); + boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+        {
+            FileDescriptor device1(handle1);
+            BOOST_CHECK(device1.handle() == handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+            device1.open(handle2);
+            BOOST_CHECK(device1.handle() == handle2);
+            BOOST_CHECK_HANDLE_OPEN(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+            device1.close();
+            BOOST_CHECK_HANDLE_OPEN(handle1);
+            BOOST_CHECK_HANDLE_CLOSED(handle2);
+        }
+        BOOST_CHECK_HANDLE_OPEN(handle1);
+        BOOST_CHECK_HANDLE_CLOSED(handle2);
+
+        ios_test::close_file_handle(handle1);
+    }
+
+    {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name()); + boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+        {
+            FileDescriptor device1(handle1, true);
+            BOOST_CHECK(device1.handle() == handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+            device1.open(handle2);
+            BOOST_CHECK(device1.handle() == handle2);
+            BOOST_CHECK_HANDLE_CLOSED(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+            device1.close();
+            BOOST_CHECK_HANDLE_CLOSED(handle1);
+            BOOST_CHECK_HANDLE_CLOSED(handle2);
+        }
+        BOOST_CHECK_HANDLE_CLOSED(handle1);
+        BOOST_CHECK_HANDLE_CLOSED(handle2);
+    }
+
+    {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name()); + boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+        {
+            FileDescriptor device1(handle1, false);
+            BOOST_CHECK(device1.handle() == handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+            device1.open(handle2, false);
+            BOOST_CHECK(device1.handle() == handle2);
+            BOOST_CHECK_HANDLE_OPEN(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+        }
+        BOOST_CHECK_HANDLE_OPEN(handle1);
+        BOOST_CHECK_HANDLE_OPEN(handle2);
+
+        ios_test::close_file_handle(handle1);
+        ios_test::close_file_handle(handle2);
+    }
+
+    {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name()); + boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+        {
+            FileDescriptor device1(handle1, true);
+            BOOST_CHECK(device1.handle() == handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+            device1.open(handle2, true);
+            BOOST_CHECK(device1.handle() == handle2);
+            BOOST_CHECK_HANDLE_CLOSED(handle1);
+            BOOST_CHECK_HANDLE_OPEN(handle2);
+        }
+        BOOST_CHECK_HANDLE_CLOSED(handle1);
+        BOOST_CHECK_HANDLE_CLOSED(handle2);
+    }
+}
+
+void deprecated_file_descriptor_test()
+{
+    file_handle_test_impl((boost_ios::file_descriptor*) 0);
+    file_handle_test_impl((boost_ios::file_descriptor_sink*) 0);
+    file_handle_test_impl((boost_ios::file_descriptor_source*) 0);
+}
+
+boost::unit_test::test_suite* init_unit_test_suite(int, char* [])
+{
+ boost::unit_test::test_suite* test = BOOST_TEST_SUITE("deprecated file_descriptor test");
+    test->add(BOOST_TEST_CASE(&deprecated_file_descriptor_test));
+    return test;
+}
=======================================
--- /dev/null
+++ /trunk/libs/iostreams/test/detail/file_handle.hpp Mon Aug 23 23:00:26 2010
@@ -0,0 +1,108 @@
+// (C) Copyright 2010 Daniel James
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// A few methods for getting and manipulating file handles.
+
+#ifndef BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
+#define BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
+
+#include <boost/iostreams/detail/file_handle.hpp>
+#include <boost/iostreams/detail/config/rtl.hpp>
+#include <boost/test/test_tools.hpp>
+#include <string>
+
+#ifdef BOOST_IOSTREAMS_WINDOWS
+# include <io.h>         // low-level file i/o.
+# define WINDOWS_LEAN_AND_MEAN
+# include <windows.h>
+#else
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
+namespace boost { namespace iostreams { namespace test {
+
+#ifdef BOOST_IOSTREAMS_WINDOWS
+
+// Windows implementation
+
+boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
+{
+    HANDLE handle =
+        ::CreateFileA( name.c_str(),
+                       GENERIC_READ | GENERIC_WRITE,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE,
+                       NULL,                   // lpSecurityAttributes
+                       OPEN_EXISTING,
+                       FILE_ATTRIBUTE_NORMAL,
+                       NULL );                 // hTemplateFile
+
+    BOOST_REQUIRE (handle != INVALID_HANDLE_VALUE);
+    return handle;
+}
+
+void close_file_handle(boost::iostreams::detail::file_handle handle)
+{
+    BOOST_REQUIRE(::CloseHandle(handle) == 1);
+}
+
+#define BOOST_CHECK_HANDLE_CLOSED(handle)
+#define BOOST_CHECK_HANDLE_OPEN(handle)
+
+#else // BOOST_IOSTREAMS_WINDOWS
+
+// Non-windows implementation
+
+boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
+{
+    int oflag = O_RDWR;
+
+    #ifdef _LARGEFILE64_SOURCE
+        oflag |= O_LARGEFILE;
+    #endif
+
+    // Calculate pmode argument to open.
+
+    mode_t pmode = S_IRUSR | S_IWUSR |
+                   S_IRGRP | S_IWGRP |
+                   S_IROTH | S_IWOTH;
+
+        // Open file.
+
+    int fd = BOOST_IOSTREAMS_FD_OPEN(name.c_str(), oflag, pmode);
+    BOOST_REQUIRE (fd != -1);
+
+    return fd;
+}
+
+void close_file_handle(boost::iostreams::detail::file_handle handle)
+{
+    BOOST_REQUIRE(BOOST_IOSTREAMS_FD_CLOSE(handle) != -1);
+}
+
+// This is pretty dubious. First you must make sure that no other
+// operations that could open a descriptor are called before this
+// check, otherwise it's quite likely that a closed descriptor
+// could be used. Secondly, I'm not sure if it's guaranteed that
+// fcntl will know that the descriptor is closed but this seems
+// to work okay, and I can't see any other convenient way to check
+// that a descripter has been closed.
+bool is_handle_open(boost::iostreams::detail::file_handle handle)
+{
+    return ::fcntl(handle, F_GETFD) != -1;
+}
+
+#define BOOST_CHECK_HANDLE_CLOSED(handle) \
+    BOOST_CHECK(!::boost::iostreams::test::is_handle_open(handle))
+#define BOOST_CHECK_HANDLE_OPEN(handle) \
+    BOOST_CHECK(::boost::iostreams::test::is_handle_open(handle))
+
+
+#endif // BOOST_IOSTREAMS_WINDOWS
+
+}}}
+
+#endif // BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
=======================================
--- /dev/null
+++ /trunk/libs/iterator/doc/Jamfile.v2 Mon Aug 23 23:00:26 2010
@@ -0,0 +1,23 @@
+# Copyright Thomas Witt 2005. Use, modification, and distribution are
+# subject to the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+using quickbook ;
+
+xml iterator
+  :
+    quickbook/iterator.qbk
+  ;
+
+boostbook standalone
+  :
+    iterator
+  :
+    <xsl:param>boost.root=../../../..
+    <xsl:param>toc.max.depth=3
+    <xsl:param>toc.section.depth=3
+    <xsl:param>chunk.section.depth=4
+ <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/iterator/doc
+  ;
+
+
=======================================
--- /trunk/libs/iostreams/doc/concepts/multi-character.html Thu Sep 4 19:12:45 2008
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<HTML>
-<HEAD>
-    <TITLE>Mutli-Character Filter</TITLE>
-    <LINK REL="stylesheet" HREF="../../../../boost.css">
-    <LINK REL="stylesheet" HREF="../theme/iostreams.css">
-</HEAD>
-<BODY>
-
-<!-- Begin Banner -->
-
-    <H1 CLASS="title">Mutli-Character Filter</H1>
-    <HR CLASS="banner">
-
-<!-- End Banner -->
-
-<H2>Description</H2>
-
-<P><A HREF="filter.html">Filter</A> which provides access to its controlled sequence or sequences <I>via</I> a socket-like interface rather than one character at a time. The difference between a Filter which is Mutli-Character and one which is not is reflected in the specifications of the various Filter refinements. <I>See</I>, <I>e.g.</I>, <A HREF="input_filter.html">InputFilter</A> and <A HREF="output_filter.html">OutputFilter</A>.</P>
-
-<H2>Refinement of</H2>
-
-<P><A HREF="filter.html">Filter</A>.</P>
-
-<A NAME="types"></A>
-<H2>Associated Types</H2>
-
-<P>Same as <A HREF="filter.html#types">Filter</A>, with the following additional requirements:</P>
-
-<TABLE CELLPADDING="5" BORDER="1">
- <TR><TD>Category</TD><TD>A type convertible to <A HREF="../guide/traits.html#category_tags">filter_tag</A> and to <A HREF="../guide/traits.html#category_tags">multichar_tag</A></TD></TR>
-</TABLE>
-
-<A NAME="expressions"></A>
-<H2>Valid Expressions / Semantics</H2>
-
-<P>Same as <A HREF="filter.html">Filter</A>.</P>
-
-<H2>Models</H2>
-
-<UL>
-    <LI>The compression and decompression filters</A>
- <LI><A HREF="../classes/regex_filter.html"><CODE>basic_regex_filter</CODE></A> - <LI><A HREF="../classes/aggregate.html"><CODE>aggregate_filter</CODE></A> - <LI><A HREF="../classes/symmetric_filter.html"><CODE>symmetric_filter</CODE></A>
-</UL>
-
-<!-- Begin Footer -->
-
-<HR>
-<P CLASS="copyright">Revised
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
-20 May, 2004
-<!--webbot bot="Timestamp" endspan i-checksum="38504" -->
-</P>
-
-<P CLASS="copyright">&copy; Copyright Jonathan Turkanis, 2004</P>
-<P CLASS="copyright">
- Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at <A HREF="http://www.boost.org/LICENSE_1_0.txt";>http://www.boost.org/LICENSE_1_0.txt</A>)
-</P>
-
-<!-- End Footer -->
-
-</BODY>
=======================================
--- /trunk/libs/graph/doc/AStarVisitor.html     Mon Sep  7 09:29:57 2009
+++ /trunk/libs/graph/doc/AStarVisitor.html     Mon Aug 23 23:00:26 2010
@@ -42,7 +42,7 @@

 <tr>
 <td><tt>g</tt></td>
-<td>一个类型为 <tt>G</tt> 的对象。</td>
+<td>一个类型为&nbsp;<tt>const G&amp;</tt><tt></tt> 的对象。</td>
 </tr>

 <tr>
=======================================
--- /trunk/libs/graph/doc/adjacency_list.html   Mon Sep  7 09:29:57 2009
+++ /trunk/libs/graph/doc/adjacency_list.html   Mon Aug 23 23:00:26 2010
@@ -475,7 +475,9 @@
 <hr>


-<pre>std::pair&lt;edge_descriptor, bool&gt;<br>edge(vertex_descriptor&nbsp;u, vertex_descriptor&nbsp;v,<br> const&nbsp;adjacency_list&amp;&nbsp;g)<br></pre>返回图 <tt>g</tt> 中连接顶 点 <tt>u</tt>&nbsp;和 <tt>v</tt>&nbsp;的一条边。 +<pre>std::pair&lt;edge_descriptor, bool&gt;<br>edge(vertex_descriptor&nbsp;u, vertex_descriptor&nbsp;v,<br> const&nbsp;adjacency_list&amp;&nbsp;g)<br></pre>如果存在一条从顶点 <tt>u</tt> 到顶点 <tt>v</tt> 的边,则返回一个包含该边及 <tt>true</tt> 的 pair. 如果在
+<tt>u</tt> 和 <tt>v</tt> 之间没有边,则返回一个包含一个任意的边描述符及
+<tt>false</tt> 的 pair.

 <hr>

=======================================
--- /trunk/libs/graph/doc/astar_search.html     Mon Feb  8 01:01:45 2010
+++ /trunk/libs/graph/doc/astar_search.html     Mon Aug 23 23:00:26 2010
@@ -22,16 +22,25 @@

 <P>
 <PRE>
-<i>// Named parameter interface</i>
+<i>// Named parameter interfaces</i>
 template &lt;typename VertexListGraph,
           typename AStarHeuristic,
           typename P, typename T, typename R&gt;
 void
 astar_search
-  (VertexListGraph &amp;g,
+  (const VertexListGraph &amp;g,
    typename graph_traits&lt;VertexListGraph&gt;::vertex_descriptor s,
<a href="AStarHeuristic.html">AStarHeuristic</a> h, const bgl_named_params&lt;P, T, R&gt;&amp; params);

+template &lt;typename VertexListGraph,
+          typename AStarHeuristic,
+          typename P, typename T, typename R&gt;
+void
+astar_search_no_init
+  (const VertexListGraph &amp;g,
+   typename graph_traits&lt;VertexListGraph&gt;::vertex_descriptor s,
+ <a href="AStarHeuristic.html">AStarHeuristic</a> h, const bgl_named_params&lt;P, T, R&gt;&amp; params);
+
 <i>// Non-named parameter interface</i>
 template &lt;typename VertexListGraph, typename AStarHeuristic,
typename <a href="AStarVisitor.html">AStarVisitor</a>, typename PredecessorMap,
@@ -42,7 +51,7 @@
           typename CostInf, typename CostZero&gt;
 inline void
 astar_search
-  (VertexListGraph &amp;g,
+  (const VertexListGraph &amp;g,
    typename graph_traits&lt;VertexListGraph&gt;::vertex_descriptor s,
    AStarHeuristic h, AStarVisitor vis,
    PredecessorMap predecessor, CostMap cost,
@@ -52,7 +61,7 @@
    CostInf inf, CostZero zero);

<i>// Version that does not initialize property maps (used for implicit graphs)</i>
-template &lt;typename VertexListGraph, typename AStarHeuristic,
+template &lt;typename IncidenceGraph, typename AStarHeuristic,
typename <a href="AStarVisitor.html">AStarVisitor</a>, typename PredecessorMap,
           typename CostMap, typename DistanceMap,
           typename WeightMap, typename ColorMap,
@@ -61,8 +70,8 @@
           typename CostInf, typename CostZero&gt;
 inline void
 astar_search_no_init
-  (VertexListGraph &amp;g,
-   typename graph_traits&lt;VertexListGraph&gt;::vertex_descriptor s,
+  (const IncidenceGraph &amp;g,
+   typename graph_traits&lt;IncidenceGraph&gt;::vertex_descriptor s,
    AStarHeuristic h, AStarVisitor vis,
    PredecessorMap predecessor, CostMap cost,
    DistanceMap distance, WeightMap weight,
@@ -71,7 +80,8 @@
    CostInf inf, CostZero zero);

 <b>Note that the index_map and color parameters are swapped in
-astar_search_no_init relative to astar_search.</b>
+astar_search_no_init() relative to astar_search(); the named parameter
+interfaces are not affected.</b>
 </PRE>

 <P>
@@ -110,14 +120,17 @@
 Implicit graphs are graphs that are not completely known at the
 beginning of the search.  Upon visiting a vertex, its neighbors are
 "generated" and added to the search.  Implicit graphs are particularly
-useful for searching large state spaces -- in gameplaying scenarios
+useful for searching large state spaces -- in game-playing scenarios
 (e.g. chess), for example -- in which it may not be possible to store
 the entire graph.  Implicit searches can be performed with this
 implementation of A* by creating special visitors that generate
 neighbors of newly-expanded vertices.  Please note that
 <tt>astar_search_no_init()</tt> must be used for implicit graphs; the basic
 <tt>astar_search()</tt> function requires a graph that models
-<a href="VertexListGraph.html"><tt>VertexListGraph</tt></a>.
+the <a href="VertexListGraph.html">Vertex List Graph</a> concept.  Both
+versions
+also require the graph type to model the <a
+href="IncidenceGraph.html">Incidence Graph</a> concept.
 </P>

 <P>
@@ -228,14 +241,23 @@

 <h3>Parameters</h3>

-IN: <tt>VertexListGraph&amp; g</tt>
+IN: <tt>const VertexListGraph&amp; g</tt>
 <blockquote>
-  The graph object on which the algorithm will be applied.  The type
+ The graph object on which the algorithm will be applied for <tt>astar_search()</tt>. The type
   <tt>VertexListGraph</tt> must be a model of the <a
   href="VertexListGraph.html">
-  Vertex List Graph</a> concept.
+ Vertex List Graph</a> and <a href="IncidenceGraph.html">Incidence Graph</a>
+  concepts.
 </blockquote>

+IN: <tt>const IncidenceGraph&amp; g</tt>
+<blockquote>
+ The graph object on which the algorithm will be applied for <tt>astar_search_no_init()</tt>. The type
+  <tt>IncidenceGraph</tt> must be a model of the
+  <a href="IncidenceGraph.html">Incidence Graph</a>
+  concept.
+</blockquote>
+
 IN: <tt>vertex_descriptor s</tt>
 <blockquote>
   The start vertex for the search.  All distances will be calculated
@@ -281,7 +303,7 @@
   <b>Default:</b> <tt>get(vertex_index, g)</tt>.
    Note: if you use this default, make sure your graph has
    an internal <tt>vertex_index</tt> property. For example,
-   <tt>adjacenty_list</tt> with <tt>VertexList=listS</tt> does
+   <tt>adjacency_list</tt> with <tt>VertexList=listS</tt> does
    not have an internal <tt>vertex_index</tt> property.
 </blockquote>

@@ -318,8 +340,8 @@
href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html";><tt>StrictWeakOrdering</tt></a>
   provided by the <tt>compare</tt> function object.<br>

-  <b>Default:</b> <tt>iterator_property_map</tt> created from a
-  <tt>std::vector</tt> with the same value type as the
+  <b>Default:</b> <tt>shared_array_property_map</tt>
+  with the same value type as the
   <tt>WeightMap</tt>, and of size <tt>num_vertices(g)</tt>, and using
   the <tt>i_map</tt> for the index map.
 </blockquote>
@@ -344,9 +366,9 @@
   for this map must be the same as the value type for the distance
   map.<br>

-  <b>Default:</b> <tt>iterator_property_map</tt> created from a
-  <tt>std::vector</tt> with the same value type as the
-  <tt>WeightMap</tt>, and of size <tt>num_vertices(g)</tt>, and using
+  <b>Default:</b> <tt>shared_array_property_map</tt>
+  with the same value type as the
+  <tt>DistanceMap</tt>, and of size <tt>num_vertices(g)</tt>, and using
   the <tt>i_map</tt> for the index map.
 </blockquote>

@@ -366,10 +388,10 @@
   key type of the map, and the value type of the map must be a model
   of <a href="./ColorValue.html"><tt>Color Value</tt></a>.<br>

-  <b>Default:</b> <tt>iterator_property_map</tt> created from a
-  <tt>std::vector</tt> of value type <tt>default_color_type</tt>, with
-  size <tt>num_vertices(g)</tt>, and using the <tt>i_map</tt> for the
-  index map.
+  <b>Default:</b> <tt>shared_array_property_map</tt>
+  of value type <tt>default_color_type</tt>, with size
+  <tt>num_vertices(g)</tt>, and using
+  the <tt>i_map</tt> for the index map.
 </blockquote>

 IN: <tt>distance_compare(CompareFunction cmp)</tt>
@@ -461,7 +483,7 @@
   is invoked on each out-edge of a vertex immediately after it is
   examined.
 <li><b><tt>vis.edge_relaxed(e, g)</tt></b>
-  is invoked on edge <i>(u,v)</i> if <i>d[u] + w(u,v) < d[v]</i>.
+  is invoked on edge <i>(u,v)</i> if <i>d[u] + w(u,v) &lt; d[v]</i>.
 <li><b><tt>vis.edge_not_relaxed(e, g)</tt></b>
   is invoked if the edge is not relaxed (see above).
 <li><b><tt>vis.black_target(e, g)</tt></b>
=======================================
--- /trunk/libs/graph/doc/bibliography.html     Mon Sep  7 09:29:57 2009
+++ /trunk/libs/graph/doc/bibliography.html     Mon Aug 23 23:00:26 2010
@@ -352,7 +352,7 @@
 <p></p><dt><a name="fruchterman91">58</a>
 <dd>T. Fruchterman and E. Reingold<br>
   <em>Graph drawing by force-directed placement.</em><br>
-Software--Practice & Experience, 21 (11), pp. 1129-1164, 1991.
+Software--Practice &amp; Experience, 21 (11), pp. 1129-1164, 1991.

 <p></p><dt><a name="coleman83">59</a>
 <dd>Thomas F. Coleman and Jorge J. More<br>
@@ -409,7 +409,7 @@
 <p></p><dt><a name="boykov-kolmogorov04">69</a>
   <dd>Yuri Boykov and Vladimir Kolmogorov<br>
<em><a href="http://www.csd.uwo.ca/faculty/yuri/Abstracts/pami04-abs.html";>An Experimental Comparison of Min-Cut/Max-Flow Algorithms for Energy Minimization in Vision</a></em><br> - In IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 26, no. 9, pp. 1124-1137, Sept. 2004. + In <em>IEEE Transactions on Pattern Analysis and Machine Intelligence</em>, vol. 26, no. 9, pp. 1124-1137, Sept. 2004.

 <p></p><dt><a name="boyermyrvold04">70</a>
 <dd>John M. Boyer and Wendy J. Myrvold<br>
@@ -432,6 +432,12 @@
 </em><br>
 Combinatorica 10: 41-51, 1990.

+<P></P><DT><A NAME="wilson96generating">73</A>
+<DD>
+David&nbsp;Bruce&nbsp;Wilson
+<BR><em>Generating random spanning trees more quickly than the cover time</em>.
+ACM Symposium on the Theory of Computing, pp. 296-303, 1996.
+
 </dl>

 <br>
=======================================
--- /trunk/libs/graph/doc/edmonds_karp_max_flow.html Mon Sep 7 09:29:57 2009 +++ /trunk/libs/graph/doc/edmonds_karp_max_flow.html Mon Aug 23 23:00:26 2010
@@ -35,7 +35,7 @@
</p><p>该算法归功于 <a href="./bibliography.html#edmonds72:_improvements_netflow">Edmonds 和 Karp</a>,虽然我们在 <a href="bibliography.html#ahuja93:_network_flows">网 络流</a> 中会用另一个名称 "标签函数"。

-</p><p>该算法为最大流问题的解答提供了一个非常简单和容易的实现。但是,有几个 原因令到本算法不如 <a href="./push_relabel_max_flow.html"><tt>push_relabel_max_flow()</tt></a> 或 <a href="./kolmogorov_max_flow.html"><tt>kolmogorov_max_flow()</tt></a> 算法 好。 +</p><p>该算法为最大流问题的解答提供了一个非常简单和容易的实现。但是,有几个 原因令到本算法不如 <a href="./push_relabel_max_flow.html"><tt>push_relabel_max_flow()</tt></a> 或 <a href="./boykov_kolmogorov_max_flow.html"><tt>boykov_kolmogorov_max_flow()</tt></a>&nbsp;算 法好。

 </p><ul>
   <li>在非整数容量的情形下,时间复杂度为 <i>O(V
@@ -115,8 +115,8 @@

 <h3>See Also 参见</h3>

-<a href="./push_relabel_max_flow.html"><tt>push_relabel_max_flow()</tt></a><br>
-<a href="./kolmogorov_max_flow.html"><tt>kolmogorov_max_flow()</tt></a>.
+<a href="./push_relabel_max_flow.html"><tt>push_relabel_max_flow()</tt><br>
+</a><a href="./boykov_kolmogorov_max_flow.html"><tt>boykov_kolmogorov_max_flow()</tt></a>.

 <br>
 <hr>
=======================================
--- /trunk/libs/graph/doc/graph_concepts.html   Mon Feb  8 01:01:45 2010
+++ /trunk/libs/graph/doc/graph_concepts.html   Mon Aug 23 23:00:26 2010
@@ -21,7 +21,7 @@

</p><p>BGL接口不是作为单一的图的概念出现的。相反,它被分解为小得多的碎片。 其原因在于,概念的目的是概括某些特定算法的要求。任何一个算法 都不需要所有类型的图操作,通常只需要其中一个小的子集。此外,有许多图数据结 构不能为所有操作提供高效的实现,而对于特定算法而言,提供某些操作的高效 -实现是必需的。通过将图接口分解为很多小的概念,我们为图算法的作者提供了好的 选择,他可以选择与其算法最为匹配的概念。 +实现是必需的。通过将图接口分解为很多小的概念,我们为图算法的作者提供了好的 选择,他可以选择与其算法最为匹配的概念。注意,由于我们使用的是 traits 类而不 是成员类型,所以定义 BGL 图类型的子类是不安全的(通常也不能工作);那些类可能 会缺少一些在类定义之外所定义的重要的 traits 和属性。
 </p><h2>Graph Structure Concepts Overview 图结构概念介绍</h2>

 <p>
@@ -190,8 +190,7 @@
 </tr>
 <!---------------------------------------------------------------->
 <tr><td colspan="2" align="left">
-<a href="./VertexListGraph.html">VertexListGraph</a> 精化自
-  IncidenceGraph 和 AdjacencyGraph </td>
+<a href="./VertexListGraph.html">VertexListGraph</a> 精化自&nbsp;Graph </td>
 </tr>
 <tr><td align="left">
 <tt>boost::graph_traits&lt;G&gt;::vertex_iterator</tt> </td>
=======================================
--- /trunk/libs/graph/doc/graph_traits.html     Thu Jul 23 20:28:01 2009
+++ /trunk/libs/graph/doc/graph_traits.html     Mon Aug 23 23:00:26 2010
@@ -7,7 +7,6 @@
   -- http://www.boost.org/LICENSE_1_0.txt)
   -->
 <title>Boost Graph Library: Graph Traits</title></head>
-
<body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b">
 <img src="../../../boost.png" alt="C++ Boost" height="86" width="277">

@@ -18,7 +17,9 @@
</h1>类似于STL的 <a href="http://www.sgi.com/tech/stl/iterator_traits.html";> 迭代器</a>,图也有<b>相关的类型</b>。正如在各种 <a href="./graph_concepts.html">图概念</a> 中所声明的,一个图带有一些相关联的类 型:<tt>vertex_descriptor</tt>, <tt>edge_descriptor</tt>, <tt>out_edge_iterator</tt>, 等等。任意一个特定的 图概念并不要求以下所有关联类型都被定义。当实现一个符合一个或多个图概念的图类 时,对于那些不被图概念所要求的关联类型,可以以 <tt>void</tt> 作为它们的类型 (在图类的内部使用嵌套 typedefs),或者在针对该图类的 <tt>graph_traits</tt> 特 化中去掉这些
-typedef。
+typedef。注意,由于我们使用的是 traits 类而不是成员类型,所以定义 BGL 图类 型的子类是不安全的(通常也不能工作);那些类可能会缺少一些在类定义之外所定义的 重要的 traits 和属性。
+
+

<pre> template &lt;typename Graph&gt;<br> struct graph_traits {<br> typedef typename Graph::vertex_descriptor vertex_descriptor;<br> typedef typename Graph::edge_descriptor edge_descriptor;<br> typedef typename Graph::adjacency_iterator adjacency_iterator;<br> typedef typename Graph::out_edge_iterator out_edge_iterator;<br> typedef typename Graph::in_edge_iterator in_edge_iterator;<br> typedef typename Graph::vertex_iterator vertex_iterator;<br> typedef typename Graph::edge_iterator edge_iterator;<br><br> typedef typename Graph::directed_category directed_category;<br> typedef typename Graph::edge_parallel_category edge_parallel_category;<br> typedef typename Graph::traversal_category traversal_category;<br><br> typedef typename Graph::vertices_size_type vertices_size_type;<br> typedef typename Graph::edges_size_type edges_size_type;<br> typedef typename Graph::degree_size_type degree_size_type;<br> };<br></pre>

=======================================
--- /trunk/libs/graph/doc/grid_graph.html       Sat Nov 28 08:00:21 2009
+++ /trunk/libs/graph/doc/grid_graph.html       Mon Aug 23 23:00:26 2010
@@ -74,7 +74,7 @@

     <h4>Template Parameters</h4>
     <pre class="code">
-<span class="keyword">template</span> &lt;<span class="keyword">typename</span> <span class="name">std</span>::<span class="type">size_t</span> <span class="name">Dimensions</span>, +<span class="keyword">template</span> &lt;<span class="name">std</span>::<span class="type">size_t</span> <span class="name">Dimensions</span>, <span class="keyword">typename</span> <span class="name">VertexIndex</span> = <span class="name">std</span>::<span class="type">size_t</span>, <span class="keyword">typename</span> <span class="name">EdgeIndex</span> = <span class="name">VertexIndex</span>&gt;
   <span class="keyword">class</span> grid_graph;
@@ -152,8 +152,8 @@
 <span class="comment">// Get the index associated with vertex</span>
<span class="name">Traits</span>::<span class="type">vertices_size_type</span> get(<span class="name">boost</span>::<span class="type">vertex_index_t</span>, - <span class="name">Traits</span>::<span class="type">vertex_descriptor</span> vertex, - <span class="keyword">const</span> <span class="name">Graph&amp;</span> graph); + <span class="keyword">const</span> <span class="name">Graph&amp;</span> graph, + <span class="name">Traits</span>::<span class="type">vertex_descriptor</span> vertex);

 <span class="comment">// Get the edge associated with edge_index</span>
 <span class="name">Traits</span>::<span class="type">edge_descriptor</span>
@@ -163,8 +163,8 @@
 <span class="comment">// Get the index associated with edge</span>
 <span class="name">Traits</span>::<span class="type">edges_size_type</span>
get(<span class="name">boost</span>::<span class="type">edge_index_t</span>, - <span class="name">Traits</span>::<span class="type">edge_descriptor</span> edge, - <span class="keyword">const</span> <span class="name">Graph&amp;</span> graph); + <span class="keyword">const</span> <span class="name">Graph&amp;</span> graph, + <span class="name">Traits</span>::<span class="type">edge_descriptor</span> edge);

<span class="comment">// Get the out-edge associated with vertex and out_edge_index</span>
 <span class="name">Traits</span>::<span class="type">edge_descriptor</span>
@@ -190,7 +190,7 @@

<span class="comment">// Do a round-trip test of the vertex index functions</span> <span class="keyword">for</span> (<span class="name">Traits</span>::<span class="type">vertices_size_type</span> v_index = <span class="literal">0</span>;
-     v_index < num_vertices(graph); ++v_index) {
+     v_index &lt; num_vertices(graph); ++v_index) {

   <span class="comment">// The two indices should always be equal</span>
<span class="name">std</span>::cout &lt;&lt; <span class="literal">&quot;Index of vertex &quot;</span> &lt;&lt; v_index &lt;&lt; <span class="literal">&quot; is &quot;</span> &lt;&lt;
@@ -200,7 +200,7 @@

<span class="comment">// Do a round-trip test of the edge index functions</span> <span class="keyword">for</span> (<span class="name">Traits</span>::<span class="type">edges_size_type</span> e_index = <span class="literal">0</span>;
-     e_index < num_edges(graph); ++e_index) {
+     e_index &lt; num_edges(graph); ++e_index) {

   <span class="comment">// The two indices should always be equal</span>
<span class="name">std</span>::cout &lt;&lt; <span class="literal">&quot;Index of edge &quot;</span> &lt;&lt; e_index &lt;&lt; <span class="literal">&quot; is &quot;</span> &lt;&lt;
=======================================
***Additional files exist in this changeset.***

Other related posts:

  • » [boost-doc-zh] r427 committed - 升级至1.44.0,第3批,libs/目录g-k子目录 - boost-doc-zh