[boost-doc-zh] r376 committed - 升级至1.41.0,第二批,libs/目录下b-e子目录

  • From: boost-doc-zh@xxxxxxxxxxxxxx
  • To: boost-doc-zh-notify@xxxxxxxxxxxxx
  • Date: Mon, 08 Feb 2010 05:51:37 +0000

Revision: 376
Author: alai04
Date: Sun Feb  7 21:50:27 2010
Log: 升级至1.41.0,第二批,libs/目录下b-e子目录
http://code.google.com/p/boost-doc-zh/source/detail?r=376

Added:
 /trunk/libs/bimap/doc/acknowledgements.qbk
 /trunk/libs/bimap/doc/bimap.hdf
 /trunk/libs/bimap/doc/bimap.qbk
 /trunk/libs/bimap/doc/bimap_and_boost.qbk
 /trunk/libs/bimap/doc/compiler_specifics.qbk
 /trunk/libs/bimap/doc/directdoxygen.jam
 /trunk/libs/bimap/doc/examples.qbk
 /trunk/libs/bimap/doc/future_work.qbk
 /trunk/libs/bimap/doc/history.qbk
 /trunk/libs/bimap/doc/introduction.qbk
 /trunk/libs/bimap/doc/jamfile.v2
 /trunk/libs/bimap/doc/performance.qbk
 /trunk/libs/bimap/doc/quick_tutorial.qbk
 /trunk/libs/bimap/doc/rationale.qbk
 /trunk/libs/bimap/doc/reference
 /trunk/libs/bimap/doc/reference/bimap.qbk
 /trunk/libs/bimap/doc/reference/list_of.qbk
 /trunk/libs/bimap/doc/reference/set_of.qbk
 /trunk/libs/bimap/doc/reference/unconstrained_set_of.qbk
 /trunk/libs/bimap/doc/reference/unordered_set_of.qbk
 /trunk/libs/bimap/doc/reference/vector_of.qbk
 /trunk/libs/bimap/doc/reference.qbk
 /trunk/libs/bimap/doc/release_notes.qbk
 /trunk/libs/bimap/doc/test_suite.qbk
 /trunk/libs/bimap/doc/toolbox.qbk
 /trunk/libs/bimap/doc/tutorial.qbk
 /trunk/libs/bimap/example/Jamfile.v2
 /trunk/libs/bimap/test/Jamfile.v2
 /trunk/libs/bind/test/Jamfile.v2
 /trunk/libs/bind/test/bind_eq2_test.cpp
 /trunk/libs/bind/test/bind_eq3_test.cpp
 /trunk/libs/bind/test/bind_ref_test.cpp
 /trunk/libs/bind/test/mem_fn_ref_test.cpp
 /trunk/libs/bind/test/mem_fn_unary_addr_test.cpp
 /trunk/libs/bind/test/protect_test.cpp
 /trunk/libs/circular_buffer/test/Jamfile.v2
 /trunk/libs/circular_buffer/test/constant_erase_test.cpp
 /trunk/libs/exception/example
 /trunk/libs/exception/example/Jamfile
 /trunk/libs/exception/example/cloning_1.cpp
 /trunk/libs/exception/example/cloning_2.cpp
 /trunk/libs/exception/example/enable_error_info.cpp
 /trunk/libs/exception/example/errinfos.cpp
 /trunk/libs/exception/example/error_info_1.cpp
 /trunk/libs/exception/example/error_info_2.cpp
 /trunk/libs/exception/example/example_io.cpp
 /trunk/libs/exception/example/info_tuple.cpp
 /trunk/libs/exception/example/logging.cpp
 /trunk/libs/exception/test
 /trunk/libs/exception/test/1-throw_exception_test.cpp
 /trunk/libs/exception/test/2-throw_exception_no_exceptions_test.cpp
 /trunk/libs/exception/test/3-throw_exception_no_integration_test.cpp
 /trunk/libs/exception/test/4-throw_exception_no_both_test.cpp
 /trunk/libs/exception/test/Jamfile.v2
 /trunk/libs/exception/test/all_hpp_test.cpp
 /trunk/libs/exception/test/cloning_test.cpp
 /trunk/libs/exception/test/copy_exception_test.cpp
 /trunk/libs/exception/test/current_exception_cast_hpp_test.cpp
 /trunk/libs/exception/test/current_exception_cast_test.cpp
 /trunk/libs/exception/test/diagnostic_information_hpp_test.cpp
 /trunk/libs/exception/test/diagnostic_information_test.cpp
 /trunk/libs/exception/test/enable_error_info_test.cpp
 /trunk/libs/exception/test/errinfo_api_function_hpp_test.cpp
 /trunk/libs/exception/test/errinfo_at_line_hpp_test.cpp
 /trunk/libs/exception/test/errinfo_errno_hpp_test.cpp
 /trunk/libs/exception/test/errinfo_file_handle_hpp_test.cpp
 /trunk/libs/exception/test/errinfo_file_name_hpp_test.cpp
 /trunk/libs/exception/test/errinfo_file_open_mode_hpp_test.cpp
 /trunk/libs/exception/test/errinfo_nested_exception_hpp_test.cpp
 /trunk/libs/exception/test/errinfo_type_info_name_hpp_test.cpp
 /trunk/libs/exception/test/errinfos_test.cpp
 /trunk/libs/exception/test/errno_test.cpp
 /trunk/libs/exception/test/error_info_const_fail.cpp
 /trunk/libs/exception/test/error_info_hpp_test.cpp
 /trunk/libs/exception/test/error_info_test.cpp
 /trunk/libs/exception/test/exception_fail.cpp
 /trunk/libs/exception/test/exception_hpp_test.cpp
 /trunk/libs/exception/test/exception_ptr_hpp_test.cpp
 /trunk/libs/exception/test/exception_test.cpp
 /trunk/libs/exception/test/get_error_info_hpp_test.cpp
 /trunk/libs/exception/test/has_to_string_test.cpp
 /trunk/libs/exception/test/helper1.cpp
 /trunk/libs/exception/test/helper1.hpp
 /trunk/libs/exception/test/helper2.cpp
 /trunk/libs/exception/test/helper2.hpp
 /trunk/libs/exception/test/info_hpp_test.cpp
 /trunk/libs/exception/test/info_tuple_hpp_test.cpp
 /trunk/libs/exception/test/is_output_streamable_test.cpp
 /trunk/libs/exception/test/no_exceptions_test.cpp
 /trunk/libs/exception/test/refcount_ptr_test.cpp
 /trunk/libs/exception/test/throw_exception_fail.cpp
 /trunk/libs/exception/test/throw_exception_test.cpp
 /trunk/libs/exception/test/to_string_fail.cpp
 /trunk/libs/exception/test/to_string_hpp_test.cpp
 /trunk/libs/exception/test/to_string_stub_hpp_test.cpp
 /trunk/libs/exception/test/to_string_stub_test.cpp
 /trunk/libs/exception/test/to_string_test.cpp
 /trunk/libs/exception/test/unknown_exception_test.cpp
Modified:
 /trunk/libs/bimap/doc/html/boost_bimap/acknowledgements.html
 /trunk/libs/bimap/example/bimap_and_boost/xpressive.cpp
 /trunk/libs/bind/test/bind_and_or_test.cpp
 /trunk/libs/bind/test/bind_cdecl_mf_test.cpp
 /trunk/libs/bind/test/bind_const_test.cpp
 /trunk/libs/bind/test/bind_cv_test.cpp
 /trunk/libs/bind/test/bind_dm2_test.cpp
 /trunk/libs/bind/test/bind_dm3_test.cpp
 /trunk/libs/bind/test/bind_dm_test.cpp
 /trunk/libs/bind/test/bind_eq_test.cpp
 /trunk/libs/bind/test/bind_fastcall_mf_test.cpp
 /trunk/libs/bind/test/bind_fastcall_test.cpp
 /trunk/libs/bind/test/bind_fn2_test.cpp
 /trunk/libs/bind/test/bind_fnobj2_test.cpp
 /trunk/libs/bind/test/bind_function_test.cpp
 /trunk/libs/bind/test/bind_lookup_problem_test.cpp
 /trunk/libs/bind/test/bind_mf2_test.cpp
 /trunk/libs/bind/test/bind_not_test.cpp
 /trunk/libs/bind/test/bind_placeholder_test.cpp
 /trunk/libs/bind/test/bind_rel_test.cpp
 /trunk/libs/bind/test/bind_rv_sp_test.cpp
 /trunk/libs/bind/test/bind_rvalue_test.cpp
 /trunk/libs/bind/test/bind_stateful_test.cpp
 /trunk/libs/bind/test/bind_stdcall_mf_test.cpp
 /trunk/libs/bind/test/bind_stdcall_test.cpp
 /trunk/libs/bind/test/bind_test.cpp
 /trunk/libs/bind/test/bind_unary_addr.cpp
 /trunk/libs/bind/test/bind_visit_test.cpp
 /trunk/libs/bind/test/mem_fn_cdecl_test.cpp
 /trunk/libs/bind/test/mem_fn_derived_test.cpp
 /trunk/libs/bind/test/mem_fn_dm_test.cpp
 /trunk/libs/bind/test/mem_fn_eq_test.cpp
 /trunk/libs/bind/test/mem_fn_fastcall_test.cpp
 /trunk/libs/bind/test/mem_fn_rv_test.cpp
 /trunk/libs/bind/test/mem_fn_stdcall_test.cpp
 /trunk/libs/bind/test/mem_fn_test.cpp
 /trunk/libs/bind/test/mem_fn_void_test.cpp
 /trunk/libs/bind/test/ref_fn_test.cpp
 /trunk/libs/circular_buffer/doc/circular_buffer.html
 /trunk/libs/circular_buffer/test/base_test.cpp
 /trunk/libs/circular_buffer/test/bounded_buffer_comparison.cpp
 /trunk/libs/circular_buffer/test/common.ipp
 /trunk/libs/circular_buffer/test/soft_iterator_invalidation.cpp
 /trunk/libs/circular_buffer/test/space_optimized_test.cpp
 /trunk/libs/circular_buffer/test/test.hpp
 /trunk/libs/crc/crc.html
 /trunk/libs/date_time/xmldoc/changes.xml
 /trunk/libs/date_time/xmldoc/posix_time_zone.xml
 /trunk/libs/exception/doc/boost_exception_ptr_hpp.html
 /trunk/libs/exception/doc/diagnostic_information.html

=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/acknowledgements.qbk  Sun Feb  7 21:50:27 2010
@@ -0,0 +1,66 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Acknowledgements]
+
+This library was developed in the context of the Google SoC 2006. I
+first want to thank my mentor, Joaquin, for his friendship during this
+project. Not only did he help me go through the process of creating this
+library, but he also did his best so we could have a great time doing
+it. Also, Boost.Bimap would not exist had Boost.MultiIndex, Joaquin's
+masterpiece, not existed. Thanks a lot!
+
+__GOOGLE_SOC_2006__
+
+I want to thank Google for this amazing ['boost] to the open-source
+community and to Boost mentors for trusting in my proposal in the first
+place. Next on the list are my colleagues from SoC that helped me not
+get bored during the long hours of coding.
+
+Special acknowledgements to the developers of the Boost libraries that
+Boost.Bimap has abused. See the dependencies section for a complete list.
+
+I want to thank the open-source developers who wrote the tools I used
+during this project. The list of names is infinitely long, so I
+give a general huge thanks here.
+
+Thanks to Paul Giaccone for proof-reading this documentation. (He has
+not finished yet -- the remaining typos and spelling errors are mine and
+will be corrected as soon as possible.)
+
+Finally, thanks to my family, who had to see me at home all day during
+the SoC. Special thanks to my brother Agustin, future famous novelist
+(at the present time he is 19 years old), who patiently read every word
+of these docs and while correcting them, barked at me for my bad written
+English. I have learned a lot from his sermons. I want to thank my dog,
+Mafalda, too for barking all day from my window and for being such a
+good company.
+
+Thanks to Alisdair Meredith, Fernando Cacciola, Jeff Garland, John Maddock,
+Thorsten Ottosen, Tony and Giovanni Piero Deretta for participating in
+the formal review and give me useful advices to improve this library.
+And thanks a lot to Ion Gaztañaga for managing the review.
+
+[heading Boost.Bimap Team]
+
+From Argentina... Matias and Mafalda and from Spain... Joaquin and Hector
+
+__MATIAS_PHOTO__
+__MAFALDA_PHOTO__
+__JOAQUIN_PHOTO__
+__HECTOR_PHOTO__
+
+Luckily, the distance helps team members avoid eating each other.
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/bimap.hdf     Sun Feb  7 21:50:27 2010
@@ -0,0 +1,237 @@
+# Doxyfile 1.4.7
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = Boost.Bimap
+PROJECT_NUMBER         =
+OUTPUT_DIRECTORY       = html
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = YES
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        = ../../../boost/bimap
+STRIP_FROM_INC_PATH    =
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 4
+ALIASES                =
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+BUILTIN_STL_SUPPORT    = YES
+DISTRIBUTE_GROUP_DOC   = YES
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = NO
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = YES
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = YES
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = YES
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = NO
+GENERATE_TESTLIST      = NO
+GENERATE_BUGLIST       = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS       =
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+FILE_VERSION_FILTER    =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = NO
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = ../../../boost/bimap
+FILE_PATTERNS          = *.hpp
+RECURSIVE              = YES
+EXCLUDE = ../../../boost/bimap/detail/test/check_metadata.hpp \
+                         
../../../boost/bimap/detail/test/check_size_of_pair.hpp
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       =
+EXAMPLE_PATH           =
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             =
+INPUT_FILTER           =
+FILTER_PATTERNS        =
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 3
+IGNORE_PREFIX          =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = doxydoc
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = style/doxyheader.html
+HTML_FOOTER            = style/doxyfooter.html
+HTML_STYLESHEET        = style/template/doxydoc/doxygen.css
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               =
+HHC_LOCATION           =
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = YES
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         =
+LATEX_HEADER           =
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    =
+RTF_EXTENSIONS_FILE    =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             =
+XML_DTD                =
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = NO
+INCLUDE_PATH           =
+INCLUDE_FILE_PATTERNS  =
+PREDEFINED = BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES \ + BOOST_BIMAP_ONLY_DOXYGEN_WILL_PROCESS_THE_FOLLOWING_LINES
+EXPAND_AS_DEFINED      =
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES               =
+GENERATE_TAGFILE       =
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = YES
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = YES
+TEMPLATE_RELATIONS     = YES
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = YES
+CALLER_GRAPH           = YES
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               =
+DOTFILE_DIRS           =
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 2046
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = YES
+GENERATE_LEGEND        = NO
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/bimap.qbk     Sun Feb  7 21:50:27 2010
@@ -0,0 +1,165 @@
+[library Boost.Bimap
+    [quickbook 1.4]
+    [authors [Capeletto, Matias]]
+    [copyright 2006-2007 Matias Capeletto]
+    [category container]
+    [id bimap]
+    [dirname bimap]
+    [purpose
+        Bidirectional map
+    ]
+    [source-mode c++]
+    [license
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+[@http://www.boost.org/LICENSE_1_0.txt])
+    ]
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[/ Logos ]
+
+[def __BOOST_BIMAP_LOGO__ [$images/bimap/boost.bimap.logo.png]]
+[def __GOOGLE_SOC_2006__ [$images/extern/googlesoc.png]]
+
+[/ Helpers ]
+
+[def __MI_FRAMEWORK__ [$images/bimap/miBimapFramework.png]]
+[def __SIMPLE_BIMAP__ [$images/bimap/simple.bimap.png]]
+[def __STANDARD_MAPPING_FRAMEWORK__ [$images/bimap/standard.mapping.framework.png]] +[def __EXTENDED_MAPPING_FRAMEWORK__ [$images/bimap/extended.mapping.framework.png]]
+[def __RELATION__ [$images/bimap/relation.png]]
+[def __STD_PAIR__ [$images/bimap/std_pair.png]]
+[def __COLLECTION_TYPE_OF_RELATION__ [$images/bimap/collection.type.of.relation.png]]
+[def __BIMAP_STRUCTURES__ [$images/bimap/bimap.structures.png]]
+[def __TAGGED__ [$images/bimap/tagged.png]]
+[def __MORE_BIMAP_STRUCTURES__ [$images/bimap/more.bimap.structures.png]]
+[def __RELATION_AND_PAIR__ [$images/bimap/relation.and.pair.png]]
+[def __RELATION_AND_PAIR_WITH_INFO__ [$images/bimap/relation.and.pair.with.info.png]]
+
+
+[/ People ]
+
+[def __MATIAS_PHOTO__ [$images/people/matias.png]]
+[def __JOAQUIN_PHOTO__ [$images/people/joaquin.png]]
+[def __MAFALDA_PHOTO__ [$images/people/mafalda.png]]
+[def __HECTOR_PHOTO__ [$images/people/hector.png]]
+
+[/ Icons ]
+
+[def __NOTE__ [$images/note.png]]
+[def __ALERT__ [$images/caution.png]]
+[def __DETAIL__ [$images/note.png]]
+[def __TIP__ [$images/tip.png]]
+[def __QUESTION_MARK__ [$images/question.png]]
+
+
+[/ Boost Libraries ]
+
+[def __BOOST_MULTI_INDEX__ [@http://www.boost.org/libs/multi_index/doc/index.html [*Boost.MultiIndex]]] +[def __BOOST_MPL__ [@http://www.boost.org/libs/mpl/doc/index.html [*Boost.MPL]]] +[def __BOOST_TYPE_TRAITS__ [@http://www.boost.org/doc/html/boost_typetraits.html [*Boost.TypeTraits]]] +[def __BOOST_ENABLE_IF__ [@http://www.boost.org/libs/utility/enable_if.html [*Boost.enable_if]]] +[def __BOOST_ITERATORS__ [@http://www.boost.org/libs/iterator/doc/index.html [*Boost.Iterators]]] +[def __BOOST_CALL_TRAITS__ [@http://www.boost.org/libs/utility/call_traits.htm [*Boost.call_traits]]] +[def __BOOST_STATIC_ASSERT__ [@http://www.boost.org/doc/html/boost_staticassert.html [*Boost.StaticAssert]]]
+
+[def __BOOST_SERIALIZATION__ [@http://www.boost.org/libs/serialization/doc/index.html [*Boost.Serialization]]] +[def __BOOST_HASH__ [@http://www.boost.org/doc/html/hash.html [*Boost.Hash]]] +[def __BOOST_ASSIGN__ [@http://www.boost.org/libs/assign/doc/index.html [*Boost.Assign]]] +[def __BOOST_LAMBDA__ [@http://www.boost.org/doc/html/lambda.html [*Boost.Lambda]]] +[def __BOOST_PROPERTY_MAP__ [@http://www.boost.org/doc/html/property_map.html [*Boost.PropertyMap]]] +[def __BOOST_RANGE__ [@http://www.boost.org/doc/html/range.html [*Boost.Range]]] +[def __BOOST_FOREACH__ [@http://www.boost.org/doc/html/foreach.html [*Boost.Foreach]]] +[def __BOOST_TEST__ [@http://www.boost.org/libs/test/doc/index.html [*Boost.Test]]] +[def __BOOST_TYPEOF__ [@http://www.boost.org/libs/typeof/doc/index.html [*Boost.Typeof]]] +[def __BOOST_XPRESSIVE__ [@http://www.boost.org/libs/xpressive/doc/index.html [*Boost.Xpressive]]]
+
+
+[/ Extern Links ]
+
+[def __CPP_STANDARD_LIBRARY_TECHNICAL_REPORT__ [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf C++ Standard Library Technical Report]] +[def __CPP_DEFECT_REPORT_130__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130 Defect Report 130]] +[def __TR1_ISSUES_LIST__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf Issues List]]
+
+[def __BOOST_HASH_FUNCTION__ [@http://www.boost.org/regression-logs/cs-win32_metacomm/doc/html/hash.html boost::hash]]
+
+[def __BOOST_PERMUTATION_ITERATOR__ [@http://www.boost.org/libs/iterator/doc/permutation_iterator.html `permutation_iterator`]]
+
+[def __BOOST_ASSERT_MACRO__ [@where_it_is `BOOST_ASSERT`]]
+[def __BOOST_MPL_FORWARD_SEQUENCE__ [@http://www.boost.org/libs/mpl/doc/refmanual/forward-sequence.html MPL Forward Sequence]] +[def __BOOST_MPL_RANDOM_ACCESS_SEQUENCE__ [@http://www.boost.org/libs/mpl/doc/refmanual/random-access-sequence.html MPL Random Access Sequence]] +[def __BOOST_MPL_EXTENSIBLE_SEQUENCE__ [@http://www.boost.org/libs/mpl/doc/refmanual/extensible-sequence.html MPL Extensible Sequence]]
+
+[def __SGI_UNARY_FUNCTION__ [@http://www.sgi.com/tech/stl/UnaryFunction.html Unary Function]] +[def __SGI_BINARY_FUNCTION__ [@http://www.sgi.com/tech/stl/BinaryFunction.html Binary Function]]
+
+[def __SGI_ASSIGNABLE__ [@http://www.sgi.com/tech/stl/Assignable.html Assignable]] +[def __SGI_DEFAULT_CONSTRUCTIBLE__ [@http://www.sgi.com/tech/stl/DefaultConstructible.html Default Constructible]] +[def __SGI_BINARY_PREDICATE__ [@http://www.sgi.com/tech/stl/BinaryPredicate.html Binary Predicate]] +[def __SGI_CONTAINER__ [@http://www.sgi.com/tech/stl/Container.html Container]] +[def __SGI_SORTED_ASSOCIATIVE_CONTAINER__ [@http://www.sgi.com/tech/stl/SortedAssociativeContainer.html Sorted Associative Container]] +[def __SGI_UNIQUE_ASSOCIATIVE_CONTAINER__ [@http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html Unique Associative Container]] +[def __SGI_REVERSIBLE_CONTAINER__ [@http://www.sgi.com/tech/stl/ReversibleContainer.html Reversible Container]] +[def __SGI_RANDOM_ACCESS_CONTAINER__ [@http://www.sgi.com/tech/stl/RandomAccessContainer.html Random Access Container]] +[def __SGI_FRONT_INSERTION_SEQUENCE__ [@http://www.sgi.com/tech/stl/FrontInsertionSequence.html Front Insertion Sequence]] +[def __SGI_BACK_INSERTION_SEQUENCE__ [@http://www.sgi.com/tech/stl/BackInsertionSequence.html Back Insertion Sequence]] +[def __SGI_INPUT_ITERATOR__ [@http://www.sgi.com/tech/stl/InputIterator.html Input Iterator]] +[def __SGI_FORWARD_ITERATOR__ [@http://www.sgi.com/tech/stl/ForwardIterator.html Forward Iterator]] +[def __SGI_STRICT_WEAK_ORDERING__ [@http://www.sgi.com/tech/stl/StrictWeakOrdering.html Strict Weak Ordering]]
+
+[def __EIFFEL__ [@http://www.eiffel.com/ Eiffel]]
+[def __SAFE_STL__ [@http://www.horstmann.com/safestl.html Safe STL]]
+[def __STL_PORT_DEBUG_MODE__ [@http://www.stlport.com/doc/debug_mode.html STLport Debug Mode]]
+
+[def __CGAL__ [@http://www.cgal.org/ CGAL]]
+[def __MYSQLPP__ [@http://tangentsoft.net/mysql++/ MySQL++]]
+
+
+[def __STL_TREE_H__ [@http://www.sgi.com/tech/stl/stl_tree.h stl_tree.h]]
+[def __ORDER_STATISTICS_TREE__ [@http://pine.cs.yale.edu/pinewiki/OrderStatisticsTree ['order-statistics trees]]]
+
+[def __GENERIC_PROGRAMMING_MOVE_CONSTRUCTORS__ [@http://www.ddj.com/dept/cpp/184403855 "Generic<Programming>: Move Constructors]] +[def __CLARIFICATION_OF_INITIALIZATION__ [@http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html "Clarification of Initialization of Class Objects by rvalues"]]
+
+
+[/ Code snippets ]
+
+[import ../example/simple_bimap.cpp]
+[import ../example/mighty_bimap.cpp]
+
+[section Preface]
+
+[heading Description]
+
+__BOOST_BIMAP_LOGO__
+
+Boost.Bimap is a bidirectional maps library for C++. With Boost.Bimap you can create associative containers in which both types can be used as key. A `bimap<X,Y>` +can be thought of as a combination of a `std::map<X,Y>` and a `std::map<Y,X>`.
+The learning curve of bimap is almost flat if you know how to use standard
+containers. A great deal of effort has been put into mapping the naming scheme of the +STL in Boost.Bimap. The library is designed to match the common STL containers.
+
+[heading Influences and Related Work]
+
+The design of Boost.Bimap interface follows the standard template library.
+It has been strongly influenced by Joaquin Lopez Muñoz's Boost.MultiIndex library
+(the heart of bimaps) and codeproject::bimap library.
+
+[endsect]
+
+[include introduction.qbk]
+[include quick_tutorial.qbk]
+[include tutorial.qbk]
+[include bimap_and_boost.qbk]
+[include reference.qbk]
+[include compiler_specifics.qbk]
+[include performance.qbk]
+[include examples.qbk]
+[include test_suite.qbk]
+[include future_work.qbk]
+[include release_notes.qbk]
+[include rationale.qbk]
+[include history.qbk]
+[include acknowledgements.qbk]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/bimap_and_boost.qbk   Sun Feb  7 21:50:27 2010
@@ -0,0 +1,477 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Bimap and Boost]
+
+[section Bimap and MultiIndex]
+
+['MISC] - [*M]ulti-[*I]ndex [*S]pecialized [*C]ontainers
+
+[:['
+Let's be generic, construct frameworks, describe the world in an
+unified way...
+]]
+[:['
+No!, it is better to be specialized, design easy-to-use components,
+offer plug-and-play objects...
+]]
+[:[*
+Why not take advantage of the best of both worlds?
+]]
+
+__MI_FRAMEWORK__
+
+With Boost.Bimap, you can build associative containers in which both
+types can be used as key. There is a library in Boost that already
+allows the creation of this kind of container: Boost.MultiIndex. It
+offers great flexibility and lets you construct almost any container
+that you could dream of. The framework is very clean. You migh want to
+read this library's tutorial to learn about the power that has been
+achieved.
+
+
+But generality comes at a price: the interface that results might not be
+the best for every specialization. People may end up wrapping a B.MI
+container in its own class every time they want to use it as a
+bidirectional map. Boost.Bimap takes advantage of the narrower scope to
+produce a better interface for bidirectional maps
+[footnote In the same fashion, Boost.MRU will allow the creation of ['most
+recent updated] aware containers, hiding the complexity of Boost.MultiIndex.].
+There is no learning curve if you know how to use standard containers.
+Great effort was put into mapping the naming scheme of the STL to Boost.Bimap.
+The library is designed to match the common STL containers.
+
+Boost.MultiIndex is, in fact, the core of the bimap container.
+
+However, Boost.Bimap do not aim to tackle every problem with two indexed
+types. There exist some problems that are better modelled with Boost.MultiIndex.
+
+
+[blurb
+
+[*Problem I  - An employee register]
+
+['Store an ID and a name for an employee, with fast search on each member.]
+
+This type of problem is better modelled as a database table, and
+[*Boost.MultiIndex] is the preferred choice. It is possible that other data
+will need to be indexed later.
+
+]
+
+[blurb
+
+[*Problem II - A partners container]
+
+['Store the names of couples and be able to get the name of a person's
+partner.]
+
+This problem is better modelled as a collection of relations, and [*Boost.Bimap]
+fits nicely here.
+
+]
+
+You can also read
+[link boost_bimap.the_tutorial.additional_information Additional Information] for more
+information about the relation of this two libraries.
+
+[endsect]
+
+[section Boost Libraries that work well with Boost.Bimap]
+
+[section Introduction]
+
+[table
+[[Name][Description][author][Purpose]]
+
+[[ __BOOST_SERIALIZATION__ ][
+Serialization for persistence and marshalling]
+[Robert Ramey]
+[Serialization support for bimap containers and iterators]]
+
+[[ __BOOST_ASSIGN__ ][
+Filling containers with constant or generated data has never been easier]
+[Thorsten Ottosen]
+[Help to fill a bimap or views of it]]
+
+[[ __BOOST_HASH__ ][
+A TR1 hash function object that can be extended to hash user defined types]
+[Daniel James]
+[Default hashing function]]
+
+[[ __BOOST_LAMBDA__ ][
+Define small unnamed function objects at the actual call site, and more]
+[from Jaakko Järvi, Gary Powell]
+[Functors for modify, range, lower_bound and upper_bound]]
+
+[[ __BOOST_RANGE__ ][
+A new infrastructure for generic algorithms that builds on top of the new
+iterator concepts]
+[Thorsten Ottosen]
+[Range based algorithms]]
+
+[[ __BOOST_FOREACH__ ][
+BOOST_FOREACH macro for easily iterating over the elements of a sequence]
+[Eric Niebler]
+[Iteration]]
+
+[[ __BOOST_TYPEOF__ ][
+Typeof operator emulation]
+[Arkadiy Vertleyb, Peder Holt]
+[Using BOOST_AUTO while we wait for C++0x]]
+
+[[ __BOOST_XPRESSIVE__ ][
+Regular expressions that can be written as strings or as expression templates]
+[Eric Niebler]
+[Help to fill a bimap from a string]]
+
+[[ __BOOST_PROPERTY_MAP__ ][
+Concepts defining interfaces which map key objects to value objects]
+[Jeremy Siek]
+[Integration with BGL]]
+]
+
+[endsect]
+
+[section Boost.Serialization]
+
+A bimap can be archived and retrieved by means of the Boost.Serialization Library. +Both regular and XML archives are supported. The usage is straightforward and does
+not differ from that of any other serializable type. For instance:
+
+[import ../example/bimap_and_boost/serialization.cpp]
+
+[@../../example/bimap_and_boost/serialization.cpp Go to source code]
+
+[code_bimap_and_boost_serialization]
+
+Serialization capabilities are automatically provided by just linking with the +appropriate Boost.Serialization library module: it is not necessary to explicitly +include any header from Boost.Serialization, apart from those declaring the type +of archive used in the process. If not used, however, serialization support can +be disabled by globally defining the macro BOOST_BIMAP_DISABLE_SERIALIZATION. +Disabling serialization for Boost.MultiIndex can yield a small improvement in
+build times, and may be necessary in those defective compilers that fail to
+correctly process Boost.Serialization headers.
+
+[warning Boost.Bimap and Boost.MultiIndex share a lot of serialization code. +The macro `BOOST_BIMAP_DISABLE_SERIALIZATION` disables serialization in *both* +libraries. The same happens when `BOOST_MULTI_INDEX_DISABLE_SERIALIZATION` is
+defined.
+]
+
+Retrieving an archived bimap restores not only the elements, but also the order +they were arranged in the views of the container. There is an exception to this rule, +though: for unordered sets, no guarantee is made about the order in which elements +will be iterated in the restored container; in general, it is unwise to rely on +the ordering of elements of a hashed view, since it can change in arbitrary ways +during insertion or rehashing --this is precisely the reason why hashed indices +and TR1 unordered associative containers do not define an equality operator.
+
+Iterators of a bimap can also be serialized. Serialization of an
+iterator must be done only after serializing its corresponding container.
+
+[endsect]
+
+[section Boost.Assign]
+
+The purpose of this library is to make it easy to fill containers with data by +overloading operator,() and operator()(). These two operators make it possible
+to construct lists of values that are then copied into a container.
+
+These lists are particularly useful in learning, testing, and prototyping
+situations, but can also be handy otherwise. The library comes with predefined +operators for the containers of the standard library, but most functionality will +work with any standard compliant container. The library also makes it possible +to extend user defined types so for example a member function can be called for
+a list of values instead of its normal arguments.
+
+Boost.Assign can be used with bimap containers.
+The views of a bimap are signature-compatible with their standard
+counterparts, so we can use other Boost.Assign utilities with them.
+
+[import ../example/bimap_and_boost/assign.cpp]
+
+[@../../example/bimap_and_boost/assign.cpp Go to source code]
+
+[code_bimap_and_boost_assign]
+
+[endsect]
+
+[section Boost.Hash]
+
+The hash function is the very core of the fast lookup capabilities of the
+unordered sets: a hasher is just a Unary Function returning an std::size_t value
+for any given key. In general, it is impossible that every key map to a
+different hash value, for the space of keys can be greater than the number of permissible hash codes: what makes for a good hasher is that the probability of a collision (two different keys with the same hash value) is as close to zero as possible.
+
+This is a statistical property depending on the typical distribution of keys in a given application, so it is not feasible to have a general-purpose hash function with excellent results in every possible scenario; the default value for this parameter uses Boost.Hash, which often provides good enough results.
+
+Boost.Hash can be
+[@http://www.boost.org/doc/html/hash/custom.html
+extended for custom data types],
+enabling to use the default parameter of the unordered set types with any user types.
+
+[endsect]
+
+[section Boost.Lambda]
+
+The Boost Lambda Library (BLL in the sequel) is a C++ template library, which implements +form of lambda abstractions for C++. The term originates from functional programming and
+lambda calculus, where a lambda abstraction defines an unnamed function.
+Lambda expressions are very useful to construct the function objects required by some of
+the functions in a bimap view.
+
+Boost.Bimap defines new placeholders in `<boost/bimap/support/lambda.hpp>`
+to allow a sounder solution. The placeholders are named _key and _data and both +are equivalent to boost::lambda::_1. There are two reasons to include this placeholders: +the code looks better with them and they avoid the clash problem between lambda::_1 and
+boost::_1 from Boost.Bind.
+
+[import ../example/bimap_and_boost/lambda.cpp]
+
+[@../../example/bimap_and_boost/lambda.cpp Go to source code]
+
+[code_bimap_and_boost_lambda]
+
+[endsect]
+
+[section Boost.Range]
+
+Boost.Range is a collection of concepts and utilities that are particularly useful
+for specifying and implementing generic algorithms.
+Generic algorithms have so far been specified in terms of two or more iterators. +Two iterators would together form a range of values that the algorithm could +work on. This leads to a very general interface, but also to a somewhat clumsy +use of the algorithms with redundant specification of container names. Therefore +we would like to raise the abstraction level for algorithms so they specify their
+interface in terms of Ranges as much as possible.
+
+As Boost.Bimap views are signature-compatible with their standard
+container counterparts, they are compatible with the concept of a range.
+As an additional feature, ordered bimap views offer a function named
+`range` that allows a range of values to be obtained.
+
+[import ../example/bimap_and_boost/range.cpp]
+
+If we have some generic functions that accepts ranges:
+
+[code_bimap_and_boost_range_functions]
+
+We can use them with Boost.Bimap with the help of the `range` function.
+
+[code_bimap_and_boost_range]
+
+[@../../example/bimap_and_boost/range.cpp Go to source code]
+
+[endsect]
+
+[section Boost.Foreach]
+
+In C++, writing a loop that iterates over a sequence is tedious.
+We can either use iterators, which requires a considerable amount of
+boiler-plate, or we can use the std::for_each()  algorithm and move our
+loop body into a predicate, which requires no less boiler-plate and forces
+us to move our logic far from where it will be used. In contrast, some other +languages, like Perl, provide a dedicated "foreach" construct that automates
+this process. BOOST_FOREACH is just such a construct for C++. It iterates
+over sequences for us, freeing us from having to deal directly with iterators
+or write predicates.
+
+You can use BOOST_FOREACH macro with Boost.Bimap views. The generated code will
+be as efficient as a std::for_each iteration.
+Here are some examples:
+
+[import ../example/bimap_and_boost/foreach.cpp]
+
+[code_bimap_and_boost_foreach]
+
+You can use it directly with ranges too:
+
+[code_bimap_and_boost_foreach_using_range]
+
+[@../../example/bimap_and_boost/foreach.cpp Go to source code]
+
+[endsect]
+
+[section Boost.Typeof]
+
+[import ../example/bimap_and_boost/typeof.cpp]
+
+Once C++0x is out we are going to be able to write code like:
+
+    auto iter = bm.by<name>().find("john");
+
+instead of the more verbose
+
+    bm_type::map_by<name>::iterator iter = bm.by<name>().find("john");
+
+Boost.Typeof defines a macro BOOST_AUTO that can be used as a library
+solution to the auto keyword while we wait for the next standard.
+
+If we have
+
+[code_bimap_and_boost_typeof_first]
+
+The following code snippet
+
+[code_bimap_and_boost_typeof_not_using_auto]
+
+can be rewrited as
+
+[code_bimap_and_boost_typeof_using_auto]
+
+[@../../example/bimap_and_boost/typeof.cpp Go to source code]
+
+[endsect]
+
+[section Boost.Xpressive]
+
+[import ../example/bimap_and_boost/xpressive.cpp]
+
+Using Boost.Xpressive we can parse a file and insert the relations in a bimap
+in the same step. It is just amazing the power of four lines of code.
+Here is an example (it is just beatifull)
+
+[code_bimap_and_boost_xpressive]
+
+[@../../example/bimap_and_boost/xpressive.cpp Go to source code]
+
+[endsect]
+
+[section Boost.Property_map]
+
+The Boost Property Map Library consists mainly of interface specifications in the form of +concepts (similar to the iterator concepts in the STL). These interface specifications +are intended for use by implementers of generic libraries in communicating requirements on +template parameters to their users. In particular, the Boost Property Map concepts define a +general purpose interface for mapping key objects to corresponding value objects, thereby
+hiding the details of how the mapping is implemented from algorithms.
+
+The need for the property map interface came from the Boost Graph Library (BGL), which +contains many examples of algorithms that use the property map concepts to specify their +interface. For an example, note the ColorMap template parameter of the breadth_first_search. +In addition, the BGL contains many examples of concrete types that implement the property map +interface. The adjacency_list class implements property maps for accessing objects
+(properties) that are attached to vertices and edges of the graph.
+
+The counterparts of two of the views of Boost.Bimap map, the `set` and
+`unordered_set`, are read-write property maps. In order to use these, you
+need to include one of the following headers:
+
+    #include <boost/bimap/property_map/set_support.hpp>
+    #include <boost/bimap/property_map/unordered_set_support.hpp>
+
+The following is adapted from the example in the Boost.PropertyMap
+documentation.
+
+[import ../example/bimap_and_boost/property_map.cpp]
+
+[@../../example/bimap_and_boost/property_map.cpp Go to source code]
+
+[code_bimap_and_boost_property_map]
+
+[endsect]
+
+[endsect]
+
+[section Dependencies]
+
+Boost.Bimap is built on top of several Boost libraries. The rationale
+behind this decision is keeping the Boost code base small by reusing
+existent code. The libraries used are well-established and have been
+tested extensively, making this library easy to port since all the hard
+work has already been done. The glue that holds everything together is
+Boost.MPL. Clearly Boost.MultiIndex is the heart of this library.
+
+[table Boost Libraries needed by Boost.Bimap
+[[Name][Description][author]]
+
+[[ __BOOST_MULTI_INDEX__ ][
+Containers with multiple STL-compatible access interfaces]
+[Joaquín M López Muñoz]]
+
+[[ __BOOST_MPL__ ][
+Template metaprogramming framework of compile-time algorithms, sequences and metafunction classes]
+[Aleksey Gurtovoy]]
+
+[[ __BOOST_TYPE_TRAITS__ ][
+Templates for fundamental properties of types.]
+[John Maddock, Steve Cleary]]
+
+[[ __BOOST_ENABLE_IF__ ][
+Selective inclusion of function template overloads]
+[Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine]]
+
+[[ __BOOST_ITERATORS__ ][
+Iterator construction framework, adaptors, concepts, and more.]
+[Dave Abrahams, Jeremy Siek, Thomas Witt]]
+
+[[ __BOOST_CALL_TRAITS__ ][
+Defines types for passing parameters.]
+[John Maddock, Howard Hinnant]]
+
+[[ __BOOST_STATIC_ASSERT__ ][
+Static assertions (compile time assertions).]
+[John Maddock]]
+
+]
+
+[table Optional Boost Libraries
+[[Name][Description][author][Purpose]]
+
+[[ __BOOST_SERIALIZATION__ ][
+Serialization for persistence and marshalling]
+[Robert Ramey]
+[Serialization support for bimap containers and iterators]]
+
+[[ __BOOST_ASSIGN__ ][
+Filling containers with constant or generated data has never been easier]
+[Thorsten Ottosen]
+[Help to fill a bimap or views of it]]
+
+[[ __BOOST_HASH__ ][
+A TR1 hash function object that can be extended to hash user defined types]
+[Daniel James]
+[Default hashing function]]
+
+[[ __BOOST_LAMBDA__ ][
+Define small unnamed function objects at the actual call site, and more]
+[from Jaakko Järvi, Gary Powell]
+[Functors for modify, range, lower_bound and upper_bound]]
+
+[[ __BOOST_RANGE__ ][
+A new infrastructure for generic algorithms that builds on top of the new
+iterator concepts]
+[Thorsten Ottosen]
+[Range based algorithms]]
+
+[[ __BOOST_PROPERTY_MAP__ ][
+Concepts defining interfaces which map key objects to value objects]
+[Jeremy Siek]
+[Integration with BGL]]
+]
+
+[table Additional Boost Libraries needed to run the test-suite
+[[Name][Description][author]]
+
+[[ __BOOST_TEST__ ][
+Support for simple program testing, full unit testing, and for program execution monitoring.]
+[Gennadiy Rozental]
+]
+]
+
+[endsect]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/compiler_specifics.qbk        Sun Feb  7 21:50:27 2010
@@ -0,0 +1,61 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Compiler specifics]
+
+[table
+[[Compiler  ][OS Tested ][State                               ]]
+[[GCC 3.3   ][Linux     ][Supported                           ]]
+[[GCC 3.4   ][Linux     ][Supported                           ]]
+[[GCC 4.0   ][Linux, Mac][Supported                           ]]
+[[GCC 4.1   ][Linux     ][Supported                           ]]
+[[GCC 4.2   ][Linux     ][Supported                           ]]
+[[ICC 8.0   ][Linux     ][Supported                           ]]
+[[ICC 9.0   ][Linux     ][Supported                           ]]
+[[ICC 9.1   ][Linux     ][Supported                           ]]
+[[GCC 4.2   ][Linux     ][Supported                           ]]
+[[GCC 4.2   ][Linux     ][Supported                           ]]
+[[VS 7.1    ][Windows   ][Supported                           ]]
+[[VS 8.0    ][Windows   ][Supported                           ]]
+[[ICC 7.1   ][Windows   ][Not Supported                       ]]
+[[ICC 8.0   ][Windows   ][Supported                           ]]
+[[ICC 9.1   ][Windows   ][Supported                           ]]
+[[CW 8.3    ][Windows   ][Not Supported                       ]]
+]
+
+[/
+[[Comeau C++][          ][Not yet tested (Will be supported)  ]]
+[[CW 8.3    ][Windows   ][On going effort to support it       ]]
+]
+
+[h2 VS 7.1]
+
+If a .cpp file uses more than four differents bimaps the compiler will run
+out of symbols and issue an internal compiler error. The official solution
+in msdn is to split the .cpp in several files or upgrade your compiler.
+
+[h2 VS 8.0]
+
+VC++ 8.0 warns on usage of certain Standard Library and API functions that
+can be cause buffer overruns or other possible security issues if misused.
+See http://msdn.microsoft.com/msdnmag/issues/05/05/SafeCandC/default.aspx
+But the wording of the warning is misleading and unsettling, there are no
+portable alternative functions, and VC++ 8.0's own libraries use the
+functions in question. In order to turn off the warnings add the followings
+defines at the begging of your .cpp files:
+
+    #define _CRT_SECURE_NO_DEPRECATE
+    #define _SCL_SECURE_NO_DEPRECATE
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/directdoxygen.jam     Sun Feb  7 21:50:27 2010
@@ -0,0 +1,22 @@
+# Boost.Bimap
+#
+# Copyright (c) 2006-2007 Matias Capeletto
+#
+# 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)
+
+
+import type ;
+import generators ;
+
+type.register HTML_DOXYFILE : hdf ;
+type.register HTML_DOXYDOCS : hdt ;
+
+generators.register-standard directdoxygen.run : HTML_DOXYFILE : HTML_DOXYDOCS ;
+
+actions run
+{
+    "doxygen" $(>)
+    echo "Stamped" > "$(<)"
+}
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/examples.qbk  Sun Feb  7 21:50:27 2010
@@ -0,0 +1,236 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Examples]
+
+[section Examples list]
+
+In the folder [@../../example libs/bimap/example] you can find all the examples
+used in bimap documentation. Here is a list of them:
+
+
+[table Tutorial examples
+[[Program ][Description ]]
+
+[[[@../../example/simple_bimap.cpp
+ simple_bimap.cpp ]] + [Soccer world cup example ]]
+
+[[[@../../example/tagged_simple_bimap.cpp
+ tagged_simple_bimap.cpp ]] + [Soccer world cup example using user defined names ]]
+
+[[[@../../example/step_by_step.cpp
+ step_by_step.cpp ]] + [Basic example of the three views of bimap ]]
+
+[[[@../../example/population_bimap.cpp
+ population_bimap.cpp ]] + [Countries populations, using `unordered_set_of` and `multiset_of` ]]
+
+[[[@../../example/repetitions_counter.cpp
+ repetitions_counter.cpp ]] + [Word repetitions counter, using `unordered_set_of` and `list_of` ]]
+
+[[[@../../example/mighty_bimap.cpp
+ mighty_bimap.cpp ]] + [Dictionary using `list_of_relation` ]]
+
+[[[@../../example/user_defined_names.cpp
+ user_defined_names.cpp ]] + [Equivalence between code with tagged and untagged code ]]
+
+[[[@../../example/standard_map_comparison.cpp
+ standard_map_comparison.cpp ]] + [Comparison between standard maps and bimap map views ]]
+
+[[[@../../example/at_function_examples.cpp
+ at_function_examples.cpp ]] + [Functions `at(key)` and `operator[](key)` examples ]]
+
+[[[@../../example/tutorial_modify_and_replace.cpp
+ tutorial_modify_and_replace.cpp ]] + [`modify` and `replace` examples ]]
+
+[[[@../../example/tutorial_range.cpp
+ tutorial_range.cpp ]] + [`range()` tutorial ]]
+
+[[[@../../example/tutorial_info_hook.cpp
+ tutorial_info_hook.cpp ]] + [Additional information hooking ]]
+
+[[[@../../example/unconstrained_collection.cpp
+ unconstrained_collection.cpp ]] + [Using `unconstrained_set_of` collection type ]]
+]
+
+
+[table Bimap and Boost examples
+[[Program ][Description ]]
+
+[[[@../../example/bimap_and_boost/assign.cpp
+ assign.cpp ]] + [Bimap and Boost.Assign: Methods to insert elements ]]
+
+[[[@../../example/bimap_and_boost/lambda.cpp
+ lambda.cpp ]] + [Bimap and Boost.Lambda: new lambda placeholders ]]
+
+[[[@../../example/bimap_and_boost/property_map.cpp
+ property_map.cpp ]] + [Bimap and Boost.PropertyMap: PropertyMap support ]]
+
+[[[@../../example/bimap_and_boost/range.cpp
+ range.cpp ]] + [Bimap and Boost.Range: Using bimaps in the new range framework ]]
+
+[[[@../../example/bimap_and_boost/foreach.cpp
+ foreach.cpp ]] + [Bimap and Boost.Foreach: Iterating over bimaps ]]
+
+[[[@../../example/bimap_and_boost/typeof.cpp
+ typeof.cpp ]] + [Bimap and Boost.Typeof: using BOOST_AUTO while we wait for C++0x ]]
+
+[[[@../../example/bimap_and_boost/xpressive.cpp
+ xpressive.cpp ]] + [Bimap and Boost.Xpressive: Inserting elements in a bimap ]]
+
+[[[@../../example/bimap_and_boost/serialization.cpp
+ serialization.cpp: ]] + [Bimap and Boost.Serialization: Load and save bimaps and iterators ]]
+]
+
+
+[table Boost.MultiIndex to Boost.Bimap path examples
+[[Program ][Description ]]
+
+[[[@../../example/mi_to_b_path/bidirectional_map.cpp
+ bidirectional_map.cpp ]] + [Boost.MultiIndex to Boost.Bimap path example ]]
+
+[[[@../../example/mi_to_b_path/hashed_indices.cpp
+ hashed_indices.cpp ]] + [Boost.MultiIndex to Boost.Bimap path example ]]
+
+[[[@../../example/mi_to_b_path/tagged_bidirectional_map.cpp
+ tagged_bidirectional_map.cpp ]] + [Boost.MultiIndex to Boost.Bimap path example ]]
+
+]
+
+[endsect]
+
+[section Simple Bimap]
+
+This is the example from the one minute tutorial section.
+
+[@../../example/simple_bimap.cpp Go to source code]
+
+[code_simple_bimap]
+
+You can rewrite it using tags to gain readability.
+
+[@../../example/tagged_simple_bimap.cpp Go to source code]
+
+[import ../example/tagged_simple_bimap.cpp]
+
+[code_tagged_simple_bimap]
+
+
+[endsect]
+
+[section Mighty Bimap]
+
+This is the translator example from the tutorial.
+In this example the collection type of relation is changed to allow the iteration
+of the container.
+
+[@../../example/mighty_bimap.cpp Go to source code]
+
+[code_mighty_bimap]
+
+
+[endsect]
+
+[section MultiIndex to Bimap Path - Bidirectional Map]
+
+This is example 4 in Boost.MultiIndex documentation.
+
+[blurb
+This example shows how to construct a bidirectional map with multi_index_container.
+By a bidirectional map we mean a container of elements of
+`std::pair<const FromType,const ToType>` such that no two elements exists with the +same first or second value (`std::map` only guarantees uniqueness of the first member). +Fast look-up is provided for both keys. The program features a tiny Spanish-English
+dictionary with on-line query of words in both languages.
+]
+
+[heading Boost.MultiIndex]
+
+[@../../example/mi_to_b_path/mi_bidirectional_map.cpp Go to source code]
+
+[import ../example/mi_to_b_path/mi_bidirectional_map.cpp]
+
+[code_mi_to_b_path_mi_bidirectional_map]
+
+[heading Boost.Bimap]
+
+[@../../example/mi_to_b_path/bidirectional_map.cpp Go to source code]
+
+[import ../example/mi_to_b_path/bidirectional_map.cpp]
+
+[code_mi_to_b_path_bidirectional_map]
+
+Or better, using tags...
+
+[@../../example/mi_to_b_path/tagged_bidirectional_map.cpp Go to source code]
+
+[import ../example/mi_to_b_path/tagged_bidirectional_map.cpp]
+
+[code_mi_to_b_path_tagged_bidirectional_map]
+
+[endsect]
+
+[section MultiIndex to Bimap Path - Hashed indices]
+
+This is example 8 of Boost.MultiIndex.
+
+[blurb
+Hashed indices can be used as an alternative to ordered indices when fast look-up is needed and sorting +information is of no interest. The example features a word counter where duplicate entries are checked by
+means of a hashed index.
+]
+
+[heading Boost.MultiIndex]
+
+[@../../example/mi_to_b_path/mi_hashed_indices.cpp Go to source code]
+
+[import ../example/mi_to_b_path/mi_hashed_indices.cpp]
+
+[code_mi_to_b_path_mi_hashed_indices]
+
+[heading Boost.Bimap]
+
+[@../../example/mi_to_b_path/hashed_indices.cpp Go to source code]
+
+[import ../example/mi_to_b_path/hashed_indices.cpp]
+
+[code_mi_to_b_path_hashed_indices]
+
+
+[endsect]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/future_work.qbk       Sun Feb  7 21:50:27 2010
@@ -0,0 +1,23 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Future work]
+
+
+[heading Rearrange Function]
+
+Boost.MultiIndex includes some others functions that can be included in the views.
+
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/history.qbk   Sun Feb  7 21:50:27 2010
@@ -0,0 +1,450 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section History]
+
+[section The long path from Code Project to Boost]
+
+[variablelist
+[[2002 - bimap at Code Project]
+[
+Joaquin Lopez Muñoz posted his first
+[@http://www.codeproject.com/vcpp/stl/bimap.asp#test_suite bimap library]
+in 2002. Tons of users have been using it. He then
+[@http://aspn.activestate.com/ASPN/Mail/Message/boost/1404881 asked the
+list for interest] in his library in 2003. Luckily, there was a lot of
+interest and Joaquin started to boostify the code. At some point all the
+developers seemed to agree that, rather than a bidirectional map, it would
+be better to work on an N-indexed set that contained Joaquin's library as a
+particular case.
+]]
+
+[[2003 - multiindex_set]
+[
+The library grew enormously and was ready for a formal review in
+2003. At this point, the container was a lot more powerful, but
+everything comes with a price and this new beast lacked the simplicity
+of the original bimap.
+]]
+
+[[2004 - indexed_set]
+[
+In 2004, the formal review ended well for the new multi-indexed
+container. This Swiss army knife introduced several new features, such
+as non-unique indexes, hashed indices and sequenced indices. In the list
+of improvements to the library, it was mentioned that a bidirectional
+map should be coded in top of this container.
+]]
+
+[[2005 - multi_index_container]
+[
+Once in Boost, the library switched to the now familiar name
+"Boost.MultiIndex". Late in 2004, it formally became a member of Boost.
+Joaquin continued to enchance the library and added new features such as
+composite keys and random-access indices.
+]]
+
+[[2006 - Multi Index Specialized Containers SoC project]
+[
+In 2006, during the formal review of Boost.Property_tree, the need
+for a bidirectional map container built on top of Boost.MultiIndex arose
+again. Boost entered the Google SoC 2006 as a mentor organization at the
+same time. Joaquin put himself forward as a mentor. He proposed to build
+not only a bidirectional map, but a myriad multi-indexed specialized
+containers. Matias Capeletto presented an application to code Boost.Misc
+for the SoC and was elected, along with nine other students. Matias's and
+Joaquin's SoC project ends with a working implementation of the bimap
+library that was presented in an informal review. By the end of the year
+the library was queued for a formal review.
+]]
+
+[[2007 - Boost.Bimap]
+[
+The formal review took place at the beggining of the year and Boost.Bimap
+was accepted in Boost.
+]]
+]
+
+[endsect]
+
+[section MultiIndex and Bimap]
+
+This is the conversation thread that began during Boost.PropertyTree formal
+review process. The review was very interesting and very deep topics were
+addressed. It is quite interesting and it is now part of this library history.
+Enjoy!
+
+
+[*Marcin]
+[:['
+The biggest virtue of property_tree is easy to use interface.
+If we try to make generic tree of it, it will be compromised.
+]]
+
+[*Gennadiy]
+[:['
+IMO the same result (as library presents) could be achieved
+just by using multi_index.
+]]
+
+[*Marcin]
+[:['
+Could you elaborate more on that? I considered use of
+multi_index to implement indexing for properties, but it only affected the
+implementation part of library, not interface, and because I already had a
+working, exception safe solution, I didn't see the reason to dump it and add
+another dependency on another library.
+]]
+
+[*Gennadiy]
+[:['
+I mean why do I need this half baked property_tree as another
+data structure? Property tree supports nothing in itself. It's just a data
+structure. You have parsers that produce property tree out of different sources. +But you mat as well produce maps or something else. Here for example All that
+I need to do to "implement" similar functionality as your property tree:
+]]
+
+``
+// Data structure itself
+template<typename ValueType,typename KeyType>
+struct Node;
+template<typename ValueType,typename KeyType>
+struct ptree_gen {
+    typedef std::pair<KeyType,Node<ValueType,KeyType> > mi_value;
+    typedef multi_index_container<mi_value, indexed_by<...> > type;
+};
+template<typename ValueType,typename KeyType>
+struct Node {
+    ValueType v;
+    ptree_gen<ValueType,KeyType>::type children;
+};
+// serialization support
+template<class Archive,typename ValueType,typename KeyType>
+void serialize(Archive & ar, Node<ValueType,KeyType>& n,
+               const unsigned int version)
+{
+    ar & n.v;
+    ar & n.children;
+}
+// some access methods
+template<typename ValueType,typename KeyType>
+ValueType const&
+get( string const& keys, ptree_gen<ValueType,KeyType>::type const& src )
+{
+    std::pait<string,string> sk = split( keys, "." );
+    Node const& N = src.find( sk.first );
+    return sk.second.empty() ? N.v : get( sk.second, N.children );
+}
+``
+
+[:['
+Use it like this:
+]]
+
+``
+ptree_gen<string,string>::type PT;
+boost::archive::text_iarchive ia( std::ifstream ifs("filename") );
+ia >> PT;
+string value = get( "a.b.c.d", PT );
+``
+
+[:['
+Now tell me how property_tree interface is easier? And what is the value in
+50k of Code you need to implement this data structure.
+]]
+
+[*Thorsten]
+[:['
+Seriously Gennadiy, do you really see newbies writing
+the code you just did?
+]]
+
+[*Marcin]
+[:['
+What you just implemented is stripped down, bare bones version
+of property_tree that, among other things, does not allow you to produce human
+editable XML files. Now add more interface (aka get functions), add more
+archives to serialization lib, add customization, add transparent
+translation from strings to arbitrary types and vice versa. Spend some weeks +trying to get all the corner cases right, and then some more weeks trying to
+smooth rough edges in the interface. Then write tests. Write docs. At the
+end, I believe you will not get much less code than there is in the library
+already. Maybe you get some savings by using multi_index instead of manual
+indexing.
+]]
+[:['
+The reason why ptree does not use multi index is because implementation
+existed long before I considered submitting to boost, probably before even I
+knew of multi index existence. It was working well. Later, when I was
+improving it during pre-review process, I seriously considered using
+multi-index. But I decided it is not worth throwing everything out.
+]]
+[:['
+Although ptree has large interface with many functions modifying state of
+the tree, it uses "single point of change" approach. Every insert eventually
+goes through one function, which takes care of exception safety and keeping
+index in sync with data. The same applies to erase. This function has 9
+lines of code in case of insert, and (by coincidence) also 9 in case of
+erase. By using multi index these functions would obviously be simplified,
+maybe to 4 lines each. Net gain: 10 lines of code (out of several hundred in
+ptree_implementation.hpp).
+]]
+[:['
+I'm aware that there are performance gains to be reaped as well, but at that
+time I was rather focusing on getting the interface right.
+]]
+
+[*Dave]
+[:['
+That's perfectly reasonable, but (through no fault of yours)
+it misses the point I was trying to make.  I guess I should have said,
+"...that demonstrates it to be the best implementation."
+]]
+[:['
+All I'm saying is that the extent to which a Boost library
+implementation should leverage other Boost libraries is not a question
+that can always be decided based on following simple guidelines, and
+that if this library is accepted, it's worth revisiting your decision.
+]]
+
+[*Thorsten]
+[:['
+I think it is important to focus on the interface in
+the review, but I also see several benefits of an implementation that builds on
+Boost.MultiIndex:'
+]]
+[:['- fewer bugs like the one Joaquin found]]
+[:['- better space efficiency]]
+[:['- exception-safety guarantees are immediately full-filled (I haven't
+looked, but I suspect that there are several bugs in this area)]]
+
+[*Daniel]
+[:['
+Multi_index supports everything a bimap would, but its
+interface is more cumbersome. I for one won't use a W3DOM-like library
+if we get one, but I would happily use property_tree. I've also only
+used multi_index once, and that was to use it as a bidirectional map.
+Property_tree covers other areas as well as being a potential subset of
+an XML library, but I still hold there is value in such a subset.
+]]
+
+[*Boris]
+[:['
+I haven't used program_options yet. But if I understand
+correctly both libraries seem to support storing and accessing data with
+strings that might describe some kind of hierarchy. This seems to be the core
+idea of both libraries - is this correct?
+]]
+[:['
+Then it wouldn't matter much what container is used. However a generic tree
+which can store data hierarchically probably makes most sense. If I
+understand correctly both libraries could make use of such a class?
+]]
+
+[*Marcin]
+[:['
+I think generic tree container is material for another library.
+Whether property_tree should be based on it or not is a matter of internal
+implementation, and generally of little interest to users. The biggest value
+of property_tree is in its easy to use interface, that should not be
+compromised, if at all possible. I have been already reassured in this view
+by quite many people who took their time to review the library.
+]]
+
+[*Boris]
+[:['
+I was trying to see the big picture: I rather prefer a C++
+standard based on a few well-known concepts like containers, iterators,
+algorithms etc. instead of having a C++ standard with hundreds of components +which are tailored for specific needs, collaborate with only a handful of other
+components and think they provide an easy-to-use interface while all the
+easy-to-use interfaces make the whole standard less easy-to-use.
+]]
+[:['
+That said I have used your property tree library myself to read and write a
+configuration file. It was indeed very easy to use. However it would have
+been even easier if it was something I had known before like eg. an
+iterator. For now I will definitely use your property tree library but would +appreciate if existing concepts were reused many C++ developers are familiar
+with. My opinion is that your library should be a part of Boost but should
+be more generalized in the future.
+]]
+
+[*Thorsten]
+[:['
+Well, I think we need both. Boost.MultiIndex is a great
+library and can do all kinds of wonderful things. But I would still like to see
+a bidirectional map (boost::bimap) written as a wrapper around it to
+get an easy and specialized interface.
+]]
+
+[*Pavel]
+[:['
+Bimap is available in libs/multi-index/examples/bimap.cpp.
+]]
+
+[*Thorsten]
+[:['
+Right, but the real value comes when somebody designs a nice
+STL-like interface and write docs etc, at least that was my point.
+]]
+
+[*Dave]
+[:['
+IMO Thorsten is exactly right.  This is precisely the sort of
+thing that could be added to the library as part of its ongoing maintenance
+and development (without review, of course).
+]]
+
+[*Joaquin]
+[:['
+Thorsten, we have talked about this privately in the past,
+but I feel like bringing it to the list in the hope of getting the attention
+of potential contributors:
+]]
+[:['
+There are some data structures buildable with B.MI which are regarded as
+particularly useful or common, like for instance the bidirectional map or
+bimap. A lean and mean implementation is provided in the aforementioned
+example, but certainly a much carefully crafted interface can be provided
+keeping B.MI as the implementation core: operator\[\], selection of
+1-1/1-N/N-1/N-N variants, hashing/ordering, etc.
+]]
+[:['
+I'm afraid I don't have the time to pursue this, as the current roadmap for
+core features of B.MI is taking all the spare time I can dedicate to the
+library. For this reason, I would love to see some volunteer jumping in who
+can develop this and other singular containers using B.MI (a cache container
+comes to mind) and then propose the results here either as a stand alone
+library of as part of B.MI --I'd prefer the former so as to keep the size
+of B.MI bounded.
+]]
+[:['
+If there's such a volunteer I can provide her with some help/mentoring. I also
+wonder whether this is a task suitable to be proposed for Google Summer of
+Code.
+]]
+
+[*Thorsten]
+[:['
+I think it would be good for SOC. All the really hard things
+are taken care of by B.MI, and so it seems reasonable for a student to be able
+to fill in the details.
+]]
+
+[*Dave]
+[:['
+Great!
+]]
+
+[*Jeff]
+[:['
+Please write a proposal!
+]]
+
+[*Joaquin]
+[:['
+I've just done so:
+]]
+
+[blurb *Specialized containers with Boost.MultiIndex*
+
+    *Introduction*
+
+ Boost.MultiIndex allows the construction of complex data structures involving
+    two or more indexing mechanisms on the same set of elements. Out of the
+    unlimited range of possible data structures specifiable within
+    Boost.MultiIndex, some particular configurations arise recurrently:
+
+ *a.* A bidirectional map or bimap is a container of elements of type pair<T,Q>
+    where fast look up is provided both for the T and the Q field,
+ in contrast with a regular STL map which only allows for fast look up on T.
+
+ *b.* An MRU (most recently used) list keeps the n last referenced elements: + when a new item is inserted and the list has reached its maximum length, the + oldest element is erased, whereas if an insertion is tried of a preexistence + element, this gets promoted to the first position. MRU lists can be used to
+    implement dynamic caches and the kind of behavior exhibited by programs
+    featuring a "Recent files" menu command, for instance.
+
+ Although Boost.MultiIndex provides the mechanisms to build these common structures, + the resulting interface can be cumbersome and too general in comparison with
+    specialized containers focusing on such particular structures.
+
+    *Goal*
+
+ To write a library of specialized containers like the ones described above, using + Boost.MultiIndex as the implementation core. Besides bimap and MRU list, the student + can also propose other specialized containers of interest in the community. It is + expected that the library meets the standards of quality required by Boost for an + eventual inclusion in this project, which implies a strong emphasis on interface + design, documentation and unit testing; the mentor will be guiding the student + through the complete cycle from specification and requirements gathering to + documentation and actual coding. The final result of the project must then contain:
+
+    *a.* Source code following
+ [@http://boost.org/more/lib_guide.htm#Guidelines Boost programming guidelines].
+
+ *b.* User documentation. Requirements on the format are loose, though the + [@http://www.boost.org/tools/quickbook/doc/html/index.html QuickBook] format is
+    gaining acceptance within Boost.
+
+    *c.* Complete set of unit tests powered by
+    [@http://boost.sourceforge.net/boost-build2/ Boost Build System V2].
+
+    *Requirements*
+
+ *a.* Intermediate-to-high level in C++, with emphasis in generic programming
+    (templates).
+
+ *b.* Knowledge of the STL framework and design principles. Of course, knowledge
+    of Boost in general and Boost.MultiIndex in particular is a big plus.
+
+ *c.* Acquaintance with at least two different C++ programming environments.
+
+ *d.* Some fluency in the English language; subsequent reviews of the documentation
+    can help smooth rough edges here, though.
+
+ *e.* A mathematical inclination and previous exposure to a formal Algorithms course
+    would help very much.
+
+    *f.* A craving for extreme quality work.
+
+    *Benefits for the student*
+
+ The student taking on this project will have the opportunity to learn the complete + process of software production inside a highly regarded C++ open source institution, + and even see her work included in Boost eventually. The completion of the project + involves non-trivial problems in C++ interface design and so-called modern C++ + programming, high quality user documentation and unit testing. The student will + also learn, perhaps to her surprise, that most of the time will be spent gathering + and trying ideas and, in general, thinking, rather than writing actual code.
+]
+
+[*Matias]
+[:['
+I am planning to submit an application to SoC. I will love to make real
+the specialized containers you mention and try to include some useful others.
+]]
+
+[:[^
+And then... after long hours of coding (and fun) this library saw the light.
+]]
+
+[:__BOOST_BIMAP_LOGO__]
+
+[endsect]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/introduction.qbk      Sun Feb  7 21:50:27 2010
@@ -0,0 +1,99 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+
+[/ QuickBook Document version 1.4 ]
+
+[section Introduction]
+
+[heading How to use this document]
+
+This documentation contains a large amount of information. Whereas it
+may be worth reading it all, this documentation is intended for
+programmers with various motives:
+
+[variablelist
+[[I have to finished this today, I just want a bidirectional map!][
+If your boss will kill you if the project is not finished by the end of
+the day, just read the [link boost_bimap.one_minute_tutorial One-minute tutorial]. +If you have a background in STL, you can be testing a bimap within ten minutes.
+]]
+[[I am a serious programmer and want to learn Boost.Bimap][
+Boost.Bimap has a lot to offer if you are prepared to spend some time
+reading this documentation. You will need to read [link boost_bimap.the_tutorial The tutorial]
+and skim through some of the [link boost_bimap.examples Examples].
+The best way to read this documentation is in the order given here.
+Just click on the arrow at the right bottom corner as you finish each page.
+You may skip the reference section, and return to it later to look up a function
+signature or to find a specific metafunction.
+]]
+[[I just love C++, I want to see the inner workings of Boost.Bimap.][
+If you are a library developer, this documentation is the best place to
+learn how Boost.Bimap is implemented. It is strongly recommended that
+you first learn to use the library as if you were the second type of
+programmer above. This library was developed in the Google SoC 2006, and
+the mentor and student generated a great deal of documentation in the
+building process. The rationale section is very large and contains a lot
+of information. There is a history section for those who might find it
+useful. Finally, in the reference section, each entity of the library is
+documented and its source code is presented.
+]]
+]
+
+[note
+If anything in the documentation is unclear, please email me at ['matias
+{dot} capeletto {at} gmail {dot} com], telling me which of the three
+types of programmer above you are and which section needs improvement.
+Please use the following notation for the subject: ['\[boost\]\[bimap\] Your
+problem] as this will help me to identify it more easily. If appropriate,
+I will act on your advice to improve the documentation. Thanks and enjoy!
+]
+
+[important
+If you should find a bug or would like to see an additional feature in
+the library, please use the standard Boost methods of dealing with this
+kind of issue rather than emailing me directly. Boost has a very good
+system to [@http://www.boost.org/more/bugs.htm track bugs] and
+[@http://www.boost.org/more/requesting_new_features.htm features requests],
+and using it is the best way of dealing with them as soon as possible.
+]
+
+[heading Navigation]
+
+Used in combination with the configured browser key (usually Alt), the
+following keys act as handy shortcuts for common navigation tasks.
+
+* [*General]
+
+    * [^[*p]] - Previous page
+    * [^[*n]] - Next page
+    * [^[*h]] - home
+    * [^[*u]] - Up
+
+* [*Main TOC]
+
+    * [^[*i]] - Introduction
+    * [^[*o]] - One minute tutorial
+    * [^[*t]] - The tutorial
+    * [^[*b]] - Bimap and Boost
+    * [^[*r]] - Reference
+    * [^[*c]] - Compiler specifics
+    * [^[*v]] - Performance
+    * [^[*e]] - Examples
+    * [^[*s]] - Test Suite
+    * [^[*f]] - Future work
+    * [^[*m]] - Release notes
+    * [^[*w]] - Rationale
+    * [^[*y]] - History
+    * [^[*a]] - Acknowledgements
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/jamfile.v2    Sun Feb  7 21:50:27 2010
@@ -0,0 +1,42 @@
+# Boost.Bimap
+#
+# Copyright (c) 2006-2007 Matias Capeletto
+#
+# 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)
+
+
+# Quickbook
+# -----------------------------------------------------------------------------
+
+import quickbook ;
+
+xml bimap
+    :
+        bimap.qbk
+    ;
+
+path-constant images_location : html ;
+
+boostbook standalone
+    :
+        bimap
+    :
+        <xsl:param>boost.root=../../../..
+        <xsl:param>boost.libraries=../../../libraries.htm
+        <xsl:param>toc.max.depth=2
+        <xsl:param>toc.section.depth=4
+        <xsl:param>chunk.section.depth=2
+        <format>pdf:<xsl:param>img.src.path=$(images_location)/
+ <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/bimap/doc/html
+    ;
+
+
+# Doxygen
+# -----------------------------------------------------------------------------
+# This generate the doxydocs and write "bimap.hdt".
+# Delete this file if you want to regenerate the doxydocs again
+# import directdoxygen ;
+# html-doxydocs bimap.hdt : bimap.hdf ;
+
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/performance.qbk       Sun Feb  7 21:50:27 2010
@@ -0,0 +1,19 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Performance]
+
+Section under construction.
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/quick_tutorial.qbk    Sun Feb  7 21:50:27 2010
@@ -0,0 +1,182 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section One minute tutorial]
+
+[heading What is a bimap?]
+
+A Bimap is a data structure that represents bidirectional relations between
+elements of two collections. The container is designed to work as two opposed STL maps. A bimap between a collection `X` and a collection `Y` can be viewed as a map from `X` to `Y` (this view will be called the ['left map view]) or as a map from `Y` to `X` (known as the ['right map view]). Additionally, the bimap can also be viewed as a set of relations between `X` and `Y` (named the ['collection of relations view]).
+
+The following code creates an empty bimap container:
+
+    typedef bimap<X,Y> bm_type;
+    bm_type bm;
+
+Given this code, the following is the complete description of the resulting bimap. +[footnote A type is ['signature-compatible] with other type if it has the same +signature for functions and metadata. Preconditions, postconditions and the order
+of operations need not be the same.
+]
+
+* `bm.left` is signature-compatible with `std::map<X,Y>`
+* `bm.right` is signature-compatible with `std::map<Y,X>`
+* `bm` is signature-compatible with `std::set< relation<X,Y> >`
+
+__SIMPLE_BIMAP__
+
+You can see how a bimap container offers three views over the same collection of bidirectional relations.
+
+If we have any generic function that work with maps
+
+    template< class MapType >
+    void print_map(const MapType & m)
+    {
+        typedef typename MapType::const_iterator const_iterator;
+ for( const_iterator iter = m.begin(), iend = m.end(); iter != iend; ++iter )
+        {
+            std::cout << iter->first << "-->" << iter->second << std::endl;
+        }
+    }
+
+We can use the ['left map view] and the ['right map view] with it
+
+    bimap< int, std::string > bm;
+    ...
+    print_map( bm.left  );
+    print_map( bm.right );
+
+And the output will be
+
+[pre
+[^1 --> one]
+[^2 --> two]
+...
+[^one --> 1]
+[^two --> 2]
+...
+]
+
+[heading Layout of the relation and the pairs of a bimap]
+
+The `relation` class represents two related elements. The two values are
+named left and right to express the symmetry of this type.
+The bimap pair classes are signature-compatible with `std::pairs`.
+
+__RELATION_AND_PAIR__
+
+[heading Step by step]
+
+[import ../example/step_by_step.cpp]
+
+A convinience header is avaiable in the boost directory:
+
+    #include <boost/bimap.hpp>
+
+Lets define a bidirectional map between integers and strings:
+
+[code_step_by_step_definition]
+
+[heading The collection of relations view]
+
+Remember that `bm` alone can be used as a set of relations.
+We can insert elements or iterate over them using this view.
+
+[code_step_by_step_set_of_relations_view]
+
+[heading The left map view]
+
+`bm.left` works like a `std::map< int, std::string >`. We use it
+in the same way we will use a standard map.
+
+[code_step_by_step_left_map_view]
+
+[heading The right map view]
+
+`bm.right` works like a `std::map< std::string, int >`. It is
+important to note that the key is the first type and the data
+is the second one, exactly as with standard maps.
+
+[code_step_by_step_right_map_view]
+
+[heading Differences with std::map]
+
+The main difference between bimap views and their standard containers counterparts +is that, because of the bidirectional nature of a bimap, the values stored in
+it can not be modified directly using iterators.
+For example, when a `std::map<X,Y>` iterator is dereferenced the return type is
+`std::pair<const X, Y>`, so the following code is valid:
+`m.begin()->second = new_value;`.
+However dereferencing a `bimap<X,Y>::left_iterator` returns a type that is
+['signature-compatible] with a `std::pair<const X, const Y>`
+
+    bm.left.find(1)->second = "1"; // Compilation error
+
+If you insert `(1,"one")` and `(1,"1")` in a `std::map<int,std::string>` the second insertion will have no effect. In a `bimap<X,Y>` both keys have to remain unique. The insertion may fail in other situtions too. Lets see an example
+
+    bm.clear();
+
+    bm.insert( bm_type::value_type( 1, "one" ) );
+
+    bm.insert( bm_type::value_type( 1, "1"   ) ); // No effect!
+    bm.insert( bm_type::value_type( 2, "one" ) ); // No effect!
+
+    assert( bm.size() == 1 );
+
+[heading A simple example]
+
+Look how you can reuse code that is intend to be used with std::maps, like the
+print_map function in this example.
+
+[@../../example/simple_bimap.cpp Go to source code]
+
+[code_simple_bimap]
+
+The output of this program will be the following:
+[pre
+[^The number of countries is 4]
+
+[^The winner is Argentina]
+
+[^Countries names ordered by their final position:]
+[^1) Argentina]
+[^2) Spain]
+[^3) Germany]
+[^4) France]
+
+[^Countries names ordered alphabetically along with their final position:]
+[^Argentina ends in position 1]
+[^France ends in position 4]
+[^Germany ends in position 3]
+[^Spain ends in position 2]
+]
+
+
+[heading Continuing the journey]
+
+For information on function signatures, see any standard library
+documentation or read the [link boost_bimap.reference reference] section of
+this documentation.
+
+[caution
+Be aware that a bidirectional map is only signature-compatible with standard +containers. Some functions may give different results, such as in the case of
+inserting a pair into the left map where the second value conflicts with a
+stored relation in the container. The functions may be slower in a bimap
+because of the duplicated constraints. It is strongly recommended that
+you read [link boost_bimap.the_tutorial The full tutorial] if you intend to
+use a bimap in a serious project.
+]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/rationale.qbk Sun Feb  7 21:50:27 2010
@@ -0,0 +1,914 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Rationale]
+
+This section assumes that you have read all other sections, the most of
+important of which being ['tutorial], ['std::set theory] and the ['reference],
+and that you have tested the library. A lot of effort was invested in
+making the interface as intuitive and clean as possible. If you
+understand, and hopefully like, the interface of this library, it will
+be a lot easier to read this rationale. The following section is little
+more than a rationale. This library was coded in the context of the
+Google SoC 2006 and the student and mentor were in different continents.
+A great deal of email flowed between Joaquin and Matias. The juiciest
+parts of the conversations where extracted and rearranged here.
+
+[note To browse the code, you can use the [@doxydoc/index.html ['Bimap Complete Reference]], a
+doxygen-powered document targeted at developers.
+]
+
+[section General Design]
+
+The initial explanation includes few features. This section aims to
+describe the general design of the library and excludes details of those
+features that are of lesser importance; these features will be
+introduced later.
+
+The design of the library is divided into two parts. The first is the
+construction of a [^relation] class. This will be the object stored and
+managed by the [^multi_index_container] core. The idea is to make this
+class as easy as possible to use, while making it efficient in terms of
+memory and access time. This is a cornerstone in the design of
+[*Boost.Bimap] and, as you will see in this rationale, the rest of the
+design follows easily.
+
+The following interface is necessary for the [^relation] class:
+
+    typedef -unspecified- TA; typedef -unspecified- TB;
+
+    TA a, ai; TB b, bi;
+
+    typedef relation< TA, TB > rel;
+    STATIC_ASSERT( is_same< rel::left_type , TA >::value );
+    STATIC_ASSERT( is_same< rel::right_type, TB >::value );
+
+    rel r(ai,bi);
+    assert( r.left == ai && r.right == bi );
+
+    r.left  = a; r.right = b;
+    assert( r.left  == a && r.right == b );
+
+    typedef pair_type_by< member_at::left , rel >::type pba_type;
+    STATIC_ASSERT( is_same< pba_type::first_type , TA >::value );
+    STATIC_ASSERT( is_same< pba_type::second_type, TB >::value );
+
+    typedef pair_type_by< member_at::right, rel >::type pbb_type;
+    STATIC_ASSERT( is_same< pbb_type::first_type , TB >::value );
+    STATIC_ASSERT( is_same< pbb_type::second_type, TA >::value );
+
+    pba_type pba = pair_by< member_at::left  >(r);
+    assert( pba.first == r.left  && pba.second == r.right );
+
+    pbb_type pbb = pair_by< member_at::right >(r);
+    assert( pbb.first == r.right && pbb.second == r.left  );
+
+
+__RELATION__
+
+Although this seems straightforward, as will be seen later, it is the
+most difficult code hack of the library. It is indeed very easy if we
+relax some of the efficiency constraints. For example, it is trivial if
+we allow a relation to have greater size than the the sum of those of
+its components. It is equally simple if access speed is not important.
+One of the first decisions made about [*Boost.Bimap] was, however, that, in
+order to be useful, it had to achieve zero overhead over the wrapped
+[*Boost.MultiIndex] container. Finally, there is another constraint that
+can be relaxed: conformance to C++ standards, but this is quite
+unacceptable. Let us now suppose that we have coded this class, and it
+conforms to what was required.
+
+The second part is based on this [^relation] class. We can now view the
+data in any of three ways: `pair<A,B>`, `relation<A,B>` and `pair<B,A>`.
+Suppose that our bimap supports only one-to-one relations. (Other
+relation types are considered additional features in this design.)
+The proposed interface is very simple, and it is based heavily on the
+concepts of the STL. Given a `bimap<A,B> bm`:
+
+# `bm.left` is signature-compatible with a `std::map<A,B>`
+# `bm.right` is signature-compatible with a `std::map<B,A>`
+# `bm` is signature-compatible with a `std::set<relation<A,B> >`
+
+__SIMPLE_BIMAP__
+
+This interface is easily learned by users who have a STL background, as
+well as being simple and powerful. This is the general design.
+
+[heading Relation Implementation]
+
+This section explains the details of the actual [^relation] class implementation.
+
+The first thing that we can imagine is the use of an [^union]. Regrettably,
+the current C++ standard only allows unions of POD types. For the views,
+we can try a wrapper around a `relation<A,B>` that has two references
+named first and second that bind to `A` and `B`, or to `B` and `A`.
+
+    relation<TA,TB> r;
+
+    const_reference_pair<A,B> pba(r);
+    const_reference_pair<B,A> pbb(r);
+
+It is not difficult to code the relation class using this, but two
+references are initialized at every access and using of `pba.first` will
+be slower in most compilers than using `r.left` directly . There is
+another hidden drawback of using this scheme: it is not
+iterator-friendly, since the map views iterators must be degraded to
+['Read Write] instead of ['LValue]. This will be explained later.
+
+At first, this seems to be the best we can do with the current C++
+standard. However there is a solution to this problem that does not
+conform very well to C++ standards but does achieve zero overhead in
+terms of access time and memory, and additionally allows the view
+iterators to be upgraded to ['LValue] again.
+
+In order to use this, the compiler must conform to a
+layout-compatibility clause that is not currently in the standard but is
+very natural. The additional clause imposes that if we have two classes:
+
+    struct class_a_b
+    {
+        Type1 name_a;
+        Type2 name_b;
+    };
+
+    struct class_b_a
+    {
+        Type1 name_b;
+        Type2 name_a;
+    };
+
+then the storage layout of [^class_a_b] is equal to the storage layout of
+[^class_b_a]. If you are surprised to learn that this does not hold in a
+standards-compliant C++ compiler, welcome to the club. It is the natural
+way to implement it from the point of view of the compiler's vendor and
+is very useful for the developer. Maybe it will be included in the
+standard some day. Every current compiler conforms to this.
+
+If we are able to count on this, then we can implement an idiom called
+[^mutant]. The idea is to provide a secure wrapper around [^reinterpret_cast].
+A class can declare that it can be viewed using different view classes
+that are storage-compatible with it. Then we use the free function
+[^mutate<view>(mutant)] to get the view. The `mutate` function checks at
+compile time that the requested view is declared in the mutant views list.
+We implement a class name `structured_pair` that is signature-compatible
+with a `std::pair`, while the storage layout is configured with a third
+template parameter. Two instances of this template class will provide
+the views of the relation.
+
+The thing is that if we want to be standards-compliant, we cannot use
+this approach. It is very annoying not to be able to use something that
+we know will work with every compiler and that is far better than
+alternatives. So -- and this is an important decision -- we have to find
+a way to use it and still make the library standards-compliant.
+
+The idea is very simple. We code both approaches: the
+const_reference_pair-based and the mutant-based, and use the mutant
+approach if the compiler is compliant with our new layout-compatible
+clause. If the compiler really messes things up, we degrade the
+performance of the bimap a little. The only drawback here is that, while
+the mutant approach allows to make ['LValue] iterators, we have to degrade
+them to ['Read Write] in both cases, because we require that the same code
+be compilable by any standards-compliant compiler.
+
+[note
+Testing this approach in all the supported compilers indicated that the
+mutant idiom was always supported. The strictly compliant version was
+removed from the code because it was never used.
+]
+
+
+[heading Bimap Implementation]
+
+The core of bimap will be obviously a `multi_index_container`. The basic
+idea to tackle the implementation of the bimap class is to use
+[^iterator_adaptor] to convert the iterators from Boost.MultiIndex to the
+`std::map` and `std::set` behaviour. The `map_view` and the `set_view` can be
+implemented directly using this new transformed iterators and a wrapper
+around each index of the core container. However, there is a hidden
+idiom here, that, once coded, will be very useful for other parts of
+this library and for Boost.MRU library. Following the ideas from
+`iterator_adaptor`, Boost.Bimap views are implemented using a
+[^container_adaptor]. There are several template classes (for example
+`map_adaptor` and `set_adaptor`) that take a `std::map` signature-conformant
+class and new iterators, and adapt the container so it now uses this
+iterators instead of the originals. For example, if you have a
+`std::set<int*>`, you can build other container that behaves exactly as a
+`std::set<int>` using `set_adaptor` and [^iterator_adaptor]. The combined use
+of this two tools is very powerful. A [^container_adaptor] can take classes
+that do not fulfil all the requirements of the adapted container. The
+new container must define these missing functions.
+
+[endsect]
+
+[section Additional Features]
+
+[heading N-1, N-N, hashed maps]
+
+This is a very interesting point of the design. The framework introduced
+in ['std::set theory] permits the management of the different constraints
+with a very simple and conceptual approach. It is easy both to remember
+and to learn. The idea here is to allow the user to specify the collection type
+of each key directly. In order to implement this feature, we have to
+solve two problems:
+
+* The index types of the `multi_index_container` core now depends on
+the collection type used for each key.
+* The map views now change their semantics according to the collection type
+chosen.
+
+Boost.Bimap relies heavily on Boost.MPL to implement all of the
+metaprogramming necessary to make this framework work. By default, if
+the user does not specify the kind of the set, a `std::set` type is used.
+
+__BIMAP_STRUCTURES__
+
+[heading Collection type of relation constraints]
+
+The constraints of the bimap set view are another very important
+feature. In general, Boost.Bimap users will base the set view type on
+one of the two collection types of their keys. It may be useful however to give
+this set other constraints or simply to order it differently. By
+default, Boost.Bimap bases the collection type of relations on the left collection
+type, but the user may choose between:
+
+* left_based
+* right_based
+* set_of_relation<>
+* multiset_of_relation<>
+* unordered_set_of_relation<>
+* unordered_multiset_of_relation<>
+* list_of
+* vector_of
+
+In the first two cases, there are only two indices in the
+`multi_index_core`, and for this reason, these are the preferred options.
+The implementation uses further metaprogramming to define a new index if
+necessary.
+
+[/
+[heading Hooking Data]
+
+This is one of the things that makes Boost.Bimap very appealing in
+tackling a problem. In general, programmers use maps to access
+information quickly. Boost.Bimap allows the user to hook data inside the
+bimap so that it is not necessary to maintain another map. The
+implementation is based heavily on metaprogramming.
+]
+
+[heading Tagged]
+
+The idea of using tags instead of the [^member_at::side] idiom is very
+appealing since code that uses it is more readable. The only cost is
+compile time. ['boost/bimap/tagged] is the implementation of a non-invasive
+tagged idiom. The [^relation] class is built in such a way that even when
+the user uses tags, the [^member_at::side] idiom continues to work. This is
+good since an user can start tagging even before completing the coding
+of the algorithm, and the untagged code continues to work. The
+development becomes a little more complicated when user-defined tags are
+included, but there are many handy metafunctions defined in the [^tagged]
+idiom that help to keep things simple enough.
+
+__TAGGED__
+
+[endsect]
+
+[section Code]
+
+You can browse the code using the [@doxydoc/index.html [*Boost.Bimap doxygen docs]].
+
+The code follows the [@http://www.boost.org/more/lib_guide.htm Boost Library Requirement and Guidelines] as
+closely as possible.
+
+[table folders in boost/bimap
+[[name][what is inside?]]
+[[/                     ][user level header files             ]]
+[[tagged/               ][tagged idiom                        ]]
+[[relation/             ][the bimap data                      ]]
+[[container_adaptor/    ][easy way of adapting containers     ]]
+[[views/                ][bimap views                         ]]
+[[property_map/         ][support for property map concept    ]]
+]
+
+[table folders in each folder
+[[name][what is inside?]]
+[[          ][class definitions]]
+[[support/  ][optional metafunctions and free functions]]
+[[detail/   ][things not intended for the user's eyes]]
+]
+
+[endsect]
+
+[section The student and the mentor]
+
+[tip It is a good idea to read the original
+[@http://h1.ripway.com/mcape/boost/libs/misc/ Boost.Misc SoC proposal] first.]
+
+[:[^- The discussion starts with Joaquin trying to strip out the "misc" name out of the library -]]
+
+__JOAQUIN_PHOTO__
+
+[*Joaquin]
+[:['
+Thinking about it, the unifying principle of MISC containers is perhaps
+misleading: certainly all miscs use multi-indexing internally, but this does +not reflect much in the external interface (as it should be, OTOH). So, from +the user's point of view, miscs are entirely heterogeneous beasts. Moreover, +there isn't in your proposal any kind of global facility common to all miscs.
+What about dropping the misc principle and working on each container as a
+separate library, then? You'd have boost::bimap, boost::mru, etc, and no common +intro to them. This also opens up the possibility to add other containers to +the suite which aren't based on B.MI. What's your stance on this? Do you see a
+value in keeping miscs conceptually together?
+]]
+
+__MATIAS_PHOTO__
+
+[*Matias]
+[:['
+As the original proposal states only two containers (bimap and mru set) both
+based in B.MI, it was straight forward to group them together. When I was
+writing the SoC proposal I experienced a similar feeling when the two families
+begin to grow. As you say, the only common denominator is their internal
+implementation. I thought a bit about a more general framework to join this two +families (and other internally related ones) and finally came up with an idea: +Boost.MultiIndex! So I think that it is not a good idea to try to unify the two +families and I voted in favor of get rid of the misc part of boost::misc::bimap
+and boost::misc::mru. Anyway, for my SoC application it seems OK to put the
+two families in the same project because although from the outside they are
+completely unrelated, the work I will have to do in order to build the libraries +will be consistent and what I will learn coding the bimap family will be used +when I start to code the mru family. When the mru family is in place, I will
+surely have learnt other things to improve the bimap group.
+]]
+[:['
+On the other hand, I think it will be useful for the general user to
+have at least some document linked in the B.MI documentation that
+enumerates the most common cases of uses (a bimap and an mru set for
+example) and points where to find clean implementation for this useful
+containers. For now, a link to boost::bimap and other one to boost::mru
+will suffice. If you think about the title of such a document,
+you will probably come up with something like: Common Multi Index
+Specialized Containers, and we are back to our misc proposal.
+So, to order some ideas:
+]]
+[:['- A new family of containers that can be accessed by both key will
+be created. (boost::bimap)]]
+[:['- A new family of time aware containers will see the light.
+(boost::mru)]]
+[:['- A page can be added to B.MI documentation, titled misc that links
+this new libraries.]]
+[:['
+This is a clearer framework for the user. They can use a mru container
+without hearing about Boost.MultiIndex at all.
+And B.MI users will get some of their common containers already
+implemented with an STL friendly interface in other libraries.
+And as you stated this is more extensible because opens the door to use
+other libraries in bimap and mru families than just Boost.MultiIndex
+without compromising the more general boost framework.
+The word "misc" it is going to disappear from the code and
+the documentation of bimap and mru. From now on the only use for it will be to
+identify our SoC project. I am thinking in a name for the bimap library.
+What about Boost.BidirectionalMap? Ideas?
+]]
+
+[*Joaquin]
+[:['
+Yes, Boost.Bimap. In my opinion, bimap is a well known name
+in the Boost and even in the C++ community. It sounds and is short. Why not to
+vindicate yourself as the owner of this name?
+]]
+
+[^- Then after a week of work -]
+
+[*Matias]
+[:['
+Now that Boost.Bimap is getting some shape, I see that as
+you have told me, we must offer a "one_to_many_map" and a "multi_bimap"
+as part of the library. The framework I am actually working allowed to
+construct this kind of bidirectional maps and it is easy to understand from
+the user side.
+]]
+
+[*Joaquin]
+[:['
+OK, I am glad we agree on this point.
+]]
+
+[*Matias]
+[:['
+With respect to the symmetry of the key access names, I have to
+agree that there is not much a difference between the following ones:
+]]
+[:['- to - from]]
+[:['- to - b]]
+[:['- 0 - 1]]
+[:['- left - right]]
+[:['
+In my opinion it is a matter of taste, but left/right sounds more symmetrical than
+the others.
+]]
+
+[*Joaquin]
+[:['
+I like very much the left/right notation, it is very simple to
+remember and it is a lot more symmetrical than to/from.
+]]
+
+[*Matias]
+[:['
+At first my idea was to obtain ease of use hiding the B.MI
+core, making it more STL-intuitive. Nevertheless I have realized
+that B.MI is a lot more coherent and easy to use that I had imagined. This
+makes me think again in the problem. In the design that I am coding now, bimap
+*is-a* multi_index_container specializes with a data type very comfortable
+called bipair, that can be seen like any of the two maps that integrates it
+using map views. This scheme has great benefits for users:
+]]
+[:['
+- If the user already knows B.MI, he can take advantage of the tools that
+it provides and that are not present in the STL containers. In addition, in some
+cases the use to indices to see the data can be very useful.
+]]
+[:['
+- If the user does not know anything about B.MI but have an STL framework,
+the learning curve is reduced to understand the bimap instantiation and how a
+is obtained the desired map view.
+]]
+[:['
+Another very important benefit holds: All the algorithms done for
+B.MI continues to work with Boost.Bimap and if B.MI continues growing, bimap
+grow automatically.
+]]
+
+[*Joaquin]
+[:['
+Umm... This is an interesting design decision, but
+controversial in my opinion. Basically you decide to expose the
+implementation of bimap; that has advantages, as you stated, but also
+a nonsmall disadvantage: once *you have documented* the implementation,
+it is not possible to change it anymore. It is a marriage with B.MI without
+the chance of divorce. The other possibility, to hide the implementation and
+to duplicate and document the provided functionality, explicitly or
+implicitly due to the same characteristics of the implementation, is
+of course heavier to maintain, but it gives a degree of freedom to change
+the guts of your software if you need to. Do not take this like a frontal
+objection, but I think that it is quite important design decision, not only
+in the context of bimap but in general.
+]]
+
+[*Matias]
+[:['
+You are quite right here. I think we have to choose the hardest
+path and hide the B.MI core from the user. I am sending you the first draft of
+bimap along with some documentation.
+]]
+
+[^- This completes the second week, the documentation was basically the first
+section of this rationale -]
+
+[*Joaquin]
+[:['
+I must confess that I am beginning to like what I see.
+I am mathematical by vocation, and when I see symmetry in a formulation
+I believe that it is in the right track.
+]]
+
+[*Matias]
+[:['
+We are two mathematicians by vocation then.
+]]
+
+[*Joaquin]
+[:['
+I think that the part of std::set theory is very clear.
+To me, it turns out to me somewhat strange to consider the rank of a map
+(values X) like a std::set, but of course the formulation is consistent.
+]]
+
+[*Matias]
+[:['
+I like it very much, it can be a little odd at first, but
+now that I have get used to it, it is very easy to express in the code my
+contrains on the data, and I believe that if somebody reads the code and
+sees the bimap instantiation he is not going to have problems understanding
+it. Perhaps it is easier to understand it if we use your notation:
+ordered_nonunique, unordered_unique, but this goes against our STL facade.
+In my opinion the user that comes from STL must have to learn as less as possible.
+]]
+
+[*Joaquin]
+[:['
+Considering a relation like a `struct {left, right}`
+is clean and clear. If I understand it well, one relation has views of type
+`pair{first, second}`, is this correct?
+]]
+
+[*Matias]
+[:['
+Yes, I believe that the left/right notation to express symmetry
+is great. I believe that to people is going to love it.
+]]
+
+[*Joaquin]
+[:['
+OK, perfect. I likes this very much:
+]]
+[:['- bm.left is compatible with std::map<A,B>]]
+[:['- bm.right is compatible with std::map<B,A>]]
+[:['- bm is compatible with std::set<relation<A,B>>]]
+[:['
+It is elegant and symmetric. I feel good vibrations here.
+]]
+
+[*Matias]
+[:['
+Great!
+]]
+
+[*Joaquin]
+[:['
+Moving on, the support for N-1, N-N, and hashed index is very easy
+to grasp, and it fits well in framework.
+However I do not finish to understand very well the "set<relation> constraints" section. +Will you came up with some examples of which is the meaning of the different
+cases that you enumerate?
+]]
+
+[*Matias - ]
+[:['
+Yes, I mean:
+]]
+[:['- based on the left]]
+[:['- based on the right]]
+[:['
+The bimap core must be based on some index of multi index. If the index
+of the left is of the type hash, then in fact the main view is going
+to be an unordered_set< relation<A,B> >. Perhaps this is not what the user
+prefers and he wants to base its main view on the right index.
+]]
+[:['- set_of_relation ]]
+[:['- multiset_of_relation ]]
+[:['- unordered_set_of_relation ]]
+[:['- unordered_multiset_of_relation ]]
+[:['
+However, if both of them are hash indexes, the user may want the main view
+to be ordered. As we have a B.MI core this is very easy to support, we just have
+to add another index to it.
+]]
+
+[*Joaquin]
+[:['
+I understand it now. OK, I do not know if we have to include this
+in the first version, is going to be a functionality avalanche!
+]]
+
+[*Matias]
+[:['
+The user is not affected by the addition of this functionality,
+because by default it will be based on the left index that is a very natural +behaviour. I do not think that this is functionality bloat, but I agree with
+you that it is a functionality avalanche.
+]]
+
+[*Joaquin]
+[:['
+There are restrictions between the left and right set types
+and the possible main view set types. For example if some of the index is
+of unique type, then the main view cannot be of type multiset_of_relation.
+To the inverse one, if the main view is of type set_of_relation the left and +the right index cannot be of type multi_set. All this subject of the unicity +constrictions and the resulting interactions between indexes is one of the subtle
+subjects of B.MI.
+]]
+
+[*Matias]
+[:['
+This can be checked at compile time and informed as an error
+in compile time.
+]]
+
+[*Joaquin]
+[:['
+It can be interesting.
+]]
+
+[^- And right when everything seems to be perfect... - ]
+
+[*Joaquin]
+[:['
+I have some worse news with respect to mutant, it is very a
+well designed and manageable class, unfortunately, C++ does not guarantee
+layout-compatibility almost in any case. For example, the C++ standard does
+not guarantee that the classes `struct{T1 a; T2 b;}` and `struct{T1 b; T2 a;}`
+are layout-compatible, and therefore the trick of reinterpret_cast is an
+undefined behavior. I am with you in which that in the 100% of the cases
+this scheme will really work, but the standard is the standard. If you can
+look the layout-compatibility subject in it (http://www.kuzbass.ru/docs/isocpp/). +As you see, sometimes the standard is cruel. Although mutant seems a lost case,
+please do not hurry to eliminate it. We will see what can be done for it.
+]]
+
+[*Matias]
+[:['
+I read the standard, and you were right about it. Mutant was an implementation +detail. It is a pity because I am sure that it will work perfect in any compiler. +Perhaps the standard becomes more strict some day and mutant returns to life... +We can then try a wrapper around a relation<A,B> that have two references named
+first and second that bind to A and B, or B and A.
+]]
+``
+relation<TA,TB> r;
+const_reference_pair<A,B> pba(r);
+const_reference_pair<B,A> pbb(r);
+``
+[:['
+It is not difficult to code the relation class in this way but two references
+are initialized with every access and the use of `pba.first` will be slower
+than `r.left` in most compilers. It is very difficult to optimize this kind of
+references.
+]]
+
+[*Joaquin]
+[:['
+This workaround is not possible, due to technical problems with
+the expected behavior of the iterators. If the iterators of bm.left are of
+bidirectional type, then standard stated that it have to return an object of type +const value_type& when dereferenced. You will have to return a const_reference_pair
+created in the flight, making it impossible to return a reference.
+]]
+
+[*Matias]
+[:['
+I understand... I have workaround for that also but surely
+the standard will attack me again! We must manage to create the class relation
+that responds as we want, the rest of the code will flow from this point.
+This clear separation between the relation class and the rest of the library,
+is going to help to us to separate the problems and to attack them better.
+]]
+
+[*Joaquin]
+[:['
+What workaround? It already pricks my curiosity,I have dedicated
+a long time to the subject and I do not find any solution except that we
+allow the relation class to occupy more memory.
+]]
+
+[*Matias]
+[:['
+We must achieve that the relation<A,B> size equals the pair<A,B> size
+if we want this library to be really useful. I was going to write my workaround and
+I realized that It does not work. Look at this:
+http://www.boost.org/libs/iterator/doc/new-iter-concepts.html
+Basically the problem that we are dealing is solved if we based our iterators on +this proposal. The present standard forces that the bidirectional iterators also +are of the type input and output. Using the new concepts there is no inconvenient +in making our iterators "Readable Writable Swappable Bidirectional Traversal".
+Therefore the const_reference_pair returns to be valid.
+]]
+
+[*Joaquin]
+[:['
+It is correct in the sense that you simply say that
+your iterators are less powerful than those of the std::map. It is
+not that it is wrong, simply that instead of fixing the problem, you
+confess it.
+]]
+
+[*Matias]
+[:['
+OK, but in our particular case; What are the benefits
+of offering a LValue iterator against a Read Write iterator?
+It does not seem to me that it is less powerful in this case.
+]]
+
+[*Joaquin]
+[:['
+The main problem with a ReadWrite is that the following thing:
+`value_type * p=&(*it);`
+fails or stores a transitory direction in p. Is this important in the real life? +I do not know. How frequently you store the direction of the elements of a map?
+Perhaps it is not very frequent, since the logical thing is to store the
+iterators instead of the directions of the elements.
+Let us review our options:
+]]
+[:['
+1. We used mutant knowing that is not standard, but of course it is
+supported in the 100% of the cases.
+]]
+[:['
+2. We used const_reference_pair and we declared the iterators not LValue.
+]]
+[:['
+3. We found some trick that still we do not know. I have thus been playing
+with unions and things, without much luck.
+]]
+[:['
+4. We leverage the restriction that views have to support the first, second
+notation. If we made this decision, there are several possibilities:
+]]
+[:['
+''' '''a. The left map has standard semantics first/second while the right map
+has the inverse semantics.
+]]
+[:['
+''' '''b. Instead of first and second we provide first() and second(), with
+which the problem is trivial.
+]]
+[:['
+''' '''c. The map view do not support first/second but left/right as the
+father relation
+]]
+[:['
+5. We solve the problem using more memory than sizeof(pair<A,B>).
+]]
+[:['
+In any case, I would say that the only really unacceptable option is the last one.
+]]
+
+[*Matias]
+[:['
+Lets see.
+]]
+[:['
+1. I want the "standard compliant" label in the library.
+]]
+[:['
+2. This is the natural choice, but knowing that there is another option
+that always works and it is more efficient is awful.
+]]
+[:['
+3. I have also tried to play with unions, the problem is that the union members
+must be POD types.
+]]
+[:['
+4. This option implies a big lost to the library.
+]]
+[:['
+5. Totally agree.
+]]
+[:['
+I want to add another option to this list. Using metaprogramming,
+the relation class checks if the compiler supports the mutant idiom.
+If it supports it then it uses it and obtains zero overhead
+plus LValue iterators, but if it do not supports it then uses
+const_reference_pair and obtains minimum overhead with ReadWrite iterators.
+This might be controversial but the advantages that mutant offers are very big +and the truth is that I do not believe that in any actual compiler this idiom is
+not supported. This scheme would adjust perfectly to the present standard
+since we are not supposing anything. The only drawback here is that although
+the mutant approach allows to make LValue iterators we have to degrade they
+to Read Write in both cases, because we want that the same code can be
+compiled in any standard compliant compiler.
+]]
+
+
+[^- Hopefully we find our way out of the problem -]
+
+[*Joaquin]
+[:['
+Changing the subject, I believe that the general concept of hooking data
+is good, but I do not like the way you implement it. It has to be easy
+to migrate to B.MI to anticipate the case in that Boost.Bimap becomes insufficient. +It is more natural for a B.MI user that the data is accessed without the indirection
+of `.data`. I do not know how this can be articulated in your framework.
+]]
+
+[*Matias]
+[:['
+I have a technical problem to implement the data_hook in this way.
+If the standard would let us use the mutant idiom directly, I can implement it +using multiple inheritance. But as we must use const_reference_pair too, It becomes
+impossible for me to support it. We have three options here:
+]]
+[:['
+1) relation { left, right, data } and pair_view { first, second, data }
+]]
+[:['
+- This is more intuitive within the bimap framework, since it does not
+mix the data with the index, as a table in a data base does, but gives more importance to
+the index.
+]]
+[:['
+- It is not necessary that the user puts the mutable keyword in each member of
+the data class.
+]]
+[:['
+- This moves away just a little bit from B.MI because the model
+of it is similar to a table, but it continues to exist a clear path of migration.
+]]
+[:['
+2) relation { left,right, d1,d2... dn } and pair_view { first, second, data }
+]]
+[:['
+- The path to B.MI is the one you have proposed.
+]]
+[:['
+- It is very asymmetric. It is necessary to explain that the views are
+handled different that the relation.
+]]
+[:['
+- The user must place the mutable keyboards in the data class.
+]]
+[:['
+3) Only relation { left,right, d1,d2... dn }
+]]
+[:['
+- Simple migration path to B.MI.
+]]
+[:['
+- You are not able to access the hooked data from the views.
+]]
+[:['
+My vote goes to the first proposal.
+]]
+
+
+[*Joaquin]
+[:['
+Yes, the first option is the one that less surprises hold to the user.
+I also vote for 1.
+]]
+
+[^- The third week was over -]
+
+[*Matias]
+[:['
+There is still one problem that I have to solve. I need to
+know if it is necessary to create a map_view associated to nothing. If
+it is necessary there are two options: that it behaves as an empty container or +that it throws an exception or assert when trying to use it. If it is not necessary,
+the map_view is going to keep a reference instead of a pointer.
+To me, the map_view always must be viewing something. In the case of the iterators +being able to create them empty, makes them easy to use in contexts that require +constructors by default, like being the value_type of a container, but I do not
+believe that this is the case of map_view.
+]]
+
+[*Joaquin]
+[:['
+How would an empty map_view be useful? My intuition is like yours,
+map_view would have to be always associate to something. If we wished to obtain
+the semantics "is associated or not" we can use a pointer to a map_view.
+]]
+
+[*Matias]
+[:['
+OK, then you agree to that map_views stores a reference instead
+of a pointer?
+]]
+
+[*Joaquin]
+[:['
+It depends on the semantics you want to give to map_views, and in
+concrete to the copy of map_views.
+]]
+``
+map_view x=...;
+map_view y=...;
+x=y;
+``
+[:['
+What is supposed to do this last line?
+]]
+[:['
+1. Rebinding of x, that is to say, x points at the same container that y.
+]]
+[:['
+2. Copy of the underlying container.
+]]
+[:['
+If you want to implement 1, you cannot use references internally.
+If you want to implement 2, it is almost the same to use a reference or a pointer.
+]]
+
+[*Matias]
+[:['
+If I want that they behave exactly as std::maps then I must go for 2.
+But if I think they as "views" of something, I like 1. The question is complicated.
+I add another option:
+]]
+[:['
+3. Error: operator= is declare as private in boost::bimap::map_view std_container
+]]
+[:['
+Also What happens with `std_container = view;`? and with `view = std_container;`?
+]]
+
+[endsect]
+
+[endsect]
+
+
+
+
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/reference/bimap.qbk   Sun Feb  7 21:50:27 2010
@@ -0,0 +1,523 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Bimap Reference]
+
+[section View concepts]
+
+`bimap` instantiations comprise two side views and an view of the relation
+specified at compile time. Each view allows read-write access to the elements contained
+in a definite manner, mathing an STL container signature.
+
+Views are not isolated objects and so cannot be constructed on their
+own; rather they are an integral part of a `bimap`. The name of the view
+class implementation proper is never directly exposed to the user, who
+has access only to the associated view type specifier.
+
+Insertion and deletion of elements are always performed through the
+appropriate interface of any of the three views of the `bimap`; these
+operations do, however, have an impact on all other views as well: for
+instance, insertion through a given view may fail because there exists
+another view that forbids the operation in order to preserve its
+invariant (such as uniqueness of elements). The global operations
+performed jointly in the any view can be reduced to six primitives:
+
+* copying
+* insertion of an element
+* hinted insertion, where a pre-existing element is suggested in order to improve
+the efficiency of the operation
+* deletion of an element
+* replacement of the value of an element, which may trigger the
+rearrangement of this element in one or more views, or may forbid the
+replacement
+* modification of an element, and its subsequent
+rearrangement/banning by the various views
+
+The last two primitives deserve some further explanation: in order to
+guarantee the invariants associated to each view (e.g. some definite
+ordering) elements of a `bimap` are not mutable. To overcome this
+restriction, the views expose member functions for updating and
+modifying, which allows for the mutation of elements in a controlled
+fashion.
+
+[endsect]
+
+[#complexity_signature_explanation]
+
+[section Complexity signature]
+
+Some member functions of a view interface are implemented by global
+primitives from the above list. The complexity of these operations thus
+depends on all views of a given `bimap`, not just the currently used view.
+
+In order to establish complexity estimates, a view is characterised by
+its complexity signature, consisting of the following associated
+functions on the number of elements:
+
+* `c(n)`: copying
+* `i(n)`: insertion
+* `h(n)`: hinted insertion
+* `d(n)`: deletion
+* `r(n)`: replacement
+* `m(n)`: modifying
+
+If the collection type of the relation is `left_based` or `right_based`, and we use +an `l` subscript to denote the left view and an `r` for the right view, then
+the insertion of an element in such a container is of complexity
+`O(i_l(n)+i_r(n))`, where n is the number of elements. If the collection type of
+relation is not side-based, then there is an additional term to add that
+is contributed by the collection type of relation view. Using `a` to denote the
+above view, the complexity of insertion will now be
+`O(i_l(n)+i_r(n)+i_a(n))`. To abbreviate the notation, we adopt the
+following definitions:
+
+* `C(n) = c_l(n) + c_r(n) [ + c_a(n) ]`
+* `I(n) = i_l(n) + i_r(n) [ + i_a(n) ]`
+* `H(n) = h_l(n) + h_r(n) [ + h_a(n) ]`
+* `D(n) = d_l(n) + d_r(n) [ + d_a(n) ]`
+* `R(n) = r_l(n) + r_r(n) [ + r_a(n) ]`
+* `M(n) = m_l(n) + m_r(n) [ + m_a(n) ]`
+
+[endsect]
+
+[section Set type specification]
+
+Set type specifiers are passed as instantiation arguments to `bimap` and
+provide the information needed to incorporate the corresponding views.
+Currently, Boost.Bimap provides the collection type specifiers. The ['side collection type]
+specifiers define the constraints of the two map views of the
+bimap. The ['collection type of relation] specifier defines the main set view
+constraints. If `left_based` (the default parameter) or `right_based` is
+used, then the collection type of relation will be based on the left or right
+collection type correspondingly.
+
+[table
+[[Side collection type ][Collection type of relation ][Include ]] +[[`set_of` ][`set_of_relation` ][`boost/bimap/set_of.hpp` ]] +[[`multiset_of` ][`multiset_of_relation` ][`boost/bimap/multiset_of.hpp` ]] +[[`unordered_set_of` ][`unordered_set_of_relation` ][`boost/bimap/unordered_set_of.hpp` ]] +[[`unordered_multiset_of` ][`unordered_multiset_of_relation`][`boost/bimap/unordered_multiset_of.hpp` ]] +[[`list_of` ][`list_of_relation` ][`boost/bimap/list_of.hpp` ]] +[[`vector_of` ][`vector_of_relation` ][`boost/bimap/vector_of.hpp` ]] +[[`unconstrained_set_of` ][`unconstrained_set_of_relation` ][`boost/bimap/unconstrained_set_of.hpp` ]] +[[ ][`left_based` ][`boost/bimap/bimap.hpp` ]] +[[ ][`right_based` ][`boost/bimap/bimap.hpp` ]]
+]
+
+[endsect]
+
+[section Tags]
+
+Tags are just conventional types used as mnemonics for the types stored
+in a `bimap`. Boost.Bimap uses the tagged idiom to let the user specify
+this tags.
+
+[endsect]
+
+[section Header "boost/bimap/bimap.hpp" synopsis]
+
+    namespace boost {
+    namespace bimaps {
+
+    template< class Type, typename Tag >
+    struct tagged;
+
+    // bimap template class
+
+    template
+    <
+        class LeftCollectionType, class RightCollectionType,
+
+        class AdditionalParameter_1 = detail::not_specified,
+        class AdditionalParameter_2 = detail::not_specified
+    >
+    class bimap ``['- implementation defined { : public SetView } -]``
+    {
+        public:
+
+        // Metadata
+
+        typedef ``['-unspecified-]`` left_tag;
+        typedef ``['-unspecified-]`` left_map;
+
+        typedef ``['-unspecified-]`` right_tag;
+        typedef ``['-unspecified-]`` right_map;
+
+        // Shortcuts
+        // typedef -side-_map::-type- -side-_-type-;
+
+        typedef ``['-unspecified-]`` info_type;
+
+        // Map views
+
+         left_map  left;
+        right_map right;
+
+        // Constructors
+
+        bimap();
+
+        template< class InputIterator >
+        bimap(InputIterator first,InputIterator last);
+
+        bimap(const bimap &);
+
+        bimap& operator=(const bimap& b);
+
+        // Projection of iterators
+
+        template< class IteratorType >
+        left_iterator project_left(IteratorType iter);
+
+        template< class IteratorType >
+        left_const_iterator project_left(IteratorType iter) const;
+
+        template< class IteratorType >
+        right_iterator project_right(IteratorType iter);
+
+        template< class IteratorType >
+        right_const_iterator project_right(IteratorType iter) const;
+
+        template< class IteratorType >
+        iterator project_up(IteratorType iter);
+
+        template< class IteratorType >
+        const_iterator project_up(IteratorType iter) const;
+
+        // Support for tags
+
+        template< class Tag >
+        struct map_by;
+
+        template< class Tag >
+        map_by<Tag>::type by();
+
+        template< class Tag >
+        const map_by<Tag>::type & by() const;
+
+        template< class Tag, class IteratorType >
+        map_by<Tag>::iterator project(IteratorType iter);
+
+        template< class Tag, class IteratorType >
+        map_by<Tag>::const_iterator project(IteratorType iter) const
+
+    };
+
+
+    } // namespace bimap
+    } // namespace boost
+
+
+[/
+    // Metafunctions for a bimap
+
+    template< class Tag, class Bimap > struct value_type_by;
+    template< class Tag, class Bimap > struct key_type_by;
+    template< class Tag, class Bimap > struct data_type_by;
+    template< class Tag, class Bimap > struct iterator_type_by;
+    template< class Tag, class Bimap > struct const_iterator_type_by;
+    template< class Tag, class Bimap > struct reverse_iterator_type_by;
+ template< class Tag, class Bimap > struct const_reverse_iterator_type_by;
+    template< class Tag, class Bimap > struct local_iterator_type_by;
+    template< class Tag, class Bimap > struct const_local_iterator_type_by;
+
+    // Functions for a bimap
+
+    template<class Tag, class Relation>
+    result_of::map_by< Tag, Bimap>::type map_by(Bimap &);
+
+    // Metafunctions for a relation
+
+    template< class Tag, class Relation > struct value_type_of;
+    template< class Tag, class Relation > struct pair_type_by;
+
+    // Functions for a relation
+
+    template<class Tag, class Relation>
+    result_of::get< Tag, Relation>::type get(Relation &r);
+
+    template<class Tag, class Relation>
+    result_of::pair_by< Tag, Relation>::type pair_by(Relation &);
+
+]
+
+[endsect]
+
+[section Class template bimap]
+
+This is the main component of Boost.Bimap.
+
+[section Complexity]
+
+In the descriptions of the operations of `bimap`, we adopt the scheme
+outlined in the complexity signature section.
+
+[endsect]
+
+[section Instantiation types]
+
+`bimap` is instantiated with the following types:
+
+# LeftCollectionType and RightCollectionType are collection type specifications
+optionally tagged, or any type optionally tagged, in which case that
+side acts as a set.
+# AdditionalParameter_{1/2} can be any ordered subset of:
+    * CollectionTypeOfRelation specification
+    * Allocator
+
+[endsect]
+
+[section Nested types]
+
+    left_tag, right_tag
+
+[: Tags for each side of the bimap. If the user has not specified any tag the
+    tags default to `member_at::left` and `member_at::right`.
+]
+
+    left_key_type, right_key_type
+
+[:  Key type of each side. In a `bimap<A,B> ` `left_key_type` is `A` and
+    `right_key_type` is `B`.
+    If there are tags, it is better to use: `Bimap::map_by<Tag>::key_type`.
+]
+
+    left_data_type, right_data_type
+
+[:  Data type of each side. In a bimap<A,B> left_key_type is B and
+    right_key_type is A.
+ If there are tags, it is better to use: `Bimap::map_by<Tag>::data_type`.
+]
+
+    left_value_type, right_value_type
+
+[:  Value type used for the views.
+ If there are tags, it is better to use: `Bimap::map_by<Tag>::value_type`.
+]
+
+
+    left_iterator, right_iterator
+    left_const_iterator, right_const_iterator
+
+[:  Iterators of the views.
+    If there are tags, it is better to use:
+    `Bimap::map_by<Tag>::iterator` and
+    `Bimap::map_by<Tag>::const_iterator`
+]
+
+
+    left_map, right_map
+
+[:  Map view type of each side.
+    If there are tags, it is better to use:
+    `Bimap::map_by<Tag>::type`.
+]
+
+[endsect]
+
+[section Constructors, copy and assignment]
+
+    bimap();
+
+* [*Effects:] Constructs an empty `bimap`.
+* [*Complexity:] Constant.
+
+    template<typename InputIterator>
+    bimap(InputIterator first,InputIterator last);
+
+* [*Requires: ] `InputIterator` is a model of Input Iterator over elements of +type `relation` or a type convertible to `relation`. last is reachable from `first`. +* [*Effects:] Constructs an empty `bimap` and fills it with the elements in the range +`[first,last)`. Insertion of each element may or may not succeed depending on
+acceptance by the collection types of the `bimap`.
+* [link complexity_signature_explanation
+[*Complexity:]] O(m*H(m)), where m is the number of elements in `[first,last)`.
+
+
+    bimap(const bimap & x);
+
+* [*Effects:] Constructs a copy of x, copying its elements as well as its
+internal objects (key extractors, comparison objects, allocator.)
+* [*Postconditions:] `*this == x`. The order of the views of the `bimap`
+is preserved as well.
+* [*Complexity:] O(x.size()*log(x.size()) + C(x.size()))
+
+
+    ~bimap()
+
+* [*Effects:] Destroys the `bimap` and all the elements contained.
+The order in which the elements are destroyed is not specified.
+* [*Complexity:] O(n).
+
+
+    bimap& operator=(const bimap& x);
+
+* [*Effects:] Replaces the elements and internal objects of the `bimap`
+with copies from x.
+* [*Postconditions:] `*this==x`. The order on the views of the `bimap`
+is preserved as well.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(n + x.size()*log(x.size()) + C(x.size())).
+* [*Exception safety:] Strong, provided the copy and assignment operations
+of the types of `ctor_args_list` do not throw.
+
+[/
+    allocator_type get_allocator() const;
+
+* [*Effects:] Returns a copy of the `allocator_type` object used to construct
+the `bimap`.
+* [*Complexity:] Constant.
+]
+
+[endsect]
+
+[#reference_projection_operations]
+
+[section Projection operations]
+
+Given a `bimap` with views v1 and v2, we say than an v1-iterator
+it1 and an v2-iterator it2 are equivalent if:
+
+* `it1 == i1.end()` AND `it2 == i2.end()`,
+* OR `it1` and `it2` point to the same element.
+
+
+    template< class IteratorType >
+    left_iterator project_left(IteratorType iter);
+
+    template< class IteratorType >
+    left_const_iterator project_left(IteratorType iter) const;
+
+* [*Requires:] `IteratorType` is a bimap view iterator. it is a
+valid iterator of some view of `*this` (i.e. does not refer to some other
+`bimap`.)
+* [*Effects:] Returns a left map view iterator equivalent to `it`.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+    template< class IteratorType >
+    right_iterator project_right(IteratorType iter);
+
+    template< class IteratorType >
+    right_const_iterator project_right(IteratorType iter) const;
+
+* [*Requires:] `IteratorType` is a bimap view iterator. it is a
+valid iterator of some view of `*this` (i.e. does not refer to some other
+`bimap`.)
+* [*Effects:] Returns a right map view iterator equivalent to `it`.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+    template< class IteratorType >
+    iterator project_up(IteratorType iter);
+
+    template< class IteratorType >
+    const_iterator project_up(IteratorType iter) const;
+
+* [*Requires:] `IteratorType` is a bimap view iterator. it is a
+valid iterator of some view of `*this` (i.e. does not refer to some other
+`bimap`.)
+* [*Effects:] Returns a collection of relations view iterator equivalent to `it`.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+[endsect]
+
+[#reference_support_for_used_defined_names]
+
+[section Support for user defined names]
+
+    template< class Tag >
+    struct map_by;
+
+* `map_by<Tag>::type` yields the type of the map view tagged with `Tag`.
+`map_by<Tag>::`['-type name-] is the same as `map_by<Tag>::type::`['-type name-].
+* [*Requires: ] `Tag` is a valid user defined name of the bimap.
+
+
+    template< class Tag >
+    map_by<Tag>::type by();
+
+    template< class Tag >
+    const map_by<Tag>::type & by() const;
+
+
+* [*Requires: ] `Tag` is a valid user defined name of the bimap.
+* [*Effects:] Returns a reference to the map view tagged with `Tag` held by
+`*this`.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+    template< class Tag, class IteratorType >
+    map_by<Tag>::iterator project(IteratorType iter);
+
+    template< class Tag, class IteratorType >
+    map_by<Tag>::const_iterator project(IteratorType iter) const
+
+* [*Requires: ] `Tag` is a valid user defined name of the bimap. `IteratorType`
+is a bimap view iterator. it is a valid iterator of some view of `*this`
+(i.e. does not refer to some other `bimap`.)
+* [*Effects:] Returns a reference to the map view tagged with `Tag` held by
+`*this`.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+[endsect]
+
+[section Serialization]
+
+A `bimap` can be archived and retrieved by means of __BOOST_SERIALIZATION__.
+Boost.Bimap does not expose a public serialisation interface, as this is
+provided by Boost.Serialization itself. Both regular and XML archives
+are supported.
+
+Each of the set specifications comprising a given `bimap` contributes its
+own preconditions as well as guarantees on the retrieved containers. In describing
+these, the following concepts are used. A type `T` is ['serializable]
+(resp. XML-serializable) if any object of type `T` can be saved to an output +archive (XML archive) and later retrieved from an input archive (XML archive) +associated to the same storage. If `x`' of type `T` is loaded from the serialization +information saved from another object x, we say that x' is a ['restored copy] of x. +Given a __SGI_BINARY_PREDICATE__ `Pred` over `(T, T)`, and objects `p` and `q` of
+type `Pred`, we say that `q` is ['serialization-compatible] with `p` if
+
+* `p(x,y) == q(x`'`,y`'`)`
+
+for every `x` and `y` of type `T` and `x`' and `y`' being restored copies of `x`
+and `y`, respectively.
+
+[blurb [*Operation:] saving of a `bimap b` to an output archive
+(XML archive) ar.]
+
+* [*Requires:] Value is serializable (XML-serializable). Additionally, each
+of the views of b can impose other requirements.
+* [*Exception safety:] Strong with respect to `b`. If an exception is thrown, ar
+may be left in an inconsistent state.
+
+[blurb [*Operation:] loading of a `bimap` m' from an input archive
+(XML archive) ar.]
+
+* [*Requires:] Value is serializable (XML-serializable). Additionally, each of
+the views of `b`' can impose other requirements.
+* [*Exception safety:] Basic. If an exception is thrown, ar may be left in an
+inconsistent state.
+
+[endsect]
+[endsect]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/reference/list_of.qbk Sun Feb  7 21:50:27 2010
@@ -0,0 +1,798 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section list_of Reference]
+
+[section Header "boost/bimap/list_of.hpp" synopsis]
+
+    namespace boost {
+    namespace bimaps {
+
+
+    template< class KeyType >
+    struct list_of;
+
+    struct list_of_relation;
+
+
+    } // namespace bimap
+    } // namespace boost
+
+[endsect]
+
+[section list_of Views]
+
+A list_of set view is a std::list signature compatible
+interface to the underlying heap of elements contained in a `bimap`.
+
+If you look the bimap by a side, you will use a map view and if you looked
+it as a whole you will be using a set view.
+
+Elements in a list_of view are by default sorted according to
+their order of insertion: this means that new elements inserted through a
+different view of the `bimap` are appended to the end of the
+list_of view. Additionally, the view allows for free reordering of elements
+in the same vein as `std::list` does. Validity of iterators and references to
+elements is preserved in all operations.
+
+There are a number of differences with respect to `std::lists`:
+
+* list_of views are not
+__SGI_ASSIGNABLE__ (like any other view.)
+* Unlike as in `std::list`, insertions into a list_of view may fail due to
+clashings with other views. This alters the semantics of the operations
+provided with respect to their analogues in `std::list`.
+* Elements in a list_of view are not mutable, and can only be changed
+by means of `replace` and `modify` member functions.
+
+Having these restrictions into account, list_of views are models of
+__SGI_REVERSIBLE_CONTAINER__, __SGI_FRONT_INSERTION_SEQUENCE__ and
+__SGI_BACK_INSERTION_SEQUENCE__.
+We only provide descriptions of those types and operations that are either
+not present in the concepts modeled or do not exactly conform to the
+requirements for these types of containers.
+
+    namespace boost {
+    namespace bimaps {
+    namespace views {
+
+    template< ``['-implementation defined parameter list-]`` >
+    class ``['-implementation defined view name-]``
+    {
+        public:
+
+        // types
+
+        typedef ``['-unspecified-]`` value_type;
+        typedef ``['-unspecified-]`` allocator_type;
+        typedef ``['-unspecified-]`` reference;
+        typedef ``['-unspecified-]`` const_reference;
+        typedef ``['-unspecified-]`` iterator;
+        typedef ``['-unspecified-]`` const_iterator;
+        typedef ``['-unspecified-]`` size_type;
+        typedef ``['-unspecified-]`` difference_type;
+        typedef ``['-unspecified-]`` pointer;
+        typedef ``['-unspecified-]`` const_pointer;
+        typedef ``['-unspecified-]`` reverse_iterator;
+        typedef ``['-unspecified-]`` const_reverse_iterator;
+
+        typedef ``['-unspecified-]`` info_type;
+
+        // construct/copy/destroy
+
+        this_type & operator=(const this_type & x);
+
+        template< class InputIterator >
+ void ``[link reference_list_of_assign_iterator_iterator assign]``(InputIterator first, InputIterator last);
+
+ void ``[link reference_list_of_assign_size_value assign]``(size_type n, const value_type & value);
+
+        allocator_type get_allocator() const;
+
+        // iterators
+
+        iterator               begin();
+        const_iterator         begin() const;
+
+        iterator               end();
+        const_iterator         end() const;
+
+        reverse_iterator       rbegin();
+        const_reverse_iterator rbegin() const;
+
+        reverse_iterator       rend();
+        const_reverse_iterator rend() const;
+
+        // capacity
+
+        bool      empty() const;
+
+        size_type size() const;
+
+        size_type max_size() const;
+
+ void ``[link reference_list_of_resize_size_value resize]``(size_type n, const value_type & x = value_type());
+
+        // access
+
+        const_reference front() const;
+        const_reference back() const;
+
+        // modifiers
+
+ std::pair<iterator,bool> ``[link reference_list_of_push_front_value push_front]``(const value_type & x);
+        void                     pop_front();
+
+ std::pair<iterator,bool> ``[link reference_list_of_push_back_value push_back]``(const value_type & x);
+        void                     pop_back();
+
+ std::pair<iterator,bool> ``[link reference_list_of_insert_iterator_value insert]``(iterator position, const value_type & x);
+
+ void ``[link reference_list_of_insert_iterator_size_value insert]``(iterator position, size_type n, const value_type & x);
+
+        template< class InputIterator >
+ void ``[link reference_list_of_insert_iterator_iterator_iterator insert]``(iterator position, InputIterator first, InputIterator last);
+
+ iterator ``[link reference_list_of_erase_iterator erase]``(iterator position); + iterator ``[link reference_list_of_erase_iterator_iterator erase]``(iterator first, iterator last);
+
+ bool ``[link reference_list_of_replace_iterator_value replace]``(iterator position, const value_type & x);
+
+        // Only in map views
+        // {
+
+          template< class CompatibleKey >
+ bool ``[link reference_list_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
+
+          template< class CompatibleData >
+ bool ``[link reference_list_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
+
+          template< class KeyModifier >
+ bool ``[link reference_list_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
+
+          template< class DataModifier >
+ bool ``[link reference_list_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
+
+        // }
+
+
+        void clear();
+
+        // list operations
+
+ void ``[link reference_list_of_splice_iterator_this splice]``(iterator position, this_type & x); + void ``[link reference_list_of_splice_iterator_this_iterator splice]``(iterator position, this_type & x, iterator i);
+        void splice(
+ iterator position, this_type & x, iterator first, iterator last);
+
+ void ``[link reference_list_of_remove_value remove]``(const value_type & value);
+
+        template< class Predicate >
+ void ``[link reference_list_of_remove_if_predicate remove_if]``(Predicate pred);
+
+        void ``[link reference_list_of_unique unique]``();
+
+        template< class BinaryPredicate >
+ void ``[link reference_list_of_unique_predicate unique]``(BinaryPredicate binary_pred);
+
+        void ``[link reference_list_of_merge_this merge]``(this_type & x);
+
+        template< class Compare >
+ void ``[link reference_list_of_merge_this_compare merge]``(this_type & x,Compare comp);
+
+        void ``[link reference_list_of_sort sort]``();
+
+        template< class Compare >
+        void ``[link reference_list_of_sort_compare sort]``(Compare comp);
+
+        void ``[link reference_list_of_reverse reverse]``();
+
+        // rearrange operations
+
+        void relocate(iterator position, iterator i);
+        void relocate(iterator position, iterator first, iterator last);
+
+    }
+
+    // view comparison
+
+    bool operator==(const this_type & v1, const this_type & v2 );
+    bool operator< (const this_type & v1, const this_type & v2 );
+    bool operator!=(const this_type & v1, const this_type & v2 );
+    bool operator> (const this_type & v1, const this_type & v2 );
+    bool operator>=(const this_type & v1, const this_type & v2 );
+    bool operator<=(const this_type & v1, const this_type & v2 );
+
+    } // namespace views
+    } // namespace bimap
+    } // namespace boost
+
+In the case of a `bimap< list_of<Left>, ... >`
+
+In the set view:
+
+    typedef signature-compatible with relation< Left, ... > key_type;
+    typedef signature-compatible with relation< Left, ... > value_type;
+
+In the left map view:
+
+    typedef  Left  key_type;
+    typedef  ...   data_type;
+
+    typedef signature-compatible with std::pair< Left, ... > value_type;
+
+In the right map view:
+
+    typedef  ...  key_type;
+    typedef  Left data_type;
+
+    typedef signature-compatible with std::pair< ... , Left > value_type;
+
+
+[#list_of_complexity_signature]
+
+[section Complexity signature]
+
+Here and in the descriptions of operations of `list_of` views, we adopt the
+scheme outlined in the
+[link complexity_signature_explanation complexity signature section].
+The complexity signature of a `list_of` view is:
+
+* copying: `c(n) = n * log(n)`,
+* insertion: `i(n) = 1` (constant),
+* hinted insertion: `h(n) = 1` (constant),
+* deletion: `d(n) = 1` (constant),
+* replacement: `r(n) = 1` (constant),
+* modifying: `m(n) = 1` (constant).
+
+[endsect]
+
+[section Instantiation types]
+
+`list_of` views are instantiated internally to `bimap` and specified
+by means of the collection type specifiers and the bimap itself.
+Instantiations are dependent on the following types:
+
+* `Value` from `list_of`,
+* `Allocator` from `bimap`,
+
+[endsect]
+
+[section Constructors, copy and assignment]
+
+As explained in the view concepts section, views do not have public
+constructors or destructors. Assignment, on the other hand, is provided.
+
+    this_type & operator=(const this_type & x);
+
+* [*Effects: ] `a = b;`
+where a and b are the `bimap` objects to which `*this` and `x` belong,
+respectively.
+* [*Returns: ] `*this`.
+
+
+[#reference_list_of_assign_iterator_iterator]
+
+    template< class InputIterator >
+    void assign(InputIterator first, InputIterator last);
+
+* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements of type
+`value_type` or a type convertible to `value_type`. first and last are not
+iterators into any views of the `bimap` to which this view belongs.
+`last` is reachable from `first`.
+* [*Effects: ] `clear(); insert(end(),first,last);`
+
+
+[#reference_list_of_assign_size_value]
+
+    void assign(size_type n, const value_type & value);
+
+* [*Effects: ] `clear(); for(size_type i = 0; i < n ; ++n) push_back(v);`
+
+
+[endsect]
+
+[section Capacity operations]
+
+[#reference_list_of_resize_size_value]
+
+    void resize(size_type n,const value_type& x=value_type());
+
+* [*Effects: ]
+`if( n > size() ) insert(end(), n - size(), x);`
+`else if( n < size() ) {`
+`    iterator it = begin();`
+`    std::advance(it, n);`
+`    erase(it, end());`
+`}`
+* [*Note:] If an expansion is requested, the size of the view is not
+guaranteed to be n after this operation (other views may ban insertions.)
+
+[endsect]
+
+[section Modifiers]
+
+[#reference_list_of_push_front_value]
+
+    std::pair<iterator,bool> push_front(const value_type& x);
+
+* [*Effects:] Inserts `x` at the beginning of the sequence if no other views
+of the `bimap` bans the insertion.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only +if insertion took place. On successful insertion, `p.first` points to the element +inserted; otherwise, `p.first` points to an element that caused the insertion to be +banned. Note that more than one element can be causing insertion not to be allowed.
+* [link list_of_complexity_signature [*Complexity:]] O(I(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_list_of_push_back_value]
+
+    std::pair<iterator,bool> push_back(const value_type & x);
+
+* [*Effects:] Inserts `x` at the end of the sequence if no other views of the
+`bimap` bans the insertion.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if +insertion took place. On successful insertion, `p.first` points to the element +inserted; otherwise, `p.first` points to an element that caused the insertion
+to be banned. Note that more than one element can be causing insertion not
+to be allowed.
+* [link list_of_complexity_signature [*Complexity:]] O(I(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_list_of_insert_iterator_value]
+
+ std::pair<iterator,bool> insert(iterator position, const value_type & x);
+
+* [*Requires: ] `position` is a valid `iterator` of the view.
+* [*Effects:] Inserts `x` before position if insertion is allowed by all other
+views of the `bimap`.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if +insertion took place. On successful insertion, `p.first` points to the element +inserted; otherwise, `p.first` points to an element that caused the insertion
+to be banned. Note that more than one element can be causing insertion not
+to be allowed.
+* [link list_of_complexity_signature
+[*Complexity:]] O(I(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_list_of_insert_iterator_size_value]
+
+    void insert(iterator position, size_type n, const value_type & x);
+
+* [*Requires: ] `position` is a valid `iterator` of the view.
+* [*Effects: ] `for(size_type i = 0; i < n; ++i) insert(position, x);`
+
+
+[#reference_list_of_insert_iterator_iterator_iterator]
+
+    template< class InputIterator>
+    void insert(iterator position,InputIterator first,InputIterator last);
+
+* [*Requires: ] `position` is a valid `iterator` of the view. `InputIterator` is
+a model of __SGI_INPUT_ITERATOR__ over elements of type `value_type`.
+`first` and `last` are not iterators into any view of the
+`bimap` to which this view belongs. `last` is reachable from `first`.
+* [*Effects: ] `while(first != last) insert(position, *first++);`
+* [link list_of_complexity_signature
+[*Complexity:]] O(m*I(n+m)), where m is the number of elements in `[first,last)`.
+* [*Exception safety:] Basic.
+
+
+[#reference_list_of_erase_iterator]
+
+    iterator erase(iterator position);
+
+* [*Requires: ] `position` is a valid dereferenceable `iterator` of the view.
+* [*Effects:] Deletes the element pointed to by `position`.
+* [*Returns:] An iterator pointing to the element immediately following the
+one that was deleted, or `end()` if no such element exists.
+* [link list_of_complexity_signature
+[*Complexity:]] O(D(n)).
+* [*Exception safety:] nothrow.
+
+
+[#reference_list_of_erase_iterator_iterator]
+
+    iterator erase(iterator first, iterator last);
+
+* [*Requires: ] `[first,last)` is a valid range of the view.
+* [*Effects:] Deletes the elements in `[first,last)`.
+* [*Returns: ] `last`.
+* [link list_of_complexity_signature
+[*Complexity:]] O(m*D(n)), where m is the number of elements in `[first,last)`.
+* [*Exception safety:] nothrow.
+
+
+[#reference_list_of_replace_iterator_value]
+
+    bool replace(iterator position,const value_type& x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the view.
+* [*Effects:] Assigns the value `x` to the element pointed to by `position` into
+the `bimap` to which the view belongs if replacing is allowed by
+all other views of the `bimap`.
+* [*Postconditions:] Validity of `position` is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link list_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation the `bimap` to which the view belongs remains in its
+original state.
+
+
+[#reference_list_of_replace_key_iterator_key]
+
+    template< class CompatibleKey >
+    bool replace_key(iterator position, const CompatibleKey & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `key_type`.
+* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed +to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
+all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link list_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_list_of_replace_data_iterator_data]
+
+    template< class CompatibleData >
+    bool replace_data(iterator position, const CompatibleData & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `data_type`.
+* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed +to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
+all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link list_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_list_of_modify_key_iterator_modifier]
+
+    template< class KeyModifier >
+    bool modify_key(iterator position, KeyModifier mod);
+
+* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `key_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+It is successful if the rearrangement is allowed by all other views of the `bimap`. +* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link list_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+
+[#reference_list_of_modify_data_iterator_modifier]
+
+    template< class DataModifier >
+    bool modify_data(iterator position, DataModifier mod);
+
+* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `data_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+It is successful if the rearrangement is allowed by all other views of the `bimap`. +* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link list_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+[/
+[#reference_list_of_modify_iterator_modifier]
+
+    template< class Modifier >
+    bool modify(iterator position,Modifier mod);
+
+* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of +type: `first_type&` and `second_type&` for ['Map View] and `left_type&` and `right_type&` +for ['Set View]. `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View] or calls `mod(e.left,e.right)`
+for ['Set View] where `e` is the element pointed to by `position` and
+rearranges `*position` into all the views of the `bimap`.
+Rearrangement on `list_of` views does not change the position of the element +with respect to the view; rearrangement on other views may or might not suceed.
+If the rearrangement fails, the element is erased.
+* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link list_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly `mod`), then the element pointed to by position is erased.
+]
+
+[endsect]
+
+[section List operations]
+
+`list_of` views provide the full set of list operations found in `std::list`; +the semantics of these member functions, however, differ from that of `std::list` +in some cases as insertions might not succeed due to banning by other views.
+Similarly, the complexity of the operations may depend on the other views
+belonging to the same `bimap`.
+
+
+[#reference_list_of_splice_iterator_this]
+
+    void splice(iterator position, this_type & x);
+
+* [*Requires: ] `position` is a valid iterator of the view. `&x!=this`.
+* [*Effects:] Inserts the contents of `x` before position, in the same order as
+they were in `x`. Those elements successfully inserted are erased from `x`.
+* [link list_of_complexity_signature
+[*Complexity:]] O(`x.size()`*I(n+`x.size()`) + `x.size()`*D(`x.size()`)).
+* [*Exception safety:] Basic.
+
+
+[#reference_list_of_splice_iterator_this_iterator]
+
+    void splice(iterator position, this_type & x,iterator i);
+
+* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
+dereferenceable iterator `x`.
+* [*Effects:] Inserts the element pointed to by `i` before position: if insertion +is successful, the element is erased from `x`. In the special case `&x==this`, +no copy or deletion is performed, and the operation is always successful. If
+`position==i`, no operation is performed.
+* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
+* [link list_of_complexity_signature
+[*Complexity:]] If `&x==this`, constant; otherwise O(I(n) + D(n)).
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, strong.
+
+
+[#reference_list_of_splice_iterator_this_iterator_iterator]
+
+ void splice(iterator position, this_type & x, iterator first, iterator last);
+
+* [*Requires: ] `position` is a valid iterator of the view. `first` and `last` are +valid iterators of `x`. last is reachable from `first`. position is not in the
+range `[first,last)`.
+* [*Effects:] For each element in the range `[first,last)`, insertion is tried +before position; if the operation is successful, the element is erased from x. +In the special case `&x==this`, no copy or deletion is performed, and insertions
+are always successful.
+* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
+* [link list_of_complexity_signature
+[*Complexity:]] If `&x==this`, constant; otherwise O(m*I(n+m) + m*D(x.size()))
+where m is the number of elements in `[first,last)`.
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
+
+
+[#reference_list_of_remove_value]
+
+    void remove(const value_type & value);
+
+* [*Effects:] Erases all elements of the view which compare equal to `value`.
+* [link list_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_list_of_remove_if_predicate]
+
+    template< class Predicate >
+    void remove_if(Predicate pred);
+
+* [*Effects:] Erases all elements `x` of the view for which `pred(x)` holds.
+* [link list_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_list_of_unique]
+
+    void unique();
+
+* [*Effects:] Eliminates all but the first element from every consecutive
+group of equal elements referred to by the iterator `i` in the range
+`[first+1,last)` for which `*i==*(i-1)`.
+* [link list_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_list_of_unique_predicate]
+
+    template< class BinaryPredicate >
+    void unique(BinaryPredicate binary_pred);
+
+* [*Effects:] Eliminates all but the first element from every consecutive
+group of elements referred to by the iterator i in the range \[first+1,last)
+for which `binary_pred(*i,*(i-1))` holds.
+* [link list_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_list_of_merge_this]
+
+    void merge(this_type & x);
+
+* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
+Both the view and `x` are sorted according to `std::less<value_type>`.
+* [*Effects:] Attempts to insert every element of `x` into the corresponding +position of the view (according to the order). Elements successfully inserted +are erased from `x`. The resulting sequence is stable, i.e. equivalent elements
+of either container preserve their relative position. In the special case
+`&x==this`, no operation is performed.
+* [*Postconditions:] Elements in the view and remaining elements in `x` are sorted. +Validity of iterators to the view and of non-erased elements of `x` references
+is preserved.
+* [link list_of_complexity_signature
+[*Complexity:]] If `&x==this`, constant; otherwise
+O(n + `x.size()`*I(n+`x.size()`) + `x.size()`*D(`x.size()`)).
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
+
+
+[#reference_list_of_merge_this_compare]
+
+    template< class Compare >
+    void merge(this_type & x, Compare comp);
+
+* [*Requires:] Compare is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`. Both the view
+and `x` are sorted according to `comp`.
+* [*Effects:] Attempts to insert every element of `x` into the corresponding position +of the view (according to `comp`). Elements successfully inserted are erased from `x`. +The resulting sequence is stable, i.e. equivalent elements of either container preserve +their relative position. In the special case `&x==this`, no operation is performed. +* [*Postconditions:] Elements in the view and remaining elements in `x` are sorted +according to `comp`. Validity of iterators to the view and of non-erased elements
+of `x` references is preserved.
+* [link list_of_complexity_signature
+[*Complexity:]] If `&x==this`, constant;
+otherwise O(n + `x.size()`*I(n+`x.size()`) + `x.size()`*D(`x.size()`)).
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
+
+
+[#reference_list_of_sort]
+
+    void sort();
+
+* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over value_type. +* [*Effects:] Sorts the view according to `std::less<value_type>`. The sorting is stable,
+i.e. equivalent elements preserve their relative position.
+* [*Postconditions:] Validity of iterators and references is preserved.
+* [*Complexity:] O(n*log(n)).
+* [*Exception safety:] nothrow if `std::less<value_type>` does not throw; otherwise, basic.
+
+
+[#reference_list_of_sort_compare]
+
+    template< typename Compare >
+    void sort(Compare comp);
+
+* [*Requires:] Compare is a __SGI_STRICT_WEAK_ORDERING__ over value_type.
+* [*Effects:] Sorts the view according to comp. The sorting is stable, i.e. equivalent
+elements preserve their relative position.
+* [*Postconditions:] Validity of iterators and references is preserved.
+* [*Complexity:] O(n*log(n)).
+* [*Exception safety:] nothrow if comp does not throw; otherwise, basic.
+
+
+[#reference_list_of_reverse]
+
+    void reverse();
+
+* [*Effects:] Reverses the order of the elements in the view.
+* [*Postconditions:] Validity of iterators and references is preserved.
+* [*Complexity:] O(n).
+* [*Exception safety:] nothrow.
+
+
+[endsect]
+
+[section Rearrange operations]
+
+These operations, without counterpart in `std::list` (although splice provides +partially overlapping functionality), perform individual and global repositioning
+of elements inside the index.
+
+
+[#reference_list_of_relocate_iterator_iterator]
+
+    void relocate(iterator position, iterator i);
+
+* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
+dereferenceable iterator of the view.
+* [*Effects:] Inserts the element pointed to by `i` before `position`.
+If `position==i`, no operation is performed.
+* [*Postconditions:] No iterator or reference is invalidated.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+[#reference_list_of_relocate_iterator_iterator_iterator]
+
+    void relocate(iterator position, iterator first, iterator last);
+
+* [*Requires: ] `position` is a valid iterator of the view. `first` and `last` are +valid iterators of the view. `last` is reachable from `first`. `position` is not
+in the range `[first,last)`.
+* [*Effects:] The range of elements `[first,last)` is repositioned just before
+`position`.
+* [*Postconditions:] No iterator or reference is invalidated.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+[endsect]
+
+[section Serialization]
+
+Views cannot be serialized on their own, but only as part of the
+`bimap` into which they are embedded. In describing the additional
+preconditions and guarantees associated to `list_of` views with respect to
+serialization of their embedding containers, we use the concepts defined in the
+`bimap` serialization section.
+
+[blurb [*Operation:] saving of a `bimap` b to an output archive
+(XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container.
+
+
+[blurb [*Operation:] loading of a `bimap` b' from an input archive
+(XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container.
+[*Postconditions:] On successful loading, each of the elements of
+`[begin(), end())`
+is a restored copy of the corresponding element in
+`[m.get<i>().begin(), m.get<i>().end())`,
+where `i` is the position of the `list_of` view in the container.
+
+
+[blurb [*Operation:] saving of an `iterator` or `const_iterator` it to an output
+archive (XML archive) ar.]
+
+* [*Requires: ] `it` is a valid iterator of the view. The associated
+`bimap` has been previously saved.
+
+
+[blurb [*Operation:] loading of an `iterator` or `const_iterator it`' from an input
+archive (XML archive) ar.]
+
+* [*Postconditions:] On successful loading, if it was dereferenceable then `*it`' is the
+restored copy of `*it`, otherwise `it`'` == end()`.
+* [*Note:] It is allowed that `it` be a `const_iterator` and the restored `it`' an iterator,
+or viceversa.
+
+
+[endsect]
+[endsect]
+
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/reference/set_of.qbk  Sun Feb  7 21:50:27 2010
@@ -0,0 +1,935 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section set_of Reference]
+
+[section Header "boost/bimap/set_of.hpp" synopsis]
+
+    namespace boost {
+    namespace bimaps {
+
+
+    template
+    <
+        class KeyType,
+        class KeyCompare = std::less< KeyType >
+    >
+    struct set_of;
+
+
+    template
+    <
+        class KeyCompare = std::less< _relation >
+    >
+    struct set_of_relation;
+
+
+    } // namespace bimap
+    } // namespace boost
+
+
+[endsect]
+
+[section Header "boost/bimap/multiset_of.hpp" synopsis]
+
+
+    namespace boost {
+    namespace bimaps {
+
+
+    template
+    <
+        class KeyType,
+        class KeyCompare = std::less< KeyType >
+    >
+    struct multiset_of;
+
+
+    template
+    <
+        class KeyCompare = std::less< _relation >
+    >
+    struct multiset_of_relation;
+
+
+    } // namespace bimap
+    } // namespace boost
+
+
+[endsect]
+
+
+[section Collection type specifiers set_of and multiset_of]
+
+These collection type specifiers allow for insertion of sets disallowing or
+allowing duplicate elements, respectively. The syntaxes of `set_of` and
+`multiset_of` coincide, so they are described together.
+
+[endsect]
+
+
+[section \[multi\]set_of Views]
+
+A \[multi\]set_of set view is a std::\[multi\]set signature-compatible
+interface to the underlying heap of elements contained in a `bimap`.
+
+There are two variants: set_of, which does not allow duplicate elements
+(with respect to its associated comparison predicate) and multiset_of,
+which does accept those duplicates. The interface of these two variants
+is largely the same, so they are documented together with their
+differences explicitly noted where they exist.
+
+If you look the bimap from a side, you will use a map view, and if you
+look at it as a whole, you will be using a set view.
+
+
+
+    namespace boost {
+    namespace bimaps {
+    namespace views {
+
+    template< ``['-implementation defined parameter list-]`` >
+    class ``['-implementation defined view name-]``
+    {
+        public:
+
+        typedef ``['-unspecified-]`` key_type;
+        typedef ``['-unspecified-]`` value_type;
+        typedef ``['-unspecified-]`` key_compare;
+        typedef ``['-unspecified-]`` value_compare;
+        typedef ``['-unspecified-]`` allocator_type;
+        typedef ``['-unspecified-]`` reference;
+        typedef ``['-unspecified-]`` const_reference;
+        typedef ``['-unspecified-]`` iterator;
+        typedef ``['-unspecified-]`` const_iterator;
+        typedef ``['-unspecified-]`` size_type;
+        typedef ``['-unspecified-]`` difference_type;
+        typedef ``['-unspecified-]`` pointer;
+        typedef ``['-unspecified-]`` const_pointer;
+        typedef ``['-unspecified-]`` reverse_iterator;
+        typedef ``['-unspecified-]`` const_reverse_iterator;
+
+        typedef ``['-unspecified-]`` info_type;
+
+        this_type & operator=(const this_type & x);
+
+        allocator_type get_allocator() const;
+
+        // iterators
+
+        iterator               begin();
+        const_iterator         begin() const;
+
+        iterator               end();
+        const_iterator         end() const;
+
+        reverse_iterator       rbegin();
+        const_reverse_iterator rbegin() const;
+
+        reverse_iterator       rend();
+        const_reverse_iterator rend() const;
+
+        // capacity
+
+        bool      empty() const;
+
+        size_type size() const;
+
+        size_type max_size() const;
+
+        // modifiers
+
+ std::pair<iterator,bool> ``[link reference_set_of_insert_value insert]``(const value_type & x);
+
+ iterator ``[link reference_set_of_insert_iterator_value insert]``(iterator position, const value_type & x);
+
+        template< class InputIterator>
+ void ``[link reference_set_of_insert_iterator_iterator insert]``(InputIterator first, InputIterator last);
+
+ iterator ``[link reference_set_of_erase_iterator erase]``(iterator position);
+
+        template< class CompatibleKey >
+ size_type ``[link reference_set_of_erase_key erase]``(const CompatibleKey & x);
+
+ iterator ``[link reference_set_of_erase_iterator_iterator erase]``(iterator first, iterator last);
+
+ bool ``[link reference_set_of_replace_iterator_value replace]``(iterator position, const value_type& x);
+
+        // Only in map views
+        // {
+
+          template< class CompatibleKey >
+ bool ``[link reference_set_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
+
+          template< class CompatibleData >
+ bool ``[link reference_set_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
+
+          template< class KeyModifier >
+ bool ``[link reference_set_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
+
+          template< class DataModifier >
+ bool ``[link reference_set_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
+
+        // }
+
+        void swap(this_type & x);
+
+        void clear();
+
+        // observers
+
+        key_compare    key_comp() const;
+
+        value_compare  value_comp() const;
+
+        // set operations
+
+        template< class CompatibleKey >
+ iterator ``[link reference_set_of_find_key find]``(const CompatibleKey & x);
+
+        template< class CompatibleKey >
+ const_iterator ``[link reference_set_of_find_key find]``(const CompatibleKey & x) const;
+
+
+        template< class CompatibleKey >
+ size_type ``[link reference_set_of_count_key count]``(const CompatibleKey & x) const;
+
+
+        template< class CompatibleKey >
+ iterator ``[link reference_set_of_lower_bound_key lower_bound]``(const CompatibleKey & x);
+
+        template< class CompatibleKey >
+ const_iterator ``[link reference_set_of_lower_bound_key lower_bound]``(const CompatibleKey & x) const;
+
+
+        template< class CompatibleKey >
+ iterator ``[link reference_set_of_upper_bound_key upper_bound]``(const CompatibleKey & x);
+
+        template< class CompatibleKey >
+ const_iterator ``[link reference_set_of_upper_bound_key upper_bound]``(const CompatibleKey & x) const;
+
+
+        template< class CompatibleKey >
+        std::pair<iterator,iterator>
+ ``[link reference_set_of_equal_range_key equal_range]``(const CompatibleKey & x);
+
+        template< class CompatibleKey >
+        std::pair<const_iterator,const_iterator>
+ ``[link reference_set_of_equal_range_key equal_range]``(const CompatibleKey & x) const;
+
+        // Only in maps views
+        // {
+
+        template< class LowerBounder, class UpperBounder>
+ std::pair<iterator,iterator> ``[link reference_set_of_range_lower_upper range]``(
+            LowerBounder lower, UpperBounder upper);
+
+        template< class LowerBounder, class UpperBounder>
+ std::pair<const_iterator,const_iterator> ``[link reference_set_of_range_lower_upper range]``(
+            LowerBounder lower, UpperBounder upper) const;
+
+        typedef ``['-unspecified-]`` data_type;
+
+          // Only in for `set_of` collection type
+          // {
+
+          template< class CompatibleKey >
+ const data_type & ``[link reference_set_of_at_key_const at]``(const CompatibleKey & k) const;
+
+            // Only if the other collection type is mutable
+            // {
+
+            template< class CompatibleKey >
+ data_type & ``[link reference_set_of_operator_bracket_key operator\[\]]``(const CompatibleKey & k);
+
+            template< class CompatibleKey >
+ data_type & ``[link reference_set_of_at_key at]``(const CompatibleKey & k);
+
+            // }
+
+            // Only if info_hook is used
+            // {
+
+            template< class CompatibleKey >
+ info_type & ``[link reference_set_of_info_at_key info_at]``(const CompatibleKey & k);
+
+            template< class CompatibleKey >
+ const info_type & ``[link reference_set_of_info_at_key info_at]``(const CompatibleKey & k) const;
+
+            // }
+
+          // }
+
+        // }
+    };
+
+    // view comparison
+
+    bool operator==(const this_type & v1, const this_type & v2 );
+    bool operator< (const this_type & v1, const this_type & v2 );
+    bool operator!=(const this_type & v1, const this_type & v2 );
+    bool operator> (const this_type & v1, const this_type & v2 );
+    bool operator>=(const this_type & v1, const this_type & v2 );
+    bool operator<=(const this_type & v1, const this_type & v2 );
+
+    } // namespace views
+    } // namespace bimap
+    } // namespace boost
+
+
+
+[/ Functions that may be implemented some day
+
+        template< class Modifier>
+ bool ``[link reference_set_of_modify_iterator_modifier modify]``(iterator position, Modifier mod);
+
+        template< class CompatibleKey, class CompatibleCompare >
+        iterator find(const CompatibleKey & x,
+                      const CompatibleCompare & comp);
+
+        template< class CompatibleKey, class CompatibleCompare >
+        const_iterator find(const CompatibleKey & x,
+                            const CompatibleCompare & comp) const;
+
+        template< class CompatibleKey, class CompatibleCompare >
+        size_type count(const CompatibleKey & x,
+                        const CompatibleCompare & comp) const;
+
+        template< class CompatibleKey, class CompatibleCompare >
+        iterator lower_bound(const CompatibleKey & x,
+                             const CompatibleCompare & comp);
+
+        template< class CompatibleKey, class CompatibleCompare >
+        const_iterator lower_bound(const CompatibleKey & x,
+                                   const CompatibleCompare & comp) const;
+
+        template< class CompatibleKey, class CompatibleCompare >
+        iterator upper_bound(const CompatibleKey & x,
+                             const CompatibleCompare & comp);
+
+        template< class CompatibleKey, class CompatibleCompare >
+        const_iterator upper_bound(const CompatibleKey & x,
+                                   const CompatibleCompare & comp) const;
+
+        template< class CompatibleKey, class CompatibleCompare >
+        std::pair<iterator,iterator> equal_range(
+            const CompatibleKey & x, const CompatibleCompare & comp);
+
+        template< class CompatibleKey, class CompatibleCompare >
+        std::pair<const_iterator,const_iterator> equal_range(
+            const CompatibleKey & x, const CompatibleCompare & comp) const;
+
+]
+
+
+In the case of a `bimap< {multi}set_of<Left>, ... >`
+
+In the set view:
+
+    typedef signature-compatible with relation<       Left, ... > key_type;
+ typedef signature-compatible with relation< const Left, ... > value_type;
+
+In the left map view:
+
+    typedef  Left  key_type;
+    typedef  ...   data_type;
+
+ typedef signature-compatible with std::pair< const Left, ... > value_type;
+
+In the right map view:
+
+    typedef  ...  key_type;
+    typedef  Left data_type;
+
+ typedef signature-compatible with std::pair< ... ,const Left > value_type;
+
+
+[#set_of_complexity_signature]
+
+[section Complexity signature]
+
+Here and in the descriptions of operations of this view, we adopt the
+scheme outlined in the [link complexity_signature_explanation complexity signature section].
+The complexity signature of \[multi\]set_of view is:
+
+* copying: `c(n) = n * log(n)`,
+* insertion: `i(n) = log(n)`,
+* hinted insertion: `h(n) = 1` (constant) if the hint element precedes the point of
+insertion, `h(n) = log(n)` otherwise,
+* deletion: `d(n) = 1` (amortized constant),
+* replacement: `r(n) = 1` (constant) if the element position does not change,
+`r(n) = log(n)` otherwise,
+* modifying: `m(n) = 1` (constant) if the element position does not change,
+`m(n) = log(n)` otherwise.
+
+[endsect]
+
+[section Instantiation types]
+
+Set views are instantiated internally to a `bimap`.
+Instantiations are dependent on the following types:
+
+* `Value` from the set specifier,
+* `Allocator` from `bimap`,
+* `Compare` from the set specifier.
+
+`Compare` is a __SGI_STRICT_WEAK_ORDERING__ on elements of `Value`.
+
+[endsect]
+
+[section Constructors, copy and assignment]
+
+Set views do not have public constructors or destructors.
+Assignment, on the other hand, is provided.
+
+    this_type & operator=(const this_type & x);
+
+* [*Effects: ] `a = b;`
+where a and b are the `bimap` objects to which `*this` and x
+belong, respectively.
+* [*Returns: ] `*this`.
+
+
+
+[endsect]
+
+[section Modifiers]
+
+[#reference_set_of_insert_value]
+
+    std::pair<iterator,bool> insert(const value_type & x);
+
+* [*Effects:] Inserts `x` into the `bimap` to which the set view belongs if
+ * the set view is non-unique OR no other element with equivalent key exists,
+    * AND insertion is allowed by the other set specifications the `bimap`.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if insertion +took place. On successful insertion, `p.first` points to the element inserted; +otherwise, `p.first` points to an element that caused the insertion to be banned.
+Note that more than one element can be causing insertion not to be allowed.
+* [link set_of_complexity_signature
+[*Complexity:]] O(I(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_set_of_insert_iterator_value]
+
+    iterator insert(iterator position, const value_type & x);
+
+* [*Requires: ] `position` is a valid iterator of the view.
+* [*Effects: ] `position` is used as a hint to improve the efficiency of the operation. Inserts `x` into the `bimap` to which the view belongs if + * the set view is non-unique OR no other element with equivalent key exists,
+    * AND insertion is allowed by all other views of the `bimap`.
+* [*Returns:] On successful insertion, an iterator to the newly inserted
+element. Otherwise, an iterator to an element that caused the insertion to be +banned. Note that more than one element can be causing insertion not to be allowed.
+* [link set_of_complexity_signature
+[*Complexity:]] O(H(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_set_of_insert_iterator_iterator]
+
+    template< class InputIterator >
+    void insert(InputIterator first, InputIterator last);
+
+* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements of +type `value_type` or a type convertible to value_type. `first` and `last` are not
+iterators into any view of the `bimap` to which this index
+belongs. `last` is reachable from `first`.
+* [*Effects: ]
+`iterator hint = end()`;
+`while( first != last ) hint = insert( hint, *first++ );`
+* [link set_of_complexity_signature
+[*Complexity:]] O(m*H(n+m)), where m is the number of elements in
+`[first, last)`.
+* [*Exception safety:] Basic.
+
+
+[#reference_set_of_erase_iterator]
+
+    iterator erase(iterator position);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator if the set view.
+* [*Effects:] Deletes the element pointed to by `position`.
+* [*Returns:] An iterator pointing to the element immediately following
+the one that was deleted, or `end()` if no such element exists.
+* [link set_of_complexity_signature
+[*Complexity:]] O(D(n)).
+* [*Exception safety:] nothrow.
+
+
+[#reference_set_of_erase_key]
+
+    template< class CompatibleKey >
+    size_type erase(const CompatibleKey & x);
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Deletes the elements with key equivalent to `x`.
+* [*Returns:] Number of elements deleted.
+* [link set_of_complexity_signature
+[*Complexity:]] O(log(n) + m*D(n)), where m is the number of elements deleted.
+* [*Exception safety:] Basic.
+
+
+[#reference_set_of_erase_iterator_iterator]
+
+    iterator erase(iterator first, iterator last);
+
+* [*Requires: ] `[first,last)` is a valid range of the view.
+* [*Effects:] Deletes the elements in `[first,last)`.
+* [*Returns:] last.
+* [link set_of_complexity_signature
+[*Complexity:]] O(log(n) + m*D(n)), where m is the number of elements
+in `[first,last)`.
+* [*Exception safety:] nothrow.
+
+
+[#reference_set_of_replace_iterator_value]
+
+    bool replace(iterator position, const value_type& x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view. +* [*Effects:] Assigns the value `x` to the element pointed to by `position` into
+the `bimap` to which the set view belongs if, for the value `x`
+ * the set view is non-unique OR no other element with equivalent key exists
+(except possibly `*position`),
+    * AND replacing is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link set_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_set_of_replace_key_iterator_key]
+
+    template< class CompatibleKey >
+    bool replace_key(iterator position, const CompatibleKey & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `key_type`.
+* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed
+to by `position` into the `bimap` to which the set view belongs if,
+ * the map view is non-unique OR no other element with equivalent key exists
+(except possibly `*position`),
+    * AND replacing is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link set_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_set_of_replace_data_iterator_data]
+
+    template< class CompatibleData >
+    bool replace_data(iterator position, const CompatibleData & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `data_type`.
+* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed
+to by `position` into the `bimap` to which the set view belongs if,
+ * the map view is non-unique OR no other element with equivalent key exists
+(except possibly `*position`),
+    * AND replacing is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link set_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_set_of_modify_key_iterator_modifier]
+
+    template< class KeyModifier >
+    bool modify_key(iterator position, KeyModifier mod);
+
+* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `key_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+Rearrangement is successful if
+ * the map view is non-unique OR no other element with equivalent key exists,
+    * AND rearrangement is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link set_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+
+[#reference_set_of_modify_data_iterator_modifier]
+
+    template< class DataModifier >
+    bool modify_data(iterator position, DataModifier mod);
+
+* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `data_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+Rearrangement is successful if
+ * the oppositte map view is non-unique OR no other element with equivalent key in that
+view exists,
+    * AND rearrangement is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link set_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+[/
+
+[#reference_set_of_modify_iterator_modifier]
+
+    template< class Modifier >
+    bool modify(iterator position, Modifier mod);
+
+* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of +type: `first_type&` and `second_type&` for ['Map View] or `left_type&` and `right_type&`
+['Set View]; `position` is a valid dereferenceable iterator of the view.
+* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View] or Calls `mod(e.left,e.right)` +for ['Set View] where e is the element pointed to by position and rearranges `*position`
+into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+Rearrangement is successful if
+ * the view is non-unique OR no other element with equivalent key exists,
+    * AND rearrangement is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link set_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+
+]
+
+[endsect]
+
+[section Set operations]
+
+`[multi]set_of` views provide the full lookup functionality required by
+__SGI_SORTED_ASSOCIATIVE_CONTAINER__ and __SGI_UNIQUE_ASSOCIATIVE_CONTAINER__,
+namely `find`, `count`, `lower_bound`, `upper_bound` and `equal_range`.
+Additionally, these member functions are templatized to allow for non-standard
+arguments, so extending the types of search operations allowed.
+
+[/
+The kinds of arguments permissible when invoking the lookup member functions
+are defined by the following concept.
+
+Consider a __SGI_STRICT_WEAK_ORDERING__ `Compare` over values of type `Key`. A pair of +types `(CompatibleKey, CompatibleCompare)` is said to be a ['compatible extension]
+of Compare if
+
+* `CompatibleCompare` is a __SGI_BINARY_PREDICATE__ over `(Key, CompatibleKey)`, +* `CompatibleCompare` is a __SGI_BINARY_PREDICATE__ over `(CompatibleKey, Key)`,
+* if `c_comp(ck,k1)` then `!c_comp(k1,ck)`,
+* if `!c_comp(ck,k1)` and `!comp(k1,k2)` then `!c_comp(ck,k2)`,
+* if `!c_comp(k1,ck)` and `!comp(k2,k1)` then `!c_comp(k2,ck)`,
+
+for every `c_comp` of type `CompatibleCompare`, `comp` of type `Compare`, `ck` of type
+`CompatibleKey` and `k1`, `k2` of type `Key`.
+]
+A type `CompatibleKey` is said to be a ['compatible key] of `Compare`
+if `(CompatibleKey, Compare)` is a compatible extension of `Compare`. This implies +that `Compare`, as well as being a strict weak ordering, accepts arguments of type +`CompatibleKey`, which usually means it has several overloads of `operator()`.
+
+[/
+In the context of a compatible extension or a compatible key, the expressions +"equivalent", "less than" and "greater than" take on their obvious interpretations.
+]
+
+[#reference_set_of_find_key]
+
+    template< class CompatibleKey >
+    iterator find(const CompatibleKey & x);
+
+    template< class CompatibleKey >
+    const_iterator find(const CompatibleKey & x) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns a pointer to an element whose key is equivalent to `x`, or
+`end()` if such an element does not exist.
+* [*Complexity:] O(log(n)).
+
+[/
+    template< class CompatibleKey, class CompatibleCompare >
+    iterator find(const CompatibleKey & x,
+                  const CompatibleCompare & comp);
+
+    template< class CompatibleKey, class CompatibleCompare >
+    const_iterator find(const CompatibleKey & x,
+                        const CompatibleCompare & comp) const;
+
+* [*Requires: ] `(CompatibleKey, CompatibleCompare)` is a compatible extension of
+`key_compare.`
+* [*Effects:] Returns a pointer to an element whose key is
+equivalent to `x`, or `end()` if such an element does not exist.
+* [*Complexity:] O(log(n)).
+]
+
+[#reference_set_of_count_key]
+
+    template< class CompatibleKey >
+    size_type count(const key_type & x) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns the number of elements with key equivalent to `x`.
+* [*Complexity:] O(log(n) + count(x)).
+
+[/
+    template< class CompatibleKey, class CompatibleCompare >
+    size_type count(const CompatibleKey & x,
+                    const CompatibleCompare & comp) const;
+
+* [*Requires: ] `(CompatibleKey, CompatibleCompare)` is a compatible extension of
+`key_compare.`
+* [*Effects:] Returns the number of elements with key equivalent to `x`.
+* [*Complexity:] O(log(n) + count(x)).
+]
+
+[#reference_set_of_lower_bound_key]
+
+    template< class CompatibleKey >
+    iterator lower_bound(const key_type & x);
+
+    template< class CompatibleKey >
+    const_iterator lower_bound(const key_type & x) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns an iterator pointing to the first element with key not
+less than `x`, or `end()` if such an element does not exist.
+* [*Complexity:] O(log(n)).
+
+
+[#reference_set_of_upper_bound_key]
+
+    template< class CompatibleKey >
+    iterator upper_bound(const key_type & x);
+
+    template< class CompatibleKey >
+    const_iterator upper_bound(const key_type & x) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns an iterator pointing to the first element with key greater
+than `x`, or `end()` if such an element does not exist.
+* [*Complexity:] O(log(n)).
+
+
+[#reference_set_of_equal_range_key]
+
+    template< class CompatibleKey >
+    std::pair<iterator,iterator>
+        equal_range(const key_type & x);
+
+    template< class CompatibleKey >
+    std::pair<const_iterator,const_iterator>
+        equal_range(const key_type & x) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Equivalent to `make_pair(lower_bound(x),upper_bound(x))`.
+* [*Complexity:] O(log(n)).
+
+
+
+[endsect]
+
+[section Range operations]
+
+The member function range is not defined for sorted associative
+containers, but `[multi]set_of` map views provide it as a convenient utility.
+A range or interval is defined by two conditions for the lower and upper
+bounds, which are modelled after the following concepts.
+
+Consider a __SGI_STRICT_WEAK_ORDERING__ `Compare` over values of type Key.
+A type `LowerBounder` is said to be a lower bounder of `Compare` if
+
+* `LowerBounder` is a `Predicate` over `Key`,
+* if `lower(k1)` and `!comp(k2,k1)` then `lower(k2)`,
+
+for every `lower` of type `LowerBounder`, `comp` of type `Compare`, and `k1`, `k2`
+of type `Key`.
+Similarly, an upper bounder is a type `UpperBounder` such that
+
+* `UpperBounder` is a `Predicate` over `Key`,
+* if `upper(k1)` and `!comp(k1,k2)` then `upper(k2)`,
+
+for every `upper` of type `UpperBounder`, `comp` of type `Compare`, and `k1`, `k2`
+of type `Key`.
+
+[#reference_set_of_range_lower_upper]
+
+    template< class LowerBounder, class UpperBounder>
+    std::pair<const_iterator,const_iterator> range(
+        LowerBounder lower, UpperBounder upper) const;
+
+* [*Requires: ] `LowerBounder` and `UpperBounder` are a lower and upper bounder of
+`key_compare`, respectively.
+* [*Effects:] Returns a pair of iterators pointing to
+the beginning and one past the end of the subsequence of elements satisfying +lower and upper simultaneously. If no such elements exist, the iterators both +point to the first element satisfying lower, or else are equal to `end()` if this
+latter element does not exist.
+* [*Complexity:] O(log(n)).
+* [*Variants:] In place of lower or upper (or both), the singular value
+`boost::bimap::unbounded` can be provided. This acts as a predicate which
+all values of type `key_type` satisfy.
+* [*Note:] Only provided for map views.
+
+[endsect]
+
+[section at(), info_at() and operator\[\] - set_of only]
+
+[#reference_set_of_at_key_const]
+
+    template< class CompatibleKey >
+    const data_type & at(const CompatibleKey & k) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns the `data_type` reference that is associated with `k`, or
+throws `std::out_of_range` if such key does not exist.
+* [*Complexity:] O(log(n)).
+* [*Note:] Only provided when `set_of` is used.
+
+The symmetry of bimap imposes some constraints on `operator[]` and the
+non constant version of at() that are not found in `std::maps`.
+Tey are only provided if the other collection type is mutable
+(`list_of`, `vector_of` and `unconstrained_set_of`).
+
+[#reference_set_of_operator_bracket_key]
+
+    template< class CompatibleKey >
+    data_type & operator[](const CompatibleKey & k);
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects: ] `return insert(value_type(k,data_type()))->second;`
+* [*Complexity:] O(log(n)).
+* [*Note:] Only provided when `set_of` is used and the other collection
+type is mutable.
+
+[#reference_set_of_at_key]
+
+    template< class CompatibleKey >
+    data_type & at(const CompatibleKey & k);
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects: ] Returns the `data_type` reference that is associated with `k`, or
+throws `std::out_of_range` if such key does not exist.
+* [*Complexity:] O(log(n)).
+* [*Note:] Only provided when `set_of` is used and the other collection
+type is mutable.
+
+[/
+The symmetry of bimap imposes some constraints on `operator[]` that are
+not found in `std::maps`. If other views are unique,
+`bimap::duplicate_value` is thrown whenever an assignment is attempted to
+a value that is already a key in these views. As for
+`bimap::value_not_found`, this exception is thrown while trying to access
+a non-existent key: this behaviour differs from that of `std::map`, which
+automatically assigns a default value to non-existent keys referred to
+by `operator[]`.
+
+    const data_type & operator[](const typename key_type & k) const;
+
+* [*Effects:] Returns the `data_type` reference that is associated with `k`, or
+throws `bimap::value_not_found` if such an element does not exist.
+* [*Complexity:] O(log(n)).
+
+
+ ``['-unspecified data_type proxy-]`` operator[](const typename key_type & k);
+
+* [*Effects:] Returns a proxy to a `data_type` associated with `k` and the
+bimap. The proxy behaves as a reference to the `data_type` object. If this
+proxy is read and `k` was not in the bimap, the bimap::value_not_found is
+thrown. If it is written then `bimap::duplicate_value` is thrown if the
+assignment is not allowed by one of the other views of the `bimap`.
+* [link set_of_complexity_signature
+[*Complexity:]] If the assignment operator of the proxy is not used, then
+the order is O(log(n)). If it is used, the order is O(I(n)) if `k` was not
+in the bimap and O(R(n)) if it existed in the bimap.
+]
+
+
+[#reference_set_of_info_at_key]
+
+    template< class CompatibleKey >
+    info_type & info_at(const CompatibleKey & k);
+
+    template< class CompatibleKey >
+    const info_type & info_at(const CompatibleKey & k) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns the `info_type` reference that is associated with `k`, or
+throws `std::out_of_range` if such key does not exist.
+* [*Complexity:] O(log(n)).
+* [*Note:] Only provided when `set_of` and `info_hook` are used
+
+
+[endsect]
+
+[section Serialization]
+
+Views cannot be serialized on their own, but only as part of the `bimap`
+into which they are embedded. In describing the additional preconditions and guarantees +associated to `[multi]set_of` views with respect to serialization of their embedding containers,
+we use the concepts defined in the `bimap` serialization section.
+
+[blurb [*Operation:] saving of a `bimap` m to an output archive (XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container.
+
+
+[blurb [*Operation:] loading of a `bimap` m' from an input archive (XML archive) ar.]
+
+* [*Requires:] In addition to the general requirements, `value_comp()` must be +serialization-compatible with `m.get<i>().value_comp()`, where i is the position
+of the ordered view in the container.
+* [*Postconditions:] On successful loading, each of the elements of `[begin(), end())` +is a restored copy of the corresponding element in `[m.get<i>().begin(), m.get<i>().end())`.
+
+
+
+[blurb [*Operation:] saving of an iterator or `const_iterator` it to an output archive
+(XML archive) ar.]
+
+* [*Requires: ] `it` is a valid iterator of the view. The associated `bimap`
+has been previously saved.
+
+
+[blurb [*Operation:] loading of an `iterator` or `const_iterator` `it`' from an input archive (
+XML archive) ar.]
+
+* [*Postconditions:] On successful loading, if it was dereferenceable then `*it`' is the
+restored copy of `*it`, otherwise `it`'` == end()`.
+* [*Note:] It is allowed that it be a `const_iterator` and the restored `it`' an iterator,
+or viceversa.
+
+
+[endsect]
+[endsect]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/reference/unconstrained_set_of.qbk Sun Feb 7 21:50:27 2010
@@ -0,0 +1,123 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section unconstrained_set_of Reference]
+
+[section Header "boost/bimap/unconstrained_set_of.hpp" synopsis]
+
+    namespace boost {
+    namespace bimaps {
+
+
+    template< class KeyType >
+    struct unconstrained_set_of;
+
+    struct unconstrained_set_of_relation;
+
+
+    } // namespace bimap
+    } // namespace boost
+
+[endsect]
+
+[section unconstrained_set_of Views]
+
+An unconstrained_set_of set view is a view with no constraints. The use
+of these kind of view boost the bimap performance but the view can not
+be accessed. An unconstrained view is an empty class.
+
+    namespace boost {
+    namespace bimaps {
+    namespace views {
+
+    template< ``['-implementation defined parameter list-]`` >
+    class ``['-implementation defined view name-]``
+    {
+        // Empty view
+    };
+
+    } // namespace views
+    } // namespace bimap
+    } // namespace boost
+
+
+
+In the case of a `bimap< unconstrained_set_of<Left>, ... >`
+
+In the set view:
+
+    typedef signature-compatible with relation< Left, ... > key_type;
+    typedef signature-compatible with relation< Left, ... > value_type;
+
+In the left map view:
+
+    typedef  Left  key_type;
+    typedef  ...   data_type;
+
+    typedef signature-compatible with std::pair< Left, ... > value_type;
+
+In the right map view:
+
+    typedef  ...  key_type;
+    typedef  Left data_type;
+
+    typedef signature-compatible with std::pair< ... , Left > value_type;
+
+
+
+[#unconstrained_set_of_complexity_signature]
+
+[section Complexity signature]
+
+We adopt the scheme outlined in the
+[link complexity_signature_explanation complexity signature section].
+An unconstrained view can not be accessed by the user, but the
+formulas to find the order of an operation for a bimap hold with
+the following definitions.
+The complexity signature of a `unconstrained_set_of` view is:
+
+* copying: `c(n) = 0`
+* insertion: `i(n) = 0`
+* hinted insertion: `h(n) = 0`
+* deletion: `d(n) = 0`
+* replacement: `r(n) = 0`
+* modifying: `m(n) = 0`
+
+[endsect]
+
+[section Serialization]
+
+Views cannot be serialized on their own, but only as part of the
+`bimap` into which they are embedded. In describing the additional
+preconditions and guarantees associated to `list_of` views with respect to
+serialization of their embedding containers, we use the concepts defined in the
+`bimap` serialization section.
+
+[blurb [*Operation:] saving of a `bimap` b to an output archive
+(XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container.
+
+[blurb [*Operation:] loading of a `bimap` b' from an input archive
+(XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container.
+
+
+[endsect]
+[endsect]
+
+[endsect]
+
+
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/reference/unordered_set_of.qbk Sun Feb 7 21:50:27 2010
@@ -0,0 +1,853 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section unordered_set_of Reference]
+
+[section Header "boost/bimap/unordered_set_of.hpp" synopsis]
+
+    namespace boost {
+    namespace bimaps {
+
+
+    template
+    <
+        class KeyType,
+        class HashFunctor   = hash< KeyType >,
+        class EqualKey      = std::equal_to< KeyType >
+    >
+    struct unordered_set_of;
+
+
+    template
+    <
+        class HashFunctor   = hash< _relation >,
+        class EqualKey      = std::equal_to< _relation >
+    >
+    struct unordered_set_of_relation;
+
+
+    } // namespace bimap
+    } // namespace boost
+
+
+[endsect]
+
+[section Header "boost/bimap/unordered_multiset_of.hpp" synopsis]
+
+    namespace boost {
+    namespace bimaps {
+
+
+    template
+    <
+        class KeyType,
+        class HashFunctor   = hash< KeyType >,
+        class EqualKey      = std::equal_to< KeyType >
+    >
+    struct unordered_multiset_of;
+
+
+    template
+    <
+        class HashFunctor   = hash< _relation >,
+        class EqualKey      = std::equal_to< _relation >
+    >
+    struct unordered_multiset_of_relation;
+
+
+    } // namespace bimap
+    } // namespace boost
+
+
+[endsect]
+
+[section Collection type specifiers unordered_set_of and unordered_multiset_of]
+
+These collection types specifiers allow for set views without and
+with allowance of duplicate elements, respectively. The syntax of
+`set_of` and `multiset_of` coincide, thus we describe them
+in a grouped manner.
+
+[endsect]
+
+[section unordered_\[multi\]set_of Views]
+
+An unordered_\[multi\]set_of set view is a tr1::unordered\[multi\]set signature compatible
+interface to the underlying heap of elements contained in a `bimap`.
+
+The interface and semantics of `unordered_[multi]set_of` views are
+modeled according to the proposal for unordered associative containers given
+in the __CPP_STANDARD_LIBRARY_TECHNICAL_REPORT__, also known as TR1.
+An `unordered_[multi]set_of` view is particularized according to a given
+`Hash` function object which returns hash values for the keys and a
+binary predicate `Pred` acting as an equivalence relation on values of Key.
+
+There are two variants: unordered_set_of, which do not allow duplicate elements +(with respect to its associated comparison predicate) and unordered_multiset_of, +which accept those duplicates. The interface of these two variants is the same
+to a great extent, so they are documented together with their differences
+explicitly noted when they exist.
+
+If you look the bimap by a side, you will use a map view and if you looked
+it as a whole you will be using a set view.
+
+Except where noted, `unordered_[multi]set_of` views (both unique and non-unique) are models
+of [^Unordered Associative Container].
+Validity of iterators and references to elements is preserved in all cases.
+Occasionally, the exception safety guarantees provided are actually stronger
+than required by the extension draft. We only provide descriptions of those
+types and operations that are either not present in the concepts modeled or
+do not exactly conform to the requirements for unordered associative containers.
+
+
+    namespace boost {
+    namespace bimap {
+    namespace views {
+
+    template< ``['-implementation defined parameter list-]`` >
+    class ``['-implementation defined view name-]``
+    {
+        public:
+
+        // types
+
+        typedef ``['-unspecified-]`` key_type;
+        typedef ``['-unspecified-]`` value_type;
+        typedef ``['-unspecified-]`` key_compare;
+        typedef ``['-unspecified-]`` value_compare;
+        typedef ``['-unspecified-]`` hasher;
+        typedef ``['-unspecified-]`` key_equal;
+        typedef ``['-unspecified-]`` allocator_type;
+        typedef ``['-unspecified-]`` reference;
+        typedef ``['-unspecified-]`` const_reference;
+        typedef ``['-unspecified-]`` iterator;
+        typedef ``['-unspecified-]`` const_iterator;
+        typedef ``['-unspecified-]`` size_type;
+        typedef ``['-unspecified-]`` difference_type;
+        typedef ``['-unspecified-]`` pointer;
+        typedef ``['-unspecified-]`` const_pointer;
+        typedef ``['-unspecified-]`` local_iterator;
+        typedef ``['-unspecified-]`` const_local_iterator;
+
+        typedef ``['-unspecified-]`` info_type;
+
+        // construct/destroy/copy:
+
+        this_type & operator=(const this_type & x);
+
+        allocator_type get_allocator() const;
+
+        // size and capacity
+
+        bool      empty() const;
+        size_type size() const;
+        size_type max_size() const;
+
+        // iterators
+
+        iterator       begin();
+        const_iterator begin() const;
+        iterator       end();
+        const_iterator end() const;
+
+        // modifiers
+
+ std::pair< iterator, bool > ``[link reference_unordered_set_of_insert_value insert]``(const value_type & x);
+
+ iterator ``[link reference_unordered_set_of_insert_iterator_value insert]``(iterator position, const value_type & x);
+
+        template< class InputIterator >
+ void ``[link reference_unordered_set_of_insert_iterator_iterator insert]``(InputIterator first, InputIterator last);
+
+ iterator ``[link reference_unordered_set_of_erase_iterator erase]``(iterator position);
+
+        template< class CompatibleKey >
+ size_type ``[link reference_unordered_set_of_erase_key erase]``(const CompatibleKey & x);
+
+ iterator ``[link reference_unordered_set_of_erase_iterator_iterator erase]``(iterator first, iterator last);
+
+ bool ``[link reference_unordered_set_of_replace_iterator_value replace]``(iterator position, const value_type & x);
+
+        // Only in map views
+        // {
+
+          template< class CompatibleKey >
+ bool ``[link reference_unordered_set_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
+
+          template< class CompatibleData >
+ bool ``[link reference_unordered_set_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
+
+          template< class KeyModifier >
+ bool ``[link reference_unordered_set_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
+
+          template< class DataModifier >
+ bool ``[link reference_unordered_set_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
+
+        // }
+
+
+        void clear();
+
+        // observers
+
+        key_from_value key_extractor() const;
+        hasher         hash_function() const;
+        key_equal      key_eq() const;
+
+        // lookup
+
+        template< class CompatibleKey >
+ iterator ``[link reference_unordered_set_of_find_key find]``(const CompatibleKey & x);
+
+        template< class CompatibleKey >
+ const_iterator ``[link reference_unordered_set_of_find_key find]``(const CompatibleKey & x) const;
+
+        template< class CompatibleKey >
+ size_type ``[link reference_unordered_set_of_count_key count]``(const CompatibleKey & x) const;
+
+        template< class CompatibleKey >
+        std::pair<iterator,iterator>
+ ``[link reference_unordered_set_of_equal_range_key equal_range]``(const CompatibleKey & x);
+
+        template< class CompatibleKey >
+        std::pair<const_iterator,const_iterator>
+ ``[link reference_unordered_set_of_equal_range_key equal_range]``(const CompatibleKey & x) const;
+
+        // bucket interface
+
+        size_type bucket_count() const;
+        size_type max_bucket_count() const;
+        size_type bucket_size(size_type n) const;
+        size_type bucket(const key_type & k) const;
+
+        local_iterator       begin(size_type n);
+        const_local_iterator begin(size_type n) const;
+        local_iterator       end(size_type n);
+        const_local_iterator end(size_type n) const;
+
+        // hash policy
+
+        float load_factor() const;
+        float max_load_factor() const;
+        void  max_load_factor(float z);
+ void ``[link reference_unordered_set_of_rehash_size rehash]``(size_type n);
+
+        // Only in maps views
+        // {
+
+        typedef ``['-unspecified-]`` data_type;
+
+          // Only in for `unordered_set_of` collection type
+          // {
+
+          template<class CompatibleKey>
+ const data_type & ``[link reference_unordered_set_of_at_key_const at]``(const CompatibleKey & k) const;
+
+            // Only if the other collection type is mutable
+            // {
+
+            template<class CompatibleKey>
+ data_type & ``[link reference_unordered_set_of_operator_bracket_key operator\[\]]``(const CompatibleKey & k);
+
+            template<class CompatibleKey>
+ data_type & ``[link reference_unordered_set_of_at_key at]``(const CompatibleKey & k);
+
+            // }
+
+            // Only if info_hook is used
+            // {
+
+            template< class CompatibleKey >
+ info_type & ``[link reference_unordered_set_of_info_at_key info_at]``(const CompatibleKey & k);
+
+            template< class CompatibleKey >
+ const info_type & ``[link reference_unordered_set_of_info_at_key info_at]``(const CompatibleKey & k) const;
+
+          // }
+
+        // }
+
+    };
+
+    } // namespace views
+    } // namespace bimap
+    } // namespace boost
+
+
+
+In the case of a `bimap< unordered_{multi}set_of<Left>, ... >`
+
+In the set view:
+
+    typedef signature-compatible with relation<       Left, ... > key_type;
+ typedef signature-compatible with relation< const Left, ... > value_type;
+
+In the left map view:
+
+    typedef  Left  key_type;
+    typedef  ...   data_type;
+
+ typedef signature-compatible with std::pair< const Left, ... > value_type;
+
+In the right map view:
+
+    typedef  ...  key_type;
+    typedef  Left data_type;
+
+ typedef signature-compatible with std::pair< ... ,const Left > value_type;
+
+
+
+[#unordered_set_of_complexity_signature]
+
+[section Complexity signature]
+
+Here and in the descriptions of operations of `unordered_[multi]set_of` views,
+we adopt the scheme outlined in the
+[link complexity_signature_explanation complexity signature section].
+The complexity signature of `unordered_[multi]set_of` view is:
+
+* copying: `c(n) = n * log(n)`,
+* insertion: average case `i(n) = 1` (constant), worst case `i(n) = n`,
+* hinted insertion: average case `h(n) = 1` (constant), worst case `h(n) = n`,
+* deletion: average case `d(n) = 1` (constant), worst case `d(n) = n`,
+* replacement:
+ * if the new element key is equivalent to the original, `r(n) = 1` (constant),
+    * otherwise, average case `r(n) = 1` (constant), worst case `r(n) = n`,
+* modifying: average case `m(n) = 1` (constant), worst case `m(n) = n`.
+
+[endsect]
+
+
+[section Instantiation types]
+
+`unordered_[multi]set_of` views are instantiated internally to `bimap`
+specified by means of the collection type specifiers and the `bimap` itself.
+Instantiations are dependent on the following types:
+
+* `Value` from `bimap`,
+* `Allocator` from `bimap`,
+* `Hash` from the collection type specifier,
+* `Pred` from the collection type specifier.
+
+`Hash` is a __SGI_UNARY_FUNCTION__ taking a single argument of type
+`key_type` and returning a value of type `std::size_t` in the range
+`[0, std::numeric_limits<std::size_t>::max())`.
+Pred is a __SGI_BINARY_PREDICATE__ inducing an equivalence relation on elements of
+`key_type`. It is required that the `Hash` object return the same value for
+keys equivalent under `Pred`.
+
+[endsect]
+
+[section Nested types]
+
+    iterator
+    const_iterator
+    local_iterator
+    const_local_iterator
+
+[:  These types are models of __SGI_FORWARD_ITERATOR__.
+]
+
+
+[endsect]
+
+[section Constructors, copy and assignment]
+
+As explained in the concepts section,
+views do not have public constructors or destructors. Assignment, on the other
+hand, is provided.
+Upon construction, `max_load_factor()` is 1.0.
+
+    this_type & operator=(const this_type & x);
+
+* [*Effects: ] `a = b`;
+where a and b are the `bimap` objects to which `*this`
+and x belong, respectively.
+* [*Returns: ] `*this.`
+
+
+
+[endsect]
+
+[section Modifiers]
+
+[#reference_unordered_set_of_insert_value]
+
+    std::pair<iterator,bool> insert(const value_type & x);
+
+* [*Effects:] Inserts `x` into the `bimap` to which the view belongs if
+ * the view is non-unique OR no other element with equivalent key exists,
+    * AND insertion is allowed by all other views of the `bimap`.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if +insertion took place. On successful insertion, `p.first` points to the element +inserted; otherwise, `p.first` points to an element that caused the insertion to +be banned. Note that more than one element can be causing insertion not to be
+allowed.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(I(n)).
+* [*Exception safety:] Strong.
+
+[#reference_unordered_set_of_insert_iterator_value]
+
+    iterator insert(iterator position, const value_type & x);
+
+* [*Requires: ] `position` is a valid iterator of the view.
+* [*Effects: ] `position` is used as a hint to improve the efficiency of the operation.
+Inserts `x` into the `bimap` to which the view belongs if
+ * the view is non-unique OR no other element with equivalent key exists,
+    * AND insertion is allowed by all other views of the `bimap`.
+* [*Returns:] On successful insertion, an iterator to the newly inserted element. +Otherwise, an iterator to an element that caused the insertion to be banned.
+Note that more than one element can be causing insertion not to be allowed.
+* [link unordered_set_of_complexity_signature [*Complexity:]] O(H(n)).
+* [*Exception safety:] Strong.
+
+[#reference_unordered_set_of_insert_iterator_iterator]
+
+    template< class InputIterator>
+    void insert(InputIterator first, InputIterator last);
+
+* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements of type
+`value_type`. `first` and `last` are not iterators into any views of the
+`bimap` to which this view belongs. `last` is reachable from first.
+* [*Effects: ]
+`iterator hint = end();`
+`while(first != last) hint = insert(hint, *first++);`
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(m*H(n+m)), where m is the number of elements in `[first, last)`.
+* [*Exception safety:] Basic.
+
+[#reference_unordered_set_of_erase_iterator]
+
+    iterator erase(iterator position);
+
+* [*Requires: ] `position` is a valid dereferenceable `iterator` of the view.
+* [*Effects:] Deletes the element pointed to by `position`.
+* [*Returns:] An `iterator` pointing to the element immediately following the one
+that was deleted, or `end()` if no such element exists.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(D(n)).
+* [*Exception safety:] nothrow.
+
+
+[#reference_unordered_set_of_erase_key]
+
+    template< class CompatibleKey >
+    size_type erase(const CompatibleKey & x);
+
+* [*Effects:] Deletes the elements with key equivalent to `x`.
+* [*Returns:] Number of elements deleted.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] Average case, O(1 + m*D(n)), worst case O(n + m*D(n)),
+where m is the number of elements deleted.
+* [*Exception safety:] Basic.
+
+
+[#reference_unordered_set_of_erase_iterator_iterator]
+
+    iterator erase(iterator first, iterator last);
+
+* [*Requires: ] `[first,last)` is a valid range of the view.
+* [*Effects:] Deletes the elements in `[first,last)`.
+* [*Returns: ] `last`.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(m*D(n)), where m is the number of elements in `[first,last)`.
+* [*Exception safety:] nothrow.
+
+
+[#reference_unordered_set_of_replace_iterator_value]
+
+    bool replace(iterator position, const value_type & x);
+
+* [*Requires: ] `position` is a valid dereferenceable `iterator` of the view. +* [*Effects:] Assigns the value `x` to the element pointed to by `position` into
+the `bimap` to which the view belongs if, for the value `x`
+    * the view is non-unique OR no other element with equivalent key exists
+(except possibly `*position`),
+    * AND replacing is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided +operation the `bimap` to which the view belongs remains in its original state.
+
+
+[#reference_unordered_set_of_replace_key_iterator_key]
+
+    template< class CompatibleKey >
+    bool replace_key(iterator position, const CompatibleKey & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `key_type`.
+* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed
+to by `position` into the `bimap` to which the set view belongs if,
+ * the map view is non-unique OR no other element with equivalent key exists
+(except possibly `*position`),
+    * AND replacing is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_unordered_set_of_replace_data_iterator_data]
+
+    template< class CompatibleData >
+    bool replace_data(iterator position, const CompatibleData & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `data_type`.
+* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed
+to by `position` into the `bimap` to which the set view belongs if,
+ * the map view is non-unique OR no other element with equivalent key exists
+(except possibly `*position`),
+    * AND replacing is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_unordered_set_of_modify_key_iterator_modifier]
+
+    template< class KeyModifier >
+    bool modify_key(iterator position, KeyModifier mod);
+
+* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `key_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+Rearrangement is successful if
+ * the map view is non-unique OR no other element with equivalent key exists,
+    * AND rearrangement is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+
+[#reference_unordered_set_of_modify_data_iterator_modifier]
+
+    template< class DataModifier >
+    bool modify_data(iterator position, DataModifier mod);
+
+* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `data_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+Rearrangement is successful if
+ * the oppositte map view is non-unique OR no other element with equivalent key in that
+view exists,
+    * AND rearrangement is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+[/
+[#reference_unordered_set_of_modify_iterator_modifier]
+
+    template< class Modifier>
+    bool modify(iterator position, Modifier mod);
+
+* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of +type: `first_type&` and `second_type&` for ['Map View] or `left_type&` and `right_type&` +for ['Set View]; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View:] or calls `mod(e.left,e.right)`
+for ['Set View] where `e` is the element pointed to by `position` and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+Rearrangement is successful if
+ * the view is non-unique OR no other element with equivalent key exists,
+    * AND rearrangement is allowed by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly `mod`), then the element pointed to by `position` is erased.
+/]
+
+[endsect]
+
+[section Lookup]
+
+`unordered_[multi]set_of` views provide the full lookup functionality required by unordered +associative containers, namely `find`, `count`, and `equal_range`. Additionally,
+these member functions are templatized to allow for non-standard arguments,
+so extending the types of search operations allowed. The kind of arguments
+permissible when invoking the lookup member functions is defined by the
+following concept.
+
+[/
+Consider a pair `(Hash, Pred)` where `Hash` is a hash functor over values of type +`Key` and `Pred` is a __SGI_BINARY_PREDICATE__ inducing an equivalence relation on `Key`, +with the additional constraint that equivalent keys have the same hash value. +A triplet of types `(CompatibleKey, CompatibleHash, CompatiblePred)` is said to
+be a ['compatible extension] of `(Hash, Pred)` if
+
+* `CompatibleHash` is a hash functor on values of type `CompatibleKey`,
+* `CompatiblePred` is a __SGI_BINARY_PREDICATE__ over `(Key, CompatibleKey)`, +* `CompatiblePred` is a __SGI_BINARY_PREDICATE__ over `(CompatibleKey, Key)`,
+* if `c_eq(ck,k1)` then `c_eq(k1,ck)`,
+* if `c_eq(ck,k1)` and `eq(k1,k2)` then `c_eq(ck,k2)`,
+* if `c_eq(ck,k1)` and `c_eq(ck,k2)` then `eq(k1,k2)`,
+* if `c_eq(ck,k1)` then `c_hash(ck)==hash(k1)`,
+
+for every `c_hash` of type `CompatibleHash`, `c_eq` of type `CompatiblePred`, hash of +type `Hash`, `eq` of type `Pred`, `ck` of type `CompatibleKey` and `k1`, `k2` of type `Key`.
+]
+
+A type `CompatibleKey` is said to be a ['compatible key] of `(Hash, Pred)`
+if `(CompatibleKey, Hash, Pred)` is a compatible extension of `(Hash, Pred)`. This +implies that `Hash` and `Pred` accept arguments of type `CompatibleKey`, which usually +means they have several overloads of their corresponding `operator()` member
+functions.
+
+[/
+In the context of a compatible extension or a compatible key, the expression
+"equivalent key" takes on its obvious interpretation.
+]
+
+[#reference_unordered_set_of_find_key]
+
+    template< class CompatibleKey >
+    iterator find(const CompatibleKey & x);
+
+    template< class CompatibleKey >
+    const_iterator find(const CompatibleKey & x) const;
+
+* [*Effects:] Returns a pointer to an element whose key is equivalent to `x`,
+or `end()` if such an element does not exist.
+* [*Complexity:] Average case O(1) (constant), worst case O(n).
+
+
+[#reference_unordered_set_of_count_key]
+
+    template< class CompatibleKey >
+    size_type count(const CompatibleKey & x) const;
+
+* [*Effects:] Returns the number of elements with key equivalent to `x`.
+* [*Complexity:] Average case O(count(x)), worst case O(n).
+
+
+[#reference_unordered_set_of_equal_range_key]
+
+    template< class CompatibleKey >
+    std::pair<iterator,iterator>
+        equal_range(const CompatibleKey & x);
+
+    template< class CompatibleKey >
+    std::pair<const_iterator,const_iterator>
+        equal_range(const CompatibleKey & x) const;
+
+* [*Effects:] Returns a range containing all elements with keys equivalent
+to `x` (and only those).
+* [*Complexity:] Average case O(count(x)), worst case O(n).
+
+
+
+[endsect]
+
+[section at(), info_at() and operator\[\] - set_of only]
+
+
+[#reference_unordered_set_of_at_key_const]
+
+    template< class CompatibleKey >
+    const data_type & at(const CompatibleKey & k) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns the `data_type` reference that is associated with `k`, or
+throws `std::out_of_range` if such key does not exist.
+* [*Complexity:] Average case O(1) (constant), worst case O(n).
+* [*Note:] Only provided when `unordered_set_of` is used.
+
+The symmetry of bimap imposes some constraints on `operator[]` and the
+non constant version of at() that are not found in `std::maps`.
+Tey are only provided if the other collection type is mutable
+(`list_of`, `vector_of` and `unconstrained_set_of`).
+
+
+[#reference_unordered_set_of_operator_bracket_key]
+
+    template< class CompatibleKey >
+    data_type & operator[](const CompatibleKey & k);
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects: ] `return insert(value_type(k,data_type()))->second;`
+* [*Complexity:] If the insertion is performed O(I(n)), else: Average case
+O(1) (constant), worst case O(n).
+* [*Note:] Only provided when `unordered_set_of` is used and the other collection
+type is mutable.
+
+
+[#reference_unordered_set_of_at_key]
+
+    template< class CompatibleKey >
+    data_type & at(const CompatibleKey & k);
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects: ] Returns the `data_type` reference that is associated with `k`, or
+throws `std::out_of_range` if such key does not exist.
+* [*Complexity:] Average case O(1) (constant), worst case O(n).
+* [*Note:] Only provided when `unordered_set_of` is used and the other collection
+type is mutable.
+
+[/
+
+The symmetry of bimap imposes some constraints to the `operator[]` that are not
+found in `std::maps`.
+If other views are unique, `bimap::duplicate_value` is thrown whenever an assignment is
+attempted to a value that is already a key in this views.
+As for bimap::value_not_found, this exception is thrown while trying to access +a non-existent key: this behavior differs from that of std::map, which automatically
+assigns a default value to non-existent keys referred to by `operator[]`.
+
+    const data_type & operator[](const typename key_type & k) const;
+
+* [*Effects:] Returns the `data_type` reference that is associated with `k`, or
+throws `bimap::value_not_found` if such an element does not exist.
+* [*Complexity:] O(log(n)).
+
+
+ ``['-unspecified data_type proxy-]`` operator[](const typename key_type & k);
+
+* [*Effects:] Returns a proxy to a `data_type` associated with `k` and the
+bimap. The proxy behaves as a reference to the `data_type` object. If this
+proxy is read and `k` was not in the bimap, the bimap::value_not_found is
+thrown. If it is written then `bimap::duplicate_value` is thrown if the
+assignment is not allowed by one of the other views of the `bimap`.
+* [link unordered_set_of_complexity_signature
+[*Complexity:]] If the assignment operator of the proxy is not used, then
+the order is O(log(n)). If it is used, the order is O(I(n)) if `k` was not
+in the bimap and O(R(n)) if it existed in the bimap.
+
+]
+
+[#reference_unordered_set_of_info_at_key]
+
+    template< class CompatibleKey >
+    info_type & info_at(const CompatibleKey & k);
+
+    template< class CompatibleKey >
+    const info_type & info_at(const CompatibleKey & k) const;
+
+* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
+* [*Effects:] Returns the `info_type` reference that is associated with `k`, or
+throws `std::out_of_range` if such key does not exist.
+* [*Complexity:] Average case O(1) (constant), worst case O(n).
+* [*Note:] Only provided when `unordered_set_of` and `info_hook` are used
+
+
+[endsect]
+
+[section Hash policy]
+
+
+[#reference_unordered_set_of_rehash_size]
+
+    void rehash(size_type n);
+
+* [*Effects:] Increases if necessary the number of internal buckets so that
+`size()/bucket_count()` does not exceed the maximum load factor, and
+`bucket_count()>=n`.
+* [*Postconditions:] Validity of iterators and references to the elements
+contained is preserved.
+* [*Complexity:] Average case O(size()), worst case O(size(n)2).
+* [*Exception safety:] Strong.
+
+
+[endsect]
+
+[section Serialization]
+
+Views cannot be serialized on their own, but only as part of the
+`bimap` into which they are embedded. In describing the
+additional preconditions and guarantees associated to `unordered_[multi]set_of` views
+with respect to serialization of their embedding containers, we use
+the concepts defined in the `bimap` serialization section.
+
+[blurb [*Operation:] saving of a `bimap` b to an output archive
+(XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container.
+
+
+[blurb [*Operation:] loading of a `bimap` b' from an input
+archive (XML archive) ar.]
+
+* [*Requires:] Additionally to the general requirements, `key_eq()` must
+be serialization-compatible with `m.get<i>().key_eq()`, where i is the
+position of the `unordered_[multi]set_of` view in the container.
+* [*Postconditions:] On successful loading, the range `[begin(), end())`
+contains restored copies of every element in
+`[m.get<i>().begin(), m.get<i>().end())`, though not necessarily in
+the same order.
+
+
+[blurb [*Operation:] saving of an `iterator` or `const_iterator` `it` to an output
+archive (XML archive) ar.]
+
+* [*Requires: ] `it` is a valid `iterator` of the view. The associated
+`bimap` has been previously saved.
+
+
+[blurb [*Operation:] loading of an iterator or `const_iterator it`' from an
+input archive (XML archive) ar.]
+
+* [*Postconditions:] On successful loading, if `it` was dereferenceable then
+`*it`' is the restored copy of `*it`, otherwise `it`'` == end()`.
+* [*Note:] It is allowed that `it` be a `const_iterator` and the restored
+`it`' an `iterator`, or viceversa.
+
+
+[blurb [*Operation:] saving of a local_iterator or const_local_iterator it
+to an output archive (XML archive) ar.]
+
+* [*Requires: ] `it` is a valid local iterator of the view. The associated
+`bimap` has been previously saved.
+
+
+[blurb [*Operation:] loading of a `local_iterator` or `const_local_iterator`
+`it`' from an input archive (XML archive) ar.]
+
+* [*Postconditions:] On successful loading, if `it` was dereferenceable then +`*it`' is the restored copy of `*it`; if `it` was `m.get<i>().end(n)` for some n,
+then `it`'` == m`'`.get<i>().end(n)` (where `b` is the original `bimap`,
+`b`' its restored copy and `i` is the ordinal of the index.)
+* [*Note:] It is allowed that `it` be a `const_local_iterator` and the restored
+`it`' a `local_iterator`, or viceversa.
+
+
+[endsect]
+[endsect]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/reference/vector_of.qbk       Sun Feb  7 21:50:27 2010
@@ -0,0 +1,843 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section vector_of Reference]
+
+[section Header "boost/bimap/vector_of.hpp" synopsis]
+
+    namespace boost {
+    namespace bimaps {
+
+
+    template< class KeyType >
+    struct vector_of;
+
+    struct vector_of_relation;
+
+
+    } // namespace bimap
+    } // namespace boost
+
+
+[endsect]
+
+[section vector_of views]
+
+vector_of views are free-order sequences with constant time positional
+access and random access iterators. Elements in a vector_of view are by
+default sorted according to their order of insertion: this means that new elements
+inserted through a different view of the `bimap` are appended to
+the end of the vector_of view; additionally, facilities are provided for
+further rearrangement of the elements. The public interface of vector_of views
+includes that of list_of views, with differences in the complexity
+of the operations, plus extra operations for positional access
+(`operator[]` and `at()`) and for capacity handling. Validity of iterators and
+references to elements is preserved in all operations, regardless of the
+capacity status.
+
+As is the case with list_of views, vector_of views have the following
+limitations with respect to STL sequence containers:
+
+* vector_of views
+are not __SGI_ASSIGNABLE__ (like any other view.)
+* Insertions into a vector_of view may fail due to clashings with other views. +This alters the semantics of the operations provided with respect to their analogues
+in STL sequence containers.
+* Elements in a vector_of view are not mutable, and can only be changed by
+means of replace and modify member functions.
+
+Having these restrictions into account, vector of views are models of
+__SGI_RANDOM_ACCESS_CONTAINER__ and __SGI_BACK_INSERTION_SEQUENCE__. Although these views +do not model __SGI_FRONT_INSERTION_SEQUENCE__, because front insertion and deletion +take linear time, front operations are nonetheless provided to match the interface +of list_of views. We only describe those types and operations that are either +not present in the concepts modeled or do not exactly conform to the requirements
+for these types of containers.
+
+
+    namespace boost {
+    namespace bimaps {
+    namespace views {
+
+    template< ``['-implementation defined parameter list-]`` >
+    class ``['-implementation defined view name-]``
+    {
+        public:
+
+        // types
+
+        typedef ``['-unspecified-]`` value_type;
+        typedef ``['-unspecified-]`` allocator_type;
+        typedef ``['-unspecified-]`` reference;
+        typedef ``['-unspecified-]`` const_reference;
+        typedef ``['-unspecified-]`` iterator;
+        typedef ``['-unspecified-]`` const_iterator;
+        typedef ``['-unspecified-]`` size_type;
+        typedef ``['-unspecified-]`` difference_type;
+        typedef ``['-unspecified-]`` pointer;
+        typedef ``['-unspecified-]`` const_pointer;
+        typedef ``['-unspecified-]`` reverse_iterator;
+        typedef ``['-unspecified-]`` const_reverse_iterator;
+
+        typedef ``['-unspecified-]`` info_type;
+
+        // construct / copy / destroy
+
+        this_type & operator=(this_type & x);
+
+        template< class InputIterator >
+ void ``[link reference_vector_of_assign_iterator_iterator assign]``(InputIterator first, InputIterator last);
+
+ void ``[link reference_vector_of_assign_size_value assign]``(size_type n, const value_type & value);
+
+        allocator_type get_allocator() const;
+
+        // iterators
+
+        iterator               begin();
+        const_iterator         begin() const;
+
+        iterator               end();
+        const_iterator         end() const;
+
+        reverse_iterator       rbegin();
+        const_reverse_iterator rbegin() const;
+
+        reverse_iterator       rend();
+        const_reverse_iterator rend() const;
+
+        // capacity
+
+        bool      empty() const;
+
+        size_type size() const;
+
+        size_type max_size() const;
+
+        size_type ``[link reference_vector_of_capacity capacity]``() const;
+
+ void ``[link reference_vector_of_reserve_size reserve]``(size_type m);
+
+ void ``[link reference_vector_of_resize_size_value resize]``(size_type n, const value_type & x = value_type());
+
+        // access
+
+        const_reference operator[](size_type n) const;
+
+        const_reference at(size_type n) const;
+
+        const_reference front() const;
+
+        const_reference back() const;
+
+        // modifiers
+
+ std::pair<iterator,bool> ``[link reference_vector_of_push_front_value push_front]``(const value_type & x);
+        void                     pop_front();
+
+ std::pair<iterator,bool> ``[link reference_vector_of_push_back_value push_back]``(const value_type & x);
+        void                     pop_back();
+
+ std::pair<iterator,bool> ``[link reference_vector_of_insert_iterator_value insert]``(iterator position, const value_type & x);
+
+ void ``[link reference_vector_of_insert_iterator_size_value insert]``(iterator position, size_type m, const value_type & x);
+
+        template< class InputIterator>
+ void ``[link reference_vector_of_insert_iterator_iterator_iterator insert]``(iterator position, InputIterator first, InputIterator last);
+
+ iterator ``[link reference_vector_of_erase_iterator erase]``(iterator position); + iterator ``[link reference_vector_of_erase_iterator_iterator erase]``(iterator first, iterator last);
+
+ bool ``[link reference_vector_of_replace_iterator_value replace]``(iterator position, const value_type & x);
+
+        // Only in map views
+        // {
+
+          template< class CompatibleKey >
+ bool ``[link reference_vector_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
+
+          template< class CompatibleData >
+ bool ``[link reference_vector_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
+
+          template< class KeyModifier >
+ bool ``[link reference_vector_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
+
+          template< class DataModifier >
+ bool ``[link reference_vector_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
+
+        // }
+
+
+        void clear();
+
+        // list operations
+
+ void ``[link reference_vector_of_splice_iterator_this splice]``(iterator position, this_type & x); + void ``[link reference_vector_of_splice_iterator_this_iterator splice]``(iterator position, this_type & x, iterator i); + void ``[link reference_vector_of_splice_iterator_this_iterator_iterator splice]``( + iterator position, this_type & x, iterator first, iterator last);
+
+ void ``[link reference_vector_of_remove_value remove]``(const value_type & value);
+
+        template< class Predicate >
+ void ``[link reference_vector_of_remove_if_predicate remove_if]``(Predicate pred);
+
+        void ``[link reference_vector_of_unique unique]``();
+
+        template< class BinaryPredicate >
+ void ``[link reference_vector_of_unique_predicate unique]``(BinaryPredicate binary_pred);
+
+ void ``[link reference_vector_of_merge_this merge]``(this_type & x);
+
+        template< typename Compare >
+ void ``[link reference_vector_of_merge_this_compare merge]``(this_type & x, Compare comp);
+
+        void ``[link reference_vector_of_sort sort]``();
+
+        template< typename Compare >
+ void ``[link reference_vector_of_sort_compare sort]``(Compare comp);
+
+        void ``[link reference_vector_of_reverse reverse]``();
+
+        // rearrange operations
+
+ void ``[link reference_vector_of_relocate_iterator_iterator relocate]``(iterator position, iterator i); + void ``[link reference_vector_of_relocate_iterator_iterator_iterator relocate]``(iterator position, iterator first, iterator last);
+    };
+
+    // view comparison
+
+    bool operator==(const this_type & v1, const this_type & v2 );
+    bool operator< (const this_type & v1, const this_type & v2 );
+    bool operator!=(const this_type & v1, const this_type & v2 );
+    bool operator> (const this_type & v1, const this_type & v2 );
+    bool operator>=(const this_type & v1, const this_type & v2 );
+    bool operator<=(const this_type & v1, const this_type & v2 );
+
+    } // namespace views
+    } // namespace bimap
+    } // namespace boost
+
+
+
+In the case of a `bimap< vector_of<Left>, ... >`
+
+In the set view:
+
+    typedef signature-compatible with relation< Left, ... > key_type;
+    typedef signature-compatible with relation< Left, ... > value_type;
+
+In the left map view:
+
+    typedef  Left  key_type;
+    typedef  ...   data_type;
+
+    typedef signature-compatible with std::pair< Left, ... > value_type;
+
+In the right map view:
+
+    typedef  ...  key_type;
+    typedef  Left data_type;
+
+    typedef signature-compatible with std::pair< ... , Left > value_type;
+
+
+[#vector_of_complexity_signature]
+
+[section Complexity signature]
+
+Here and in the descriptions of operations of `vector_of` views, we adopt
+the scheme outlined in the
+[link complexity_signature_explanation complexity signature section].
+The complexity signature of `vector_of` view is:
+
+* copying: `c(n) = n * log(n)`,
+* insertion: `i(n) = 1` (amortized constant),
+* hinted insertion: `h(n) = 1` (amortized constant),
+* deletion: `d(n) = m`, where m is the distance from the deleted element to the
+end of the sequence,
+* replacement: `r(n) = 1` (constant),
+* modifying: `m(n) = 1` (constant).
+
+The following expressions are also used as a convenience for writing down some
+of the complexity formulas:
+
+[blurb
+`shl(a,b) = a+b` if a is nonzero, 0 otherwise.
+`rel(a,b,c) =` if `a<b`, `c-a`, else `a-b`,
+]
+
+(`shl` and `rel` stand for ['shift left] and ['relocate], respectively.)
+
+[endsect]
+
+[section Instantiation types]
+
+`vector_of` views are instantiated internally to `bimap` and specified
+by means of the collection type specifiers and the bimap itself.
+Instantiations are dependent on the following types:
+
+* `Value` from `vector_of`,
+* `Allocator` from `bimap`,
+
+[endsect]
+
+[section Constructors, copy and assignment]
+
+As explained in the views concepts section,
+views do not have public constructors or destructors.
+Assignment, on the other hand, is provided.
+
+    this_type & operator=(const this_type & x);
+
+* [*Effects: ] `a=b;`
+where a and b are the `bimap` objects to which `*this` and
+`x` belong, respectively.
+* [*Returns: ] `*this`.
+
+
+[#reference_vector_of_assign_iterator_iterator]
+
+    template< class InputIterator >
+    void assign(InputIterator first, InputIterator last);
+
+* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements +of type `value_type` or a type convertible to `value_type`. `first` and `last` are
+not iterators into any view of the `bimap` to which this
+view belongs. `last` is reachable from `first`.
+* [*Effects: ] `clear(); insert(end(),first,last);`
+
+
+[#reference_vector_of_assign_size_value]
+
+    void assign(size_type n, const value_type & value);
+
+* [*Effects: ] `clear(); for(size_type i = 0; i < n; ++n) push_back(v);`
+
+[endsect]
+
+[section Capacity operations]
+
+[#reference_vector_of_capacity]
+
+    size_type capacity() const;
+
+* [*Returns:] The total number of elements `c` such that, when `size() < c`,
+back insertions happen in constant time (the general case as described by
+i(n) is ['amortized] constant time.)
+* [*Note:] Validity of iterators and references to elements is preserved
+in all insertions, regardless of the capacity status.
+
+
+[#reference_vector_of_reserve_size]
+
+    void reserve(size_type m);
+
+* [*Effects:] If the previous value of `capacity()` was greater than or equal +to `m`, nothing is done; otherwise, the internal capacity is changed so that
+`capacity()>=m`.
+* [*Complexity:] If the capacity is not changed, constant; otherwise O(n).
+* [*Exception safety:] If the capacity is not changed, nothrow; otherwise, strong.
+
+
+[#reference_vector_of_resize_size_value]
+
+    void resize(size_type n, const value_type & x = value_type());
+
+* [*Effects: ] `if( n > size() ) insert(end(), n-size(), x);`
+`else if( n<size() ) erase(begin()+n,end());`
+* [*Note:] If an expansion is requested, the size of the view is not guaranteed
+to be n after this operation (other views may ban insertions.)
+
+
+[endsect]
+
+[section Modifiers]
+
+[#reference_vector_of_push_front_value]
+
+    std::pair<iterator,bool> push_front(const value_type & x);
+
+* [*Effects:] Inserts x at the beginning of the sequence if no other view
+of the `bimap` bans the insertion.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if +insertion took place. On successful insertion, `p.first` points to the element +inserted; otherwise, `p.first` points to an element that caused the insertion
+to be banned. Note that more than one element can be causing insertion not
+to be allowed.
+* [link vector_of_complexity_signature [*Complexity:]] O(n+I(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_vector_of_push_back_value]
+
+    std::pair<iterator,bool> push_back(const value_type & x);
+
+* [*Effects:] Inserts `x` at the end of the sequence if no other view of
+the `bimap` bans the insertion.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only
+if insertion took place. On successful insertion, `p.first` points to the
+element inserted; otherwise, `p.first` points to an element that caused
+the insertion to be banned. Note that more than one element can be
+causing insertion not to be allowed.
+* [link vector_of_complexity_signature [*Complexity:]] O(I(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_vector_of_insert_iterator_value]
+
+ std::pair<iterator,bool> insert(iterator position, const value_type & x);
+
+* [*Requires: ] `position` is a valid iterator of the view.
+* [*Effects:] Inserts `x` before position if insertion is allowed by all
+other views of the `bimap`.
+* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only
+if insertion took place. On successful insertion, `p.first` points to the
+element inserted; otherwise, `p.first` points to an element that caused the
+insertion to be banned. Note that more than one element can be causing
+insertion not to be allowed.
+* [link vector_of_complexity_signature [*Complexity:]] O(shl(end()-position,1) + I(n)).
+* [*Exception safety:] Strong.
+
+
+[#reference_vector_of_insert_iterator_size_value]
+
+    void insert(iterator position, size_type m, const value_type & x);
+
+* [*Requires: ] `position` is a valid iterator of the view.
+* [*Effects: ] `for(size_type i = 0; i < m; ++i) insert(position, x);`
+* [link vector_of_complexity_signature
+[*Complexity:]] O(shl(end()-position,m) + m*I(n+m)).
+
+
+[#reference_vector_of_insert_iterator_iterator_iterator]
+
+    template< class InputIterator >
+ void insert(iterator position, InputIterator first, InputIterator last);
+
+* [*Requires: ] `position` is a valid iterator of the view. `InputIterator`
+is a model of __SGI_INPUT_ITERATOR__ over elements of type `value_type` or a type +convertible to `value_type`. `first` and `last` are not iterators into any view
+of the `bimap` to which this view belongs. `last` is reachable
+from `first`.
+* [*Effects: ] `while(first!=last)insert(position,*first++);`
+* [link vector_of_complexity_signature
+[*Complexity:]] O(shl(end()-position,m) + m*I(n+m)), where m is the number
+of elements in `[first,last)`.
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_erase_iterator]
+
+    iterator erase(iterator position);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the view.
+* [*Effects:] Deletes the element pointed to by `position`.
+* [*Returns:] An iterator pointing to the element immediately following the
+one that was deleted, or `end()` if no such element exists.
+* [link vector_of_complexity_signature [*Complexity:]] O(D(n)).
+* [*Exception safety:] nothrow.
+
+
+[#reference_vector_of_erase_iterator_iterator]
+
+    iterator erase(iterator first, iterator last);
+
+* [*Requires: ] `[first,last)` is a valid range of the view.
+* [*Effects:] Deletes the elements in `[first,last)`.
+* [*Returns:] last.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(m*D(n)), where m is the number of elements in `[first,last)`.
+* [*Exception safety:] nothrow.
+
+
+[#reference_vector_of_replace_iterator_value]
+
+    bool replace(iterator position, const value_type & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the view.
+* [*Effects:] Assigns the value x to the element pointed to by position into
+the `bimap` to which the view belongs if replacing is allowed
+by all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation the `bimap` to which the view belongs remains in its
+original state.
+
+
+
+[#reference_vector_of_replace_key_iterator_key]
+
+    template< class CompatibleKey >
+    bool replace_key(iterator position, const CompatibleKey & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `key_type`.
+* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed +to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
+all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_vector_of_replace_data_iterator_data]
+
+    template< class CompatibleData >
+    bool replace_data(iterator position, const CompatibleData & x);
+
+* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
+`CompatibleKey` can be assigned to `data_type`.
+* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed +to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
+all other views of the `bimap`.
+* [*Postconditions:] Validity of position is preserved in all cases.
+* [*Returns: ] `true` if the replacement took place, `false` otherwise.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(R(n)).
+* [*Exception safety:] Strong. If an exception is thrown by some user-provided
+operation, the `bimap` to which the set view belongs remains in
+its original state.
+
+
+[#reference_vector_of_modify_key_iterator_modifier]
+
+    template< class KeyModifier >
+    bool modify_key(iterator position, KeyModifier mod);
+
+* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `key_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+It is successful if the rearrangement is allowed by all other views of the `bimap`. +* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+
+[#reference_vector_of_modify_data_iterator_modifier]
+
+    template< class DataModifier >
+    bool modify_data(iterator position, DataModifier mod);
+
+* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of +type: `data_type&`; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
+rearranges `*position` into all the views of the `bimap`.
+If the rearrangement fails, the element is erased.
+It is successful if the rearrangement is allowed by all other views of the `bimap`. +* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided +operation (except possibly mod), then the element pointed to by position is erased.
+* [*Note:] Only provided for map views.
+
+[/
+[#reference_vector_of_modify_iterator_modifier]
+
+    template< class Modifier >
+    bool modify(iterator position, Modifier mod);
+
+* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of +type: `first_type&` and `second_type&` for ['Map View] or `left_type&` and `right_type&` +for ['Set View]; `position` is a valid dereferenceable iterator of the view. +* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View:] or calls `mod(e.left,e.right)`
+for ['Set View] where e is the element pointed to by `position` and
+rearranges `*position` into all the views of the `bimap`.
+Rearrangement on `vector_of` views does not change the position of the
+element with respect to the view; rearrangement on other views may or
+might not suceed. If the rearrangement fails, the element is erased.
+* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
+* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
+* [link vector_of_complexity_signature [*Complexity:]] O(M(n)).
+* [*Exception safety:] Basic. If an exception is thrown by some user-provided
+operation (except possibly `mod`), then the element pointed to by position
+is erased.
+]
+
+
+[endsect]
+
+[section List operations]
+
+`vector_of` views replicate the interface of `list_of` views, which
+in turn includes the list operations provided by `std::list`. The syntax and
+behavior of these operations exactly matches those of `list_of` views, but
+the associated complexity bounds differ in general.
+
+
+[#reference_vector_of_splice_iterator_this]
+
+    void splice(iterator position, this_type & x);
+
+* [*Requires: ] `position` is a valid iterator of the view. `&x!=this`.
+* [*Effects:] Inserts the contents of `x` before position, in the same order +as they were in `x`. Those elements successfully inserted are erased from `x`.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(shl(end()-position,x.size()) + x.size()*I(n+x.size()) + x.size()*D(x.size())).
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_splice_iterator_this_iterator]
+
+    void splice(iterator position, this_type & x,iterator i);
+
+* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
+dereferenceable iterator `x`.
+* [*Effects:] Inserts the element pointed to by `i` before `position`: if
+insertion is successful, the element is erased from `x`. In the special
+case `&x==this`, no copy or deletion is performed, and the operation is
+always successful. If `position==i`, no operation is performed.
+* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
+* [link vector_of_complexity_signature
+[*Complexity:]] If `&x==this`, O(rel(position,i,i+1));
+otherwise O(shl(end()-position,1) + I(n) + D(n)).
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, strong.
+
+
+[#reference_vector_of_splice_iterator_this_iterator_iterator]
+
+ void splice(iterator position, this_type & x, iterator first, iterator last);
+
+* [*Requires: ] `position` is a valid iterator of the view. `first` and
+`last` are valid iterators of `x`. `last` is reachable from `first`. `position` is
+not in the range `[first,last)`.
+* [*Effects:] For each element in the range `[first,last)`, insertion is
+tried before `position`; if the operation is successful, the element is
+erased from `x`. In the special case `&x==this`, no copy or deletion is
+performed, and insertions are always successful.
+* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
+* [link vector_of_complexity_signature
+[*Complexity:]] If `&x==this`, O(rel(position,first,last));
+otherwise O(shl(end()-position,m) + m*I(n+m) + m*D(x.size()))
+where m is the number of elements in `[first,last)`.
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
+
+
+[#reference_vector_of_remove_value]
+
+    void remove(const value_type & value);
+
+* [*Effects:] Erases all elements of the view which compare equal to `value`.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_remove_if_predicate]
+
+    template< class Predicate >
+    void remove_if(Predicate pred);
+
+* [*Effects:] Erases all elements `x` of the view for which `pred(x)` holds.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_unique]
+
+    void unique();
+
+* [*Effects:] Eliminates all but the first element from every consecutive
+group of equal elements referred to by the iterator `i` in the range
+`[first+1,last)` for which `*i==*(i-1)`.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_unique_predicate]
+
+    template< class BinaryPredicate >
+    void unique(BinaryPredicate binary_pred);
+
+* [*Effects:] Eliminates all but the first element from every consecutive
+group of elements referred to by the iterator i in the range `[first+1,last)`
+for which `binary_pred(*i, *(i-1))` holds.
+* [link vector_of_complexity_signature
+[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_merge_this]
+
+    void merge(this_type & x);
+
+* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over +`value_type`. Both the view and `x` are sorted according to `std::less<value_type>`.
+* [*Effects:] Attempts to insert every element of x into the corresponding
+position of the view (according to the order). Elements successfully
+inserted are erased from `x`. The resulting sequence is stable, i.e. equivalent +elements of either container preserve their relative position. In the special
+case `&x==this`, no operation is performed.
+* [*Postconditions:] Elements in the view and remaining elements in `x` are
+sorted. Validity of iterators to the view and of non-erased elements of `x`
+references is preserved.
+* [link vector_of_complexity_signature
+[*Complexity:]] If `&x==this`, constant;
+otherwise O(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
+
+
+[#reference_vector_of_merge_this_compare]
+
+    template< class Compare >
+    void merge(this_type & x, Compare comp);
+
+* [*Requires: ] `Compare` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
+Both the view and `x` are sorted according to comp.
+* [*Effects:] Attempts to insert every element of `x` into the corresponding
+position of the view (according to `comp`). Elements successfully inserted
+are erased from `x`. The resulting sequence is stable, i.e. equivalent
+elements of either container preserve their relative position. In the
+special case `&x==this`, no operation is performed.
+* [*Postconditions:] Elements in the view and remaining elements in `x` are
+sorted according to `comp`. Validity of iterators to the view and of
+non-erased elements of `x` references is preserved.
+* [link vector_of_complexity_signature
+[*Complexity:]] If `&x==this`, constant;
+otherwise O(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
+* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
+
+
+[#reference_vector_of_sort]
+
+    void sort();
+
+* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
+* [*Effects:] Sorts the view according to `std::less<value_type>`.
+The sorting is stable, i.e. equivalent elements preserve their relative position.
+* [*Postconditions:] Validity of iterators and references is preserved.
+* [*Complexity:] O(n*log(n)).
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_sort_compare]
+
+    template< class Compare >
+    void sort(Compare comp);
+
+* [*Requires:] Compare is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
+* [*Effects:] Sorts the view according to `comp`. The sorting is stable, i.e.
+equivalent elements preserve their relative position.
+* [*Postconditions:] Validity of iterators and references is preserved.
+* [*Complexity:] O(n*log(n)).
+* [*Exception safety:] Basic.
+
+
+[#reference_vector_of_reverse]
+
+    void reverse();
+
+* [*Effects:] Reverses the order of the elements in the view.
+* [*Postconditions:] Validity of iterators and references is preserved.
+* [*Complexity:] O(n).
+* [*Exception safety:] nothrow.
+
+
+[endsect]
+
+[section Rearrange operations]
+
+These operations, without counterpart in `std::list` (although splice provides +partially overlapping functionality), perform individual and global repositioning
+of elements inside the index.
+
+
+[#reference_vector_of_relocate_iterator_iterator]
+
+    void relocate(iterator position, iterator i);
+
+* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
+dereferenceable iterator of the view.
+* [*Effects:] Inserts the element pointed to by `i` before `position`.
+If `position==i`, no operation is performed.
+* [*Postconditions:] No iterator or reference is invalidated.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+[#reference_vector_of_relocate_iterator_iterator_iterator]
+
+    void relocate(iterator position, iterator first, iterator last);
+
+* [*Requires: ] `position` is a valid iterator of the view. `first` and `last` are +valid iterators of the view. `last` is reachable from `first`. `position` is not
+in the range `[first,last)`.
+* [*Effects:] The range of elements `[first,last)` is repositioned just before
+`position`.
+* [*Postconditions:] No iterator or reference is invalidated.
+* [*Complexity:] Constant.
+* [*Exception safety:] nothrow.
+
+
+[endsect]
+
+
+[section Serialization]
+
+Views cannot be serialized on their own, but only as part of the `bimap`
+into which they are embedded. In describing the additional preconditions and guarantees +associated to `vector_of` views with respect to serialization of their embedding +containers, we use the concepts defined in the `bimap` serialization section.
+
+[blurb [*Operation:] saving of a `bimap` b to an output archive (XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container.
+
+
+[blurb [*Operation:] loading of a `bimap` b' from an input archive (XML archive) ar.]
+
+* [*Requires:] No additional requirements to those imposed by the container. +* [*Postconditions:] On successful loading, each of the elements of `[begin(), end())` is a +restored copy of the corresponding element in `[m.get<i>().begin(), m.get<i>().end())`,
+where `i` is the position of the `vector_of` view in the container.
+
+
+
+[blurb [*Operation:] saving of an `iterator` or `const_iterator` `it` to an output archive (XML archive) ar.]
+
+* [*Requires: ] `it` is a valid iterator of the view. The associated `bimap`
+has been previously saved.
+
+
+
+[blurb [*Operation:] loading of an `iterator` or `const_iterator` `it`' from an input archive (XML archive) ar.]
+
+* [*Postconditions:] On successful loading, if it was dereferenceable then `*it`' is the
+restored copy of `*it`, otherwise `it`'`==end()`.
+* [*Note:] It is allowed that it be a `const_iterator` and the restored `it`' an `iterator`,
+or viceversa.
+
+
+[endsect]
+[endsect]
+
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/reference.qbk Sun Feb  7 21:50:27 2010
@@ -0,0 +1,64 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Reference]
+
+[section Headers]
+
+The following are the interface headers of Boost.Bimap:
+
+[*Convenience]
+
+* "boost/bimap.hpp" ['(includes "boost/bimap/bimap.hpp" and imports the bimap class to boost namespace)]
+
+[*Container]
+
+* "boost/bimap/bimap.hpp" ['(includes "boost/bimap/set_of.hpp" and "boost/bimap/unconstrained_set_of.hpp")]
+
+[*Set Types]
+
+* "boost/bimap/set_of.hpp"
+* "boost/bimap/multiset_of.hpp"
+* "boost/bimap/unordered_set_of.hpp"
+* "boost/bimap/unordered_multiset_of.hpp"
+* "boost/bimap/list_of.hpp"
+* "boost/bimap/vector_of.hpp"
+* "boost/bimap/unconstrained_set_of.hpp"
+
+[*Boost Integration]
+
+* "boost/bimap/support/lambda.hpp"
+* "boost/bimap/property_map/set_support.hpp"
+* "boost/bimap/property_map/unordered_set_support.hpp"
+
+A program using Boost.Bimap must therefore include
+"boost/bimap/bimap.hpp" and the headers defining the collection types to be used.
+
+Additional headers allow the integration of Boost.Bimap with other boost libraries,
+like Boost.Lambda and Boost.Property_map.
+
+In order to use the serialization capabilities of Boost.Bimap, the appropriate +Boost.Serialization library module must be linked. Other than that, Boost.Bimap
+is a header-only library, requiring no additional object modules.
+
+[endsect]
+
+[include reference/bimap.qbk]
+[include reference/set_of.qbk]
+[include reference/unordered_set_of.qbk]
+[include reference/list_of.qbk]
+[include reference/vector_of.qbk]
+[include reference/unconstrained_set_of.qbk]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/release_notes.qbk     Sun Feb  7 21:50:27 2010
@@ -0,0 +1,19 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Release notes]
+
+Not yet released.
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/test_suite.qbk        Sun Feb  7 21:50:27 2010
@@ -0,0 +1,147 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Test suite]
+
+The Boost.Bimap test suite exercises the whole spectrum of functionalities provided by the library. +Although the tests are not meant to serve as a learning guide, the interested reader may find it +useful to inspect the source code to gain familiarity with some of the least common features
+offered by Boost.Bimap.
+
+[table
+[[Program                          ][Description                     ]
+]
+[[[@../../test/test_tagged.cpp
+    test_tagged.cpp                                                 ]]
+    [Tagged idiom checks                                            ]]
+
+[[[@../../test/test_mutant.cpp
+    test_mutant.cpp                                                 ]]
+    [Test the mutant idiom                                          ]]
+
+[[[@../../test/test_structured_pair.cpp
+    test_structured_pair.cpp                                        ]]
+    [Test structured pair class                                     ]]
+
+[[[@../../test/test_mutant_relation.cpp
+    test_mutant_relation.cpp                                        ]]
+    [Test the relation class                                        ]]
+
+[[[@../../test/test_bimap_set_of.cpp
+    test_bimap_set_of.cpp                                           ]]
+    [Library interface check                                        ]]
+
+[[[@../../test/test_bimap_multiset_of.cpp
+    test_bimap_multiset_of.cpp                                      ]]
+    [Library interface check                                        ]]
+
+[[[@../../test/test_bimap_unordered_set_of.cpp
+    test_bimap_unordered_set_of.cpp                                 ]]
+    [Library interface check                                        ]]
+
+[[[@../../test/test_bimap_unordered_multiset_of.cpp
+    test_bimap_unordered_multiset_of.cpp                            ]]
+    [Library interface check                                        ]]
+
+[[[@../../test/test_bimap_list_of.cpp
+    test_bimap_list_of.cpp                                          ]]
+    [Library interface check                                        ]]
+
+[[[@../../test/test_bimap_vector_of.cpp
+    test_bimap_vector_of.cpp                                        ]]
+    [Library interface check                                        ]]
+
+[[[@../../test/test_bimap_convenience_header.cpp
+    test_bimap_convenience_header.cpp                               ]]
+    [Library interface check                                        ]]
+
+[[[@../../test/test_bimap_ordered.cpp
+    test_bimap_ordered.cpp                                          ]]
+    [Test set and multiset based bimaps                             ]]
+
+[[[@../../test/test_bimap_unordered.cpp
+    test_bimap_unordered.cpp                                        ]]
+    [Test unordered_set and unordered_multiset based bimaps         ]]
+
+[[[@../../test/test_bimap_sequenced.cpp
+    test_bimap_sequenced.cpp                                        ]]
+    [Test list and vector based bimaps                              ]]
+
+[[[@../../test/test_bimap_unconstrained.cpp
+    test_bimap_unconstrained.cpp                                    ]]
+    [Test bimaps with unconstrained views                           ]]
+
+[[[@../../test/test_bimap_serialization.cpp
+    test_bimap_serialization.cpp                                    ]]
+    [Serialization support checks                                   ]]
+
+[[[@../../test/test_bimap_property_map.cpp
+    test_bimap_property_map.cpp                                     ]]
+    [Property map concepts for the set and unordered set views      ]]
+
+[[[@../../test/test_bimap_modify.cpp
+    test_bimap_modify.cpp                                           ]]
+    [`replace`, `modify` and `operator[]`                           ]]
+
+[[[@../../test/test_bimap_lambda.cpp
+    test_bimap_lambda.cpp                                           ]]
+    [Test lambda modified idom support                              ]]
+
+[[[@../../test/test_bimap_assign.cpp
+    test_bimap_assign.cpp                                           ]]
+    [Test Boost.Assign support                                      ]]
+
+[[[@../../test/test_bimap_project.cpp
+    test_bimap_project.cpp                                          ]]
+    [Projection of iterators support                                ]]
+
+[[[@../../test/test_bimap_operator_bracket.cpp
+    test_bimap_operator_bracket.cpp                                 ]]
+    [`operator[]` and `at()` functions                              ]]
+
+[[[@../../test/test_bimap_info.cpp
+    test_bimap_info.cpp                                             ]]
+    [Information hooking support                                    ]]
+
+[[[@../../test/test_bimap_extra.cpp
+    test_bimap_extra.cpp                                            ]]
+    [Additional checks                                              ]]
+
+[[[@../../test/compile_fail/test_bimap_info_1.cpp
+    test_bimap_info_1.cpp                                           ]]
+    [Information hooking compilation fail test                      ]]
+
+[[[@../../test/compile_fail/test_bimap_info_2.cpp
+    test_bimap_info_2.cpp                                           ]]
+    [Information hooking compilation fail test                      ]]
+
+[[[@../../test/compile_fail/test_bimap_info_3.cpp
+    test_bimap_info_3.cpp                                           ]]
+    [Information hooking compilation fail test                      ]]
+
+[[[@../../test/compile_fail/test_bimap_mutable_1.cpp
+    test_bimap_mutable_1.cpp                                        ]]
+    [Mutable members compilation fail test                          ]]
+
+[[[@../../test/compile_fail/test_bimap_mutable_2.cpp
+    test_bimap_mutable_2.cpp                                        ]]
+    [Mutable members compilation fail test                          ]]
+
+[[[@../../test/compile_fail/test_bimap_mutable_3.cpp
+    test_bimap_mutable_3.cpp                                        ]]
+    [Mutable members compilation fail test                          ]]
+
+]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/toolbox.qbk   Sun Feb  7 21:50:27 2010
@@ -0,0 +1,75 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section Bimap Toolbox]
+
+[section Mutant]
+
+[tip
+A mutant class defines storage compatible views in its declaration.
+You can the use the mutate<View>(m) function to get a view of the
+data with zero overhead.
+]
+
+__UNDER_CONSTRUCTION__
+
+[endsect]
+
+[section Structured_pair]
+
+[tip
+A structured pair allows you to control the order of the two types.
+You can instantiate it so the ['second] member appears in the first
+position.
+]
+
+__UNDER_CONSTRUCTION__
+
+
+[endsect]
+
+[section Tagged]
+
+[tip
+Tagged idiom and support metafunctions.
+]
+
+__UNDER_CONSTRUCTION__
+
+
+[endsect]
+
+[section Relation]
+
+[tip
+The bidirectional std::pair cousin.
+]
+
+__UNDER_CONSTRUCTION__
+
+[endsect]
+
+[section Container_adaptor]
+
+[tip
+Easy way to adapt a container so it behaves different in some aspect.
+It is the same concept that is use in iterator_adaptor.
+]
+
+__UNDER_CONSTRUCTION__
+
+[endsect]
+
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/bimap/doc/tutorial.qbk  Sun Feb  7 21:50:27 2010
@@ -0,0 +1,1057 @@
+[/license
+
+Boost.Bimap
+
+Copyright (c) 2006-2007 Matias Capeletto
+
+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)
+
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[section The tutorial]
+
+[section Roadmap]
+
+# Boost.Bimap is intuitive because it is based on the standard
+template library. New concepts are however presented to extend the
+standard maps to bidirectional maps. The first step is to gain a
+firm grasp of the bimap framework. The first section
+([link boost_bimap.the_tutorial.discovering_the_bimap_framework Discovering the bimap framework])
+aims to explain this.
+
+# Boost.Bimap offers much more than just a one-to-one ordered unique
+bidirectional map. It is possible to control the collection type of each side
+of the relationship that the bimap represents, giving one-to-many
+containers, hashed bidirectional containers and others that may be more
+suitable to the the task at hand. The second section
+([link boost_bimap.the_tutorial.controlling_collection_types Controlling collection types])
+explains how to instantiate a bimap with different collection constraints.
+
+# The section
+([link boost_bimap.the_tutorial.the_collection_of_relations_type The "collection of relations" type]) +explains how to create new types of bidirectional maps using custom collection types.
+
+# In the section [link boost_bimap.the_tutorial.differences_with_standard_maps Differences with standard maps] we will learn about the subtle differences between a bimap map view and a standard map.
+
+# The section [link boost_bimap.the_tutorial.useful_functions Useful functions] provides information
+about functions of a bimap that are not found in the STL.
+
+# The types of a bimap can be tagged so that each side is accessible
+by something closer to the problem than left and right. This leads to
+more readable, self-documenting code. The fourth section
+([link boost_bimap.the_tutorial.bimaps_with_user_defined_names Bimaps with user defined names]) shows
+how to use this feature.
+
+# The bimap mapping framework allows to disable a view of a bimap, including the standard
+mapping containers as a particular case. The section
+[link boost_bimap.the_tutorial.unconstrained_sets Unconstrained Sets] explains how they work.
+
+# The section [link boost_bimap.the_tutorial.additional_information Additional information]
+explains how to attach information to each relation of a bimap.
+
+# The final section
+([link boost_bimap.the_tutorial.complete_instantiation_scheme Complete Instantiation Scheme]) +summarizes bimap instantiation and explains how change the allocator type to be used.
+
+[endsect]
+
+[section Discovering the bimap framework]
+
+[section Interpreting bidirectional maps]
+
+One way to interpret bidirectional maps is as a function between two
+collections of data, lets call them the left and the right collection.
+An element in this bimap is a relation between an element from the left
+collection and an element from the right collection.
+The types of both collections defines the bimap behaviour. We can view
+the stored data from the left side, as a mapping between keys from the
+left collection and data from the right one, or from the right side, as
+a mapping between keys from the right collection and data from the
+left collection.
+
+[endsect]
+
+[section Standard mapping framework]
+
+Relationships between data in the STL are represented by maps. A
+standard map is a directed relation of keys from a left collection and
+data from a right unconstrained collection.
+The following diagram shows the relationship represented and the
+user's viewpoint.
+
+__STANDARD_MAPPING_FRAMEWORK__
+
+The left collection type depends on the selected map type. For example if the the map type is `std::multimap` the collection type of X is a `multiset_of`. +The following table shows the equivalent types for the std associative containers.
+
+[table std associative containers
+[[container           ][left collection type      ][right collection type]]
+[[`map`               ][`set_of`                  ][no constraints       ]]
+[[`multimap`          ][`multiset_of`             ][no constraints       ]]
+[[`unordered_map`     ][`unordered_set_of`        ][no constraints       ]]
+[[`unordered_multimap`][`unordered_multiset_of`   ][no constraints       ]]
+]
+
+[endsect]
+
+[section Bimap mapping framework]
+
+Boost.Bimap design is based on the STL, and extends the framework in a natural way.
+The following diagram represents the new situation.
+
+__EXTENDED_MAPPING_FRAMEWORK__
+
+Notice that now the `std::maps` are a particular case of a Boost.Bimap
+container, where you can view only one side of the relationship and can
+control the constraints of only one of the collections. Boost.Bimap
+allows the user to view the relationship from three viewpoints.
+You can view it from one side, obtaining a `std::map` compatible
+container, or you can work directly with the whole relation.
+
+The next diagram shows the layout of the relation and pairs of a bimap. It is
+the one from the ['one minute tutorial]
+
+__RELATION_AND_PAIR__
+
+Bimap pairs are signature-compatible with standard pairs but are different
+from them. As you will see in other sections they can be tagged with user
+defined names and additional information can be attached to them. You can
+convert from `std::pairs` to bimap pairs directly but the reverse conversion
+is not provided. This mean that you can insert elements in a bimap using
+algorithms like `std::copy` from containers `like std::map`, or use `std::make_pair` +to add new elements. However it is best to use `bm.left.insert( bm_type::left_value_type(f,s) )` instead of `bm.insert( std::make_pair(f,s) )` to avoid an extra call to the
+copy constructor of each type.
+
+The following code snippet shows the relation between a bimap and standard
+maps.
+
+[note
+You have to used references to views, and not directly views object.
+Views cannot be constructed as separate objects from the container they
+belong to, so the following:
+``
+// Wrong: we forgot the & after bm_type::left_type
+bm_type::left_map lm = bm.left;
+``
+does not compile, since it is trying to construct the view object `lm`.
+This is a common source of errors in user code.
+]
+
+[@../../example/standard_map_comparison.cpp Go to source code]
+
+[import ../example/standard_map_comparison.cpp]
+
+[code_standard_map_comparison]
+
+[endsect]
+
+[endsect]
+
+[section Controlling collection types]
+
+[section Freedom of choice]
+
+As has already been said, in STL maps, you can only control the
+constraints from one of the collections, namely the one that you are
+viewing. In Boost.Bimap, you can control both and it is as easy as using the STL.
+
+__EXTENDED_MAPPING_FRAMEWORK__
+
+The idea is to use the same constraint names that are used in the
+standard. If you don't specify the collection type, Boost.Bimap assumes
+that the collection is a set. The instantiation of a bimap with custom
+collection types looks like this:
+
+ typedef bimap< ``*CollectionType*``_of<A>, ``*CollectionType*``_of<B>
bm_type;
+
+The following is the list of all supported collection types.
+
+
+[table Collection of Key Types
+[[name                   ][Features          ][map view type            ]]
+[[`set_of`               ][['ordered, unique]][`map`                    ]]
+[[`multiset_of`          ][['ordered        ]][`multimap`               ]]
+[[`unordered_set_of`     ][['hashed, unique ]][`unordered_map`          ]]
+[[`unordered_multiset_of`][['hashed         ]][`unordered_multimap`     ]]
+[[`list_of`              ][['sequenced      ]][`list_map`               ]]
+[[`vector_of`            ][['random access  ]][`vector_map`             ]]
+[[`unconstrained_set_of` ][['unconstrained  ]][['can not be viewed]     ]]
+]
+
+
+`list_of` and `vector_of` map views are not associated with any existing STL
+associative containers. They are two examples of unsorted associative
+containers. `unconstrained_set_of` allow the user to ignore a view. This
+will be explained later.
+
+__BIMAP_STRUCTURES__
+
+The selection of the collection type affects the possible operations that you
+can perform with each side of the bimap and the time it takes to do
+each. If we have:
+
+ typedef bimap< ``*CollectionType*``_of<A>, ``*CollectionType*``_of<B>
bm_type;
+    bm_type bm;
+
+The following now describes the resulting map views of the bidirectional
+map.
+
+* `bm.left` is signature-compatible with *LeftMapType*`<A,B>`
+* `bm.right` is signature-compatible with *RightMapType*`<B,A>`
+
+[endsect]
+
+[section Configuration parameters]
+
+Each collection type template has different parameters to control its
+behaviour. For example, in `set_of` specification, you can pass a Functor
+type that compares two types. All of these parameters are exactly the
+same as those of the standard library container, except for the
+allocator type. You will learn later how to change the allocator for a
+bimap.
+
+The following table lists the meanings of each collection type's parameters.
+
+[table
+[[name                     ][Additional Parameters]]
+
+[[`set_of<T,KeyComp>`
+
+  `multiset_of<T,KeyComp>` ]
+
+[[*KeyComp ] is a Functor that compares two types using a less-than operator.
+By default, this is `std::less<T>`. ]]
+
+[[`unordered_set_of<T,HashFunctor,EqualKey>`
+
+  `unordered_multiset_of<T,HashFunctor,EqualKey>`]
+
+[[*HashFunctor ] converts a `T` object into an `std::size_t` value. By default it is `boost::hash<T>`.
+
+ [*EqualKey ] is a Functor that tests two types for equality. By default, the
+equality operator is `std::equal_to<T>`. ]]
+[[`list_of<T>`              ][No additional parameters.]]
+[[`vector_of<T>`            ][No additional parameters.]]
+[[`unconstrained_set_of<T>` ][No additional parameters.]]
+]
+
+[endsect]
+
+[section Examples]
+
+[heading Countries Populations]
+
+We want to store countries populations.
+The requeriments are:
+
+# Get a list of countries in decresing order of their populations.
+# Given a countrie, get their population.
+
+Lets create the appropiate bimap.
+
+    typedef bimap<
+
+        unordered_set_of< std::string >,
+        multiset_of< long, std::greater<long> >
+
+    > populations_bimap;
+
+First of all countries names are unique identifiers, while two countries
+may have the same population. This is why we choose *multi*`set_of` for
+populations.
+
+Using a `multiset_of` for population allow us to iterate over the data.
+Since listing countries ordered by their names is not a requisite, we can
+use an `unordered_set_of` that allows constant order look up.
+
+And now lets use it in a complete example
+
+[@../../example/population_bimap.cpp Go to source code]
+
+[import ../example/population_bimap.cpp]
+
+[code_population_bimap]
+
+
+[heading Repetitions counter]
+
+We want to count the repetitions for each word in a text and print them
+in order of appearance.
+
+[@../../example/repetitions_counter.cpp Go to source code]
+
+[import ../example/repetitions_counter.cpp]
+
+[code_repetitions_counter]
+
+[endsect]
+
+[endsect]
+
+[section The collection of relations type]
+
+[section A new point of view]
+
+Being able to change the collection type of the bimap relation view is another
+very important feature. Remember that this view allows the user to see
+the container as a group of the stored relations. This view has set
+semantics instead of map semantics.
+
+__COLLECTION_TYPE_OF_RELATION__
+
+By default, Boost.Bimap will base the collection type of the relation on the +type of the left collection. If the left collection type is a set, then the collection
+type of the relation will be a set with the same order as the left view.
+
+In general, Boost.Bimap users will base the collection type of a relation on
+the type of the collection on one of the two sides. However there are times
+where it is useful to give this collection other constraints or simply to order
+it differently. The user is allowed to choose between:
+
+* left_based
+* right_based
+* set_of_relation<>
+* multiset_of_relation<>
+* unordered_set_of_relation<>
+* unordered_multiset_of_relation<>
+* list_of_relation
+* vector_of_relation
+* unconstrained_set_of_relation
+
+[tip
+The first two options and the last produce faster bimaps, so prefer
+these where possible.
+]
+
+__MORE_BIMAP_STRUCTURES__
+
+The collection type of relation can be used to create powerful containers. For
+example, if you need to maximize search speed, then the best
+bidirectional map possible is one that relates elements from an
+`unordered_set` to another `unordered_set`. The problem is that this
+container cannot be iterated. If you need to know the list of relations
+inside the container, you need another collection type of relation. In this
+case, a `list_of_relation` is a good choice. The resulting container
+trades insertion and deletion time against fast search capabilities and
+the possibility of bidirectional iteration.
+
+[@../../example/mighty_bimap.cpp Go to source code]
+
+[code_mighty_bimap]
+
+[endsect]
+
+[section Configuration parameters]
+
+Each collection type of relation has different parameters to control its
+behaviour. For example, in the `set_of_relation` specification, you can
+pass a Functor type that compares two types. All of the parameters are
+exactly as in the standard library containers, except for the type,
+which is set to the bimap relation and the allocator type. To help users
+in the creation of each functor, the collection type of relation templates
+takes an mpl lambda expression where the relation type will be evaluated
+later. A placeholder named `_relation` is available to bimap users.
+
+The following table lists the meaning of the parameters for each collection type of
+relations.
+
+[table
+[[name                     ][Additional Parameters]]
+
+[[`left_based`                        ][Not a template.]]
+[[`right_based`                       ][Not a template.]]
+[[`set_of_relation<KeyComp>`
+
+  `multiset_of_relation<KeyComp>` ]
+[[*KeyComp ] is a Functor that compares two types using less than. By
+default, the less-than operator is `std::less<_relation>`. ]]
+
+[[`unordered_set_of_relation<HashFunctor,EqualKey>`
+
+  `unordered_multiset_of_relation<HashFunctor,EqualKey>`]
+[[*HashFunctor ] converts the `relation` into an `std::size_t` value. By default it is `boost::hash<_relation>`.
+
+ [*EqualKey ] is a Functor that tests two relations for equality. By default,
+the equality operator is `std::equal_to<_relation>`. ]]
+[[`list_of_relation`                  ][Not a template.]]
+[[`vector_of_relation`                ][Not a template.]]
+[[`unconstrained_set_of_relation`     ][Not a template.]]
+]
+
+[endsect]
+
+[section Examples]
+
+Consider this example:
+
+    template< class Rel >
+    struct RelOrder
+    {
+        bool operator()(Rel ra, Rel rb) const
+        {
+            return (ra.left+ra.right) < (rb.left+rb.right);
+        }
+    };
+
+    typedef bimap
+    <
+            multiset_of< int >,
+            multiset_of< int >,
+            set_of_relation< RelOrder<_relation> >
+
+    > bimap_type;
+
+Here the bimap relation view is ordered using the information of
+both sides. This container will only allow unique relations because
+`set_of_relation` has been used but the elements in each side of the
+bimap can be repeated.
+
+    struct name         {};
+    struct phone_number {};
+
+    typedef bimap
+    <
+        tagged< unordered_multiset_of< string >, name         >,
+        tagged< unordered_set_of     < int    >, phone_number >,
+        set_of_relation<>
+
+    > bimap_type;
+
+In this other case the bimap will relate names to phone numbers.
+Names can be repeated and phone numbers are unique. You can perform
+quick searches by name or phone number and the container can be viewed
+ordered using the relation view.
+
+[endsect]
+
+[endsect]
+
+[section Differences with standard maps]
+
+[section Insertion]
+
+Remember that a map can be interpreted as a relation between two collections.
+In bimaps we have the freedom to change both collection types, imposing
+constrains in each of them. Some insertions that we give for granted to
+success in standard maps fails with bimaps.
+For example:
+
+    bimap<int,std::string> bm;
+
+    bm.left.insert(1,"orange");
+    bm.left.insert(2,"orange"); // No effect! returns make_pair(iter,false)
+
+The insertion will only succeed if it is allowed by all views of the `bimap`.
+In the next snippet we define the right collection as a multiset, when we
+try to insert the same two elements the second insertion is allowed by the
+left map view because both values are different and it is allowed by the
+right map view because it is a non-unique collection type.
+
+    bimap<int, multiset_of<std::string> > bm;
+
+    bm.left.insert(1,"orange");
+    bm.left.insert(2,"orange"); // Insertion succeed!
+
+If we use a custom collection of relation type, the insertion has to be
+allowed by it too.
+
+[endsect]
+
+[section iterator::value_type]
+
+The relations stored in the Bimap will not be in most cases modifiable
+directly by iterators because both sides are used as keys of
+['key-based] sets. When a `bimap<A,B>` left view iterator is dereferenced
+the return type is ['signature-compatible] with a
+`std::pair< const A, const B >`.
+However there are some collection types that are not ['key_based], for example +list_of. If a Bimap uses one of these collection types there is no problem with
+modifying the data of that side. The following code is valid:
+
+    typedef bimap< int, list_of< std::string > > bm_type;
+    bm_type bm;
+    bm.insert( bm_type::relation( 1, "one" ) );
+    ...
+    bm.left.find(1)->second = "1"; // Valid
+
+In this case, when the iterator is dereferenced the return type is
+['signature-compatible] with a `std::pair<const int, std::string>`.
+
+The following table shows the constness of the dereferenced data of each
+collection type of:
+
+[table
+[[Side collection type   ][Dereferenced data]]
+[[`set_of`               ][['constant]]]
+[[`multiset_of`          ][['constant]]]
+[[`unordered_set_of`     ][['constant]]]
+[[`unordered_multiset_of`][['constant]]]
+[[`list_of`              ][['mutable] ]]
+[[`vector_of`            ][['mutable] ]]
+[[`unconstrained_set_of` ][['mutable] ]]
+]
+
+Here are some examples. When dereferenced the iterators returns a type that
+is ['signature-compatible] with these types.
+
+[table
+[[Bimap type   ][Signature-compatible types]]
+[[`bimap<A,B>`][
+    `iterator      ` *->* `relation<const A,const B>`
+
+    `left_iterator ` *->* `pair<const A,const B>`
+
+    `right_iterator` *->* `pair<const B,const A>`
+]]
+[[`bimap<multiset_of<A>,unordered_set_of<B> >`][
+    `iterator      ` *->* `relation<const A,const B>`
+
+    `left_iterator ` *->* `pair<const A,const B>`
+
+    `right_iterator` *->* `pair<const B,const A>`
+]]
+[[`bimap<set_of<A>,list_of<B> >`][
+    `iterator      ` *->* `relation<const A,B>`
+
+    `left_iterator ` *->* `pair<const A,B>`
+
+    `right_iterator` *->* `pair<B,const A>`
+]]
+[[`bimap<vector_of<A>,set_of<B> >`][
+    `iterator      ` *->* `relation<A,const B>`
+
+    `left_iterator ` *->* `pair<A,const B>`
+
+    `right_iterator` *->* `pair<const B,A>`
+]]
+[[`bimap<list_of<A>,unconstrained_set_of<B> >`][
+    `iterator      ` *->* `relation<A,B>`
+
+    `left_iterator ` *->* `pair<A,B>`
+
+    `right_iterator` *->* `pair<B,A>`
+]]
+]
+
+[endsect]
+
+[section operator\[\] and at()]
+
+`set_of` and `unordered_set_of` map views overload `operator[]` to retrieve the
+associated data of a given key only when the other collection type is a
+mutable one. In these cases it works in the same way as the standard.
+
+    bimap< unorderd_set_of< std::string>, list_of<int> > bm;
+
+    bm.left["one"] = 1; // Ok
+
+The standard defines an access function for `map` and `unordered_map`:
+
+    const data_type & at(const key_type & k) const;
+          data_type & at(const key_type & k);
+
+These functions look for a key and returns the associated data value, but
+throws a `std::out_of_range` exception if the key is not found.
+
+In bimaps the constant version of these functions is given for `set_of` and
+`unorderd_set_of` map views independently of the other collection type.
+The mutable version is only provided when the other collection type is
+mutable.
+
+The following examples shows the behaviour of `at(key)`
+
+[@../../example/at_function_examples.cpp Go to source code]
+
+[import ../example/at_function_examples.cpp]
+
+[code_at_function_first]
+
+[code_at_function_second]
+
+[/
+`set_of` and `unordered_set_of` views overload `operator[]` to retrieve the
+associated data of a given key.
+The symmetry of bimap imposes some constraints on `operator[]` that are
+not found in `std::map` or `std::unordered_map`. If other views are unique,
+`bimap::duplicate_value` is thrown whenever an assignment is attempted to
+a value that is already a key in these views. As for
+`bimap::value_not_found`, this exception is thrown while trying to access
+a non-existent key: this behaviour differs from the standard containers,
+which automatically assigns a default value to non-existent keys referred to
+by `operator[]`.
+
+
+    const data_type & operator[](const typename key_type & k) const;
+
+[:  Returns the `data_type` reference that is associated with `k`, or
+    throws `bimap::value_not_found` if such an element does not exist.
+]
+
+ ``['-unspecified data_type proxy-]`` operator[](const typename key_type & k);
+
+[:  Returns a proxy to a `data_type` associated with `k` and the
+ bimap. The proxy behaves as a reference to the `data_type` object. If this + proxy is read and `k` was not in the bimap, the bimap::value_not_found is
+    thrown. If it is written then `bimap::duplicate_value` is thrown if the
+    assignment is not allowed by one of the other views of the `bimap`.
+]
+
+
+The following example shows the behaviour of `operator[]`
+
+    bimap<int,std::string> bm;
+
+    bm.left[1] = "one"; // Ok
+
+    bm.right["two"] = 2; // Ok
+
+    if( bm.left[3] == "three" ) // throws bimap::value_not_found
+    {
+        ...
+    }
+
+    bm.left[3] = "one"; // throws bimap::duplicate_value
+]
+
+[endsect]
+
+[section Complexity of operations]
+
+The complexity of some operations is different in bimaps. Read
+[link complexity_signature_explanation the reference] to find the
+complexity of each function.
+
+[endsect]
+
+[endsect]
+
+[section Useful functions]
+
+[section Projection of iterators]
+
+Iterators can be projected to any of the three views of the bimap.
+A bimap provides three member functions to cope with projection: `project_left`, +`project_right` and `project_up`, with projects iterators to the ['left map view], +the ['right map view] and the ['collection of relations view]. These functions +take any iterator from the bimap and retrieve an iterator over the projected view
+pointing to the same element.
+
+[import ../example/projection.cpp]
+
+Here is an example that uses projection:
+
+[@../../example/projection.cpp Go to source code]
+
+[code_projection_years]
+
+[endsect]
+
+[section replace and modify]
+
+[import ../example/tutorial_modify_and_replace.cpp]
+
+These functions are members of the views of a bimap that are not founded in
+their standard counterparts.
+
+The `replace` family member functions performs in-place replacement of a given
+element as the following example shows:
+
+[@../../example/tutorial_modify_and_replace.cpp Go to source code]
+
+[code_tutorial_replace]
+
+`replace` functions performs this substitution in such a manner that:
+
+* The complexity is constant time if the changed element retains its original order
+with respect to all views; it is logarithmic otherwise.
+* Iterator and reference validity are preserved.
+* The operation is strongly exception-safe, i.e. the `bimap` remains unchanged if +some exception (originated by the system or the user's data types) is thrown.
+
+`replace` functions are powerful operations not provided by standard STL containers,
+and one that is specially handy when strong exception-safety is required.
+
+The observant reader might have noticed that the convenience of replace comes at a +cost: namely the whole element has to be copied ['twice] to do the updating (when +retrieving it and inside `replace`). If elements are expensive to copy, this may +be quite a computational cost for the modification of just a tiny part of the
+object. To cope with this situation, Boost.Bimap provides an alternative
+updating mechanism: `modify` functions.
+
+`modify` functions accepts a functor (or pointer to function) taking a reference +to the data to be changed, thus eliminating the need for spurious copies. Like +`replace` functions, `modify` functions does preserve the internal orderings of +all the indices of the `bimap`. However, the semantics of modify functions are not +entirely equivalent to replace functions. Consider what happens if a collision occurs +as a result of modifying the element, i.e. the modified element clashes with another +with respect to some unique view. In the case of `replace` functions, the original +value is kept and the method returns without altering the container, but `modify` +functions cannot afford such an approach, since the modifying functor leaves no +trace of the previous value of the element. Integrity constraints thus lead to the +following policy: when a collision happens in the process of calling a modify functions, +the element is erased and the method returns false. This difference in behavior +between `replace` and `modify` functions has to be considered by the programmer on
+a case-by-case basis.
+
+Boost.Bimap defines new placeholders named `_key` and `_data` to allow a sounder solution.
+You have to include `<boost/bimap/support/lambda.hpp>` to use them.
+
+[/
+Boost.Bimap defines new placeholders to allow a sounder solution. For
+pairs, two new placeholders are instantiated: `_first` and `_second`, and
+for a relation, two more complete the set: `_left` and `_right`.
+]
+
+[@../../example/tutorial_modify_and_replace.cpp Go to source code]
+
+[code_tutorial_modify]
+
+[endsect]
+
+[section Retrieval of ranges]
+
+[import ../example/tutorial_range.cpp]
+
+Standard `lower_bound` and `upper_bound` functions can be used to lookup for
+all the elements in a given range.
+
+Suppose we want to retrieve the elements from a `bimap<int,std::string>`
+where the left value is in the range `[20,50]`
+
+[code_tutorial_range_standard_way]
+
+Subtle changes to the code are required when strict inequalities are considered. +To retrieve the elements greater than 20 and less than 50, the code has to be
+rewritten as
+
+[code_tutorial_range_standard_way_subtle_changes]
+
+To add to this complexity, the careful programmer has to take into account that +the lower and upper bounds of the interval searched be compatible: for instance, +if the lower bound is 50 and the upper bound is 20, the iterators `iter_first` and +`iter_second` produced by the code above will be in reverse order, with possibly +catastrophic results if a traversal from `iter_first` to `iter_second` is tried.
+All these details make range searching a tedious and error prone task.
+
+The range member function, often in combination with lambda expressions,
+can greatly help alleviate this situation:
+
+[code_tutorial_range]
+
+`range` simply accepts predicates specifying the lower and upper bounds of
+the interval searched. Please consult the reference for a detailed explanation
+of the permissible predicates passed to range.
+
+One or both bounds can be omitted with the special unbounded marker:
+
+[code_tutorial_range_unbounded]
+
+[@../../example/tutorial_range.cpp Go to source code]
+
+[endsect]
+
+[endsect]
+
+[section Bimaps with user defined names]
+
+[import ../example/user_defined_names.cpp]
+
+In the following example, the library user inserted comments to guide
+future programmers:
+
+[@../../example/user_defined_names.cpp Go to source code]
+
+[code_user_defined_names_untagged_version]
+
+In Boost.Bimap there is a better way to document the code and
+in the meantime helping you to write more mantainable and readable code.
+You can tag the two collections of the bimap so they can be
+accessed by more descriptive names.
+
+__TAGGED__
+
+A tagged type is a type that has been labelled using a tag. A tag is any
+valid C++ type. In a bimap, the types are always tagged. If you do not
+specify your own tag, the container uses `member_at::left` and
+`member_at::right` to tag the left and right sides respectively. In order
+to specify a custom tag, the type of each side has to be tagged.
+Tagging a type is very simple:
+
+    typedef tagged< int, a_tag > tagged_int;
+
+Now we can rewrite the example:
+
+[@../../example/user_defined_names.cpp Go to source code]
+
+[code_user_defined_names_tagged_version]
+
+Here is a list of common structures in both tagged and untagged versions.
+Remember that when the bimap has user defined tags you can still use
+the untagged version structures.
+
+
+    struct Left  {};
+    struct Right {};
+    typedef bimap<
+             multiset_of< tagged< int, Left  > >,
+        unordered_set_of< tagged< int, Right > >
+    > bm_type;
+
+    bm_type bm;
+
+    //...
+
+    bm_type::iterator       iter       = bm.begin();
+    bm_type::left_iterator  left_iter  = bm.left.begin();
+    bm_type::right_iterator right_iter = bm.right.begin();
+
+
+
+[table Equivalence of expresions using user defined names
+[[Untagged version]               [Tagged version]                     ]
+[[`bm.left`]                      [`bm.by<Left>()`]                    ]
+[[`bm.right`]                     [`bm.by<Right>()`]                   ]
+[[`bm_type::left_map`]            [`bm::map_by<Left>::type`]           ]
+[[`bm_type::right_value_type`]    [`bm::map_by<Right>::value_type`]    ]
+[[`bm_type::left_iterator`]       [`bm::map_by<Left>::iterator`]       ]
+[[`bm_type::right_const_iterator`][`bm::map_by<Right>::const_iterator`]]
+[[`iter->left`]                   [`iter->get<Left>()`]                ]
+[[`iter->right`]                  [`iter->get<Right>()`]               ]
+[[`left_iter->first`]             [`left_iter->get<Left>()`]           ]
+[[`left_iter->second`]            [`left_iter->get<Right>()`]          ]
+[[`right_iter->first`]            [`right_iter->get<Right>()`]         ]
+[[`right_iter->second`]           [`right_iter->get<Left>()`]          ]
+[[`bm.project_left(iter)`]        [`bm.project<Left>(iter)`]           ]
+[[`bm.project_right(iter)`]       [`bm.project<Right>(iter)`]          ]
+]
+
+[endsect]
+
+[section Unconstrained Sets]
+
+Unconstrained sets allow the user to disable one of the views of a
+bimap. Doing so makes the bimap operations execute faster and reduces
+memory consumption. This completes the bidirectional mapping framework
+by including unidirectional mappings as a particular case.
+
+Unconstrained sets are useful for the following reasons:
+
+* A bimap type has stronger guarantees than its standard equivalent,
+and includes some useful functions (replace, modify) that the standard
+does not have.
+* You can view the mapping as a collection of relations.
+* Using this kind of map makes the code very extensible. If, at any
+moment of the development, the need to perform searches from the right
+side of the mapping arises, the only necessary change is to the `typedef`.
+
+[import ../example/unconstrained_collection.cpp]
+
+Given this bimap instance,
+
+[code_unconstrained_collection_bimap]
+
+or this standard map one
+
+[code_unconstrained_collection_map]
+
+The following code snippet is valid
+
+[code_unconstrained_collection_common]
+
+But using a bimap has some benefits
+
+[code_unconstrained_collection_only_for_bimap]
+
+[@../../example/unconstrained_collection.cpp Go to source code]
+
+[endsect]
+
+[section Additional information]
+
+[import ../example/tutorial_info_hook.cpp]
+
+Bidirectional maps may have associated information about each relation.
+Suppose we want to represent a books and author bidirectional map.
+
+[code_tutorial_info_hook_nothing]
+
+Suppose now that we want to store abstract of each book.
+We have two options:
+
+# Books name are unique identifiers, so we can create a separate
+`std::map< string, string >` that relates books names with abstracts.
+# We can use __BOOST_MULTI_INDEX__ for the new beast.
+
+Option 1 is the wrong approach, if we go this path we lost what bimap has
+won us. We now have to maintain the logic of two interdependent containers,
+there is an extra string stored for each book name, and the performance will
+be worse. This is far away from being a good solution.
+
+Option 2 is correct. We start thinking books as entries in a table. So it
+makes sense to start using Boost.MultiIndex. We can then add the year
+of publication, the price, etc... and we can index this new items too. So
+Boost.MultiIndex is a sound solution for our problem.
+
+The thing is that there are cases where we want to maintain bimap
+semantics (use `at()` to find an author given a book name and the other way
+around) and add information about the relations that we are sure we will not +want to index later (like the abstracts). Option 1 is not possible, option 2
+neither.
+
+Boost.Bimap provides support for this kind of situations by means of
+an embedded information member.
+You can pass an extra parameter to a bimap: `with_info< InfoType >`
+and an `info` member of type `InfoType` will appear in the relation and bimap
+pairs.
+
+__RELATION_AND_PAIR_WITH_INFO__
+
+Relations and bimap pairs constructors will take an extra argument.
+If only two arguments are used, the information will be initialized with
+their default constructor.
+
+[code_tutorial_info_hook_first]
+
+Contrary to the two key types, the information will be mutable using iterators.
+
+[code_tutorial_info_hook_mutable]
+
+A new function is included in ['unique] map views: `info_at(key)`, that mimics the +standard `at(key)` function but returned the associated information instead of
+the data.
+
+[code_tutorial_info_hook_info_at]
+
+The info member can be tagged just as the left or the right member. The following
+is a rewrite of the above example using user defined names:
+
+[code_tutorial_info_hook_tagged_info]
+
+[@../../example/tutorial_info_hook.cpp Go to source code]
+
+[endsect]
+
+[section Complete instantiation scheme]
+
+To summarize, this is the complete instantiation scheme.
+
+    typedef bimap
+    <
+        LeftCollectionType, RightCollectionType
+
+        [ , SetTypeOfRelation  ]  // Default to left_based
+        [ , with_info< Info >  ]  // Default to no info
+        [ , Allocator          ]  // Default to std::allocator<>
+
+    > bm;
+
+`{Side}CollectionType` can directly be a type. This defaults to
+`set_of<Type>`, or can be a `{CollectionType}_of<Type>` specification.
+Additionally, the type of this two parameters can be tagged to specify
+user defined names instead of the usual `member_at::-Side-` tags.
+
+The possibles way to use the first parameter are:
+
+    bimap< Type, R >
+
+* Left type:                `Type`
+* Left collection type:     `set_of< Type >`
+* Left tag:                 `member_at::left`
+
+    bimap< {CollectionType}_of< Type >, R >
+
+* Left type:                `Type`
+* Left collection type:     `{CollectionType}_of< LeftType >`
+* Left tag:                 `member_at::left`
+
+    bimap< tagged< Type, Tag >, R >
+
+* Left type:                `Type`
+* Left collection type:     `set_of< LeftType >`
+* Left tag:                 `Tag`
+
+    bimap< {CollectionType}_of< tagged< Type, Tag > >, R >
+
+* Left type:                `Type`
+* Left collection type:     `{CollectionType}_of< LeftType >`
+* Left tag:                 `Tag`
+
+The same options are available for the second parameter.
+
+The last three parameters are used to specify the collection type of the relation,
+the information member and the allocator type.
+
+If you want to specify a custom allocator type while relying on the default
+value of CollectionTypeOfRelation, you can do so by simply writing
+`bimap<LeftKeyType, RightKeyType, Allocator>`. Boost.Bimap's internal
+machinery detects that the third parameter in this case does not refer
+to the relation type but rather to an allocator.
+
+The following are the possible ways of instantiating the last three parameters +of a bimap. You can ignore some of the parameter but the order must be respected.
+
+
+    bimap< L, R >
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/libs/bimap/example/Jamfile.v2        Sun Feb  7 21:50:27 2010
@@ -0,0 +1,50 @@
+# Boost.Bimap
+#
+# Copyright (c) 2006-2007 Matias Capeletto
+#
+# 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)
+
+# bring in rules for testing
+import testing ;
+
+test-suite "examples"
+    :
+    [ compile mighty_bimap.cpp                                        ]
+    [ run     simple_bimap.cpp                                        ]
+    [ run     tagged_simple_bimap.cpp                                 ]
+    [ run     step_by_step.cpp                                        ]
+    [ run     population_bimap.cpp                                    ]
+    [ run     repetitions_counter.cpp                                 ]
+    [ compile user_defined_names.cpp                                  ]
+    [ run     standard_map_comparison.cpp                             ]
+    [ run     at_function_examples.cpp                                ]
+    [ run     tutorial_modify_and_replace.cpp                         ]
+    [ run     tutorial_range.cpp                                      ]
+    [ run     unconstrained_collection.cpp                            ]
+    [ run     tutorial_info_hook.cpp                                  ]
+    [ run     projection.cpp                                          ]
+    ;
+
+test-suite "bimap_and_boost"
+    :
+    [ run     bimap_and_boost/property_map.cpp                        ]
+    [ run     bimap_and_boost/range.cpp                               ]
+    [ run     bimap_and_boost/foreach.cpp                             ]
+    [ run     bimap_and_boost/lambda.cpp                              ]
+    [ run     bimap_and_boost/assign.cpp                              ]
+    [ run     bimap_and_boost/xpressive.cpp                           ]
+    [ run     bimap_and_boost/typeof.cpp                              ]
+    [ run     bimap_and_boost/serialization.cpp
+                    /boost/serialization//boost_serialization         ]
+    ;
+
+test-suite "mi_to_b_path"
+    :
+    [ compile mi_to_b_path/bidirectional_map.cpp                      ]
+    [ run     mi_to_b_path/hashed_indices.cpp                         ]
+    [ compile mi_to_b_path/tagged_bidirectional_map.cpp               ]
+    [ compile mi_to_b_path/mi_bidirectional_map.cpp                   ]
+    [ run     mi_to_b_path/mi_hashed_indices.cpp                      ]
+    ;
=======================================
--- /dev/null
+++ /trunk/libs/bimap/test/Jamfile.v2   Sun Feb  7 21:50:27 2010
@@ -0,0 +1,80 @@
+# Boost.Bimap
+#
+# Copyright (c) 2006-2007 Matias Capeletto
+#
+# 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)
+
+# bring in rules for testing
+import testing ;
+
+
+test-suite "tagged_test"
+    :
+ [ run test_tagged.cpp ]
+    ;
+
+
+test-suite "relation_test"
+    :
+ [ run test_structured_pair.cpp ] + [ run test_mutant.cpp ] + [ run test_mutant_relation.cpp ]
+    ;
+
+
+test-suite "bimap_test"
+    :
+
+    # Check library user interface
+ [ run test_bimap_set_of.cpp ] + [ run test_bimap_multiset_of.cpp ] + [ run test_bimap_unordered_set_of.cpp ] + [ run test_bimap_unordered_multiset_of.cpp ] + [ run test_bimap_list_of.cpp ] + [ run test_bimap_vector_of.cpp ]
+
+    # Test bimap container
+ [ run test_bimap_ordered.cpp ] + [ run test_bimap_unordered.cpp ] + [ run test_bimap_sequenced.cpp ] + [ run test_bimap_unconstrained.cpp ] + [ run test_bimap_assign.cpp ] + [ run test_bimap_property_map.cpp ] + [ run test_bimap_modify.cpp ] + [ run test_bimap_range.cpp ] + [ run test_bimap_operator_bracket.cpp ] + [ run test_bimap_lambda.cpp ] + [ run test_bimap_mutable.cpp ] + [ run test_bimap_extra.cpp ] + [ run test_bimap_convenience_header.cpp ] + [ run test_bimap_project.cpp ]
+    [ run test_bimap_serialization.cpp
+ /boost/serialization//boost_serialization ] + [ run test_bimap_info.cpp ]
+    ;
+
+test-suite "compile_fail_test"
+    :
+
+ [ compile-fail compile_fail/test_bimap_mutable_1.cpp ] + [ compile-fail compile_fail/test_bimap_mutable_2.cpp ] + [ compile-fail compile_fail/test_bimap_mutable_3.cpp ] + [ compile-fail compile_fail/test_bimap_info_1.cpp ] + [ compile-fail compile_fail/test_bimap_info_2.cpp ] + [ compile-fail compile_fail/test_bimap_info_3.cpp ]
+    ;
+
+test-suite "bimap_and_boost"
+    :
+ [ run ../example/bimap_and_boost/property_map.cpp ] + [ run ../example/bimap_and_boost/range.cpp ] + [ run ../example/bimap_and_boost/foreach.cpp ] + [ run ../example/bimap_and_boost/lambda.cpp ] + [ run ../example/bimap_and_boost/assign.cpp ] + [ run ../example/bimap_and_boost/xpressive.cpp ] + [ run ../example/bimap_and_boost/typeof.cpp ]
+    [ compile ../example/bimap_and_boost/serialization.cpp
+ /boost/serialization//boost_serialization ]
+    ;
=======================================
--- /dev/null
+++ /trunk/libs/bind/test/Jamfile.v2    Sun Feb  7 21:50:27 2010
@@ -0,0 +1,47 @@
+#  Boost.Bind Library test Jamfile
+#
+#  Copyright (c) 2003-2006 Peter Dimov
+#
+#  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)
+
+# bring in rules for testing
+import testing ;
+
+test-suite "bind"
+    : [ run bind_test.cpp ]
+      [ run bind_dm_test.cpp ]
+      [ run bind_eq_test.cpp ]
+      [ run bind_const_test.cpp ]
+      [ run bind_cv_test.cpp ]
+      [ run bind_stateful_test.cpp ]
+      [ run bind_dm2_test.cpp ]
+      [ run bind_not_test.cpp ]
+      [ run bind_rel_test.cpp ]
+      [ run bind_function_test.cpp ]
+      [ run bind_lookup_problem_test.cpp ]
+      [ run bind_rv_sp_test.cpp ]
+      [ compile bind_unary_addr.cpp ]
+      [ run bind_dm3_test.cpp ]
+      [ run bind_visit_test.cpp ]
+      [ run bind_placeholder_test.cpp ]
+      [ run bind_rvalue_test.cpp ]
+      [ run bind_and_or_test.cpp ]
+      [ run mem_fn_test.cpp ]
+      [ run mem_fn_void_test.cpp ]
+      [ run mem_fn_derived_test.cpp ]
+      [ run mem_fn_eq_test.cpp ]
+      [ run mem_fn_dm_test.cpp ]
+      [ run mem_fn_rv_test.cpp ]
+      [ run ref_fn_test.cpp ]
+      [ run bind_fnobj2_test.cpp ]
+      [ run bind_fn2_test.cpp ]
+      [ run bind_mf2_test.cpp ]
+      [ run bind_eq2_test.cpp ]
+      [ run mem_fn_ref_test.cpp ]
+      [ run bind_ref_test.cpp ]
+      [ run bind_eq3_test.cpp ]
+      [ run protect_test.cpp ]
+      [ run mem_fn_unary_addr_test.cpp ]
+    ;
=======================================
--- /dev/null
+++ /trunk/libs/bind/test/bind_eq2_test.cpp     Sun Feb  7 21:50:27 2010
@@ -0,0 +1,49 @@
+#include <boost/config.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(disable: 4786)  // identifier truncated in debug info
+#pragma warning(disable: 4710)  // function not inlined
+#pragma warning(disable: 4711) // function selected for automatic inline expansion
+#pragma warning(disable: 4514)  // unreferenced inline removed
+#endif
+
+//
+//  bind_eq2_test.cpp - boost::bind equality operator
+//
+//  Copyright (c) 2004, 2005, 2009 Peter Dimov
+//
+// 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/bind.hpp>
+#include <boost/function_equal.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void f( int )
+{
+}
+
+int g( int i )
+{
+    return i + 5;
+}
+
+template< class F > void test_self_equal( F f )
+{
+#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+    using boost::function_equal;
+#endif
+
+    BOOST_TEST( function_equal( f, f ) );
+}
+
+int main()
+{
+    test_self_equal( boost::bind( f, _1 ) );
+    test_self_equal( boost::bind( g, _1 ) );
+    test_self_equal( boost::bind( f, boost::bind( g, _1 ) ) );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/bind/test/bind_eq3_test.cpp     Sun Feb  7 21:50:27 2010
@@ -0,0 +1,45 @@
+#include <boost/config.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(disable: 4786)  // identifier truncated in debug info
+#pragma warning(disable: 4710)  // function not inlined
+#pragma warning(disable: 4711) // function selected for automatic inline expansion
+#pragma warning(disable: 4514)  // unreferenced inline removed
+#endif
+
+//
+//  bind_eq3_test.cpp - function_equal with bind and weak_ptr
+//
+//  Copyright (c) 2004, 2005, 2009 Peter Dimov
+//
+//  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/bind.hpp>
+#include <boost/function_equal.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int f( boost::weak_ptr<void> wp )
+{
+    return wp.use_count();
+}
+
+template< class F > void test_self_equal( F f )
+{
+#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+    using boost::function_equal;
+#endif
+
+    BOOST_TEST( function_equal( f, f ) );
+}
+
+int main()
+{
+    test_self_equal( boost::bind( f, _1 ) );
+    test_self_equal( boost::bind( f, boost::weak_ptr<void>() ) );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/bind/test/bind_ref_test.cpp     Sun Feb  7 21:50:27 2010
@@ -0,0 +1,36 @@
+//
+//  bind_ref_test.cpp - reference_wrapper
+//
+//  Copyright (c) 2009 Peter Dimov
+//
+//  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/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct X
+{
+    int f( int x )
+    {
+        return x;
+    }
+
+    int g( int x ) const
+    {
+        return -x;
+    }
+};
+
+int main()
+{
+    X x;
+
+    BOOST_TEST( boost::bind( &X::f, _1, 1 )( boost::ref( x ) ) == 1 );
+    BOOST_TEST( boost::bind( &X::g, _1, 2 )( boost::cref( x ) ) == -2 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/bind/test/mem_fn_ref_test.cpp   Sun Feb  7 21:50:27 2010
@@ -0,0 +1,36 @@
+//
+//  mem_fn_ref_test.cpp - reference_wrapper
+//
+//  Copyright (c) 2009 Peter Dimov
+//
+//  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/mem_fn.hpp>
+#include <boost/ref.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct X
+{
+    int f()
+    {
+        return 1;
+    }
+
+    int g() const
+    {
+        return 2;
+    }
+};
+
+int main()
+{
+    X x;
+
+    BOOST_TEST( boost::mem_fn( &X::f )( boost::ref( x ) ) == 1 );
+    BOOST_TEST( boost::mem_fn( &X::g )( boost::cref( x ) ) == 2 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/bind/test/mem_fn_unary_addr_test.cpp Sun Feb 7 21:50:27 2010
@@ -0,0 +1,151 @@
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(disable: 4786)  // identifier truncated in debug info
+#pragma warning(disable: 4710)  // function not inlined
+#pragma warning(disable: 4711) // function selected for automatic inline expansion
+#pragma warning(disable: 4514)  // unreferenced inline removed
+#endif
+
+//
+//  mem_fn_unary_addr_test.cpp - poisoned operator& test
+//
+//  Copyright (c) 2009 Peter Dimov
+//
+//  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/mem_fn.hpp>
+
+#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
+#pragma warning(push, 3)
+#endif
+
+#include <iostream>
+
+#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
+#pragma warning(pop)
+#endif
+
+unsigned int hash = 0;
+
+struct X
+{
+    int f0() { f1(17); return 0; }
+    int g0() const { g1(17); return 0; }
+
+    int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
+ int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
+
+    int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
+    int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
+
+    int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
+    int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
+
+ int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; } + int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
+
+ int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; } + int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
+
+ int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; } + int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
+
+ int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; } + int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
+
+ int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; } + int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
+};
+
+template<class T> class Y
+{
+private:
+
+    T * pt_;
+
+    void operator& ();
+    void operator& () const;
+
+public:
+
+    explicit Y( T * pt ): pt_( pt )
+    {
+    }
+
+    T * get() const
+    {
+        return pt_;
+    }
+};
+
+#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x620 ) )
+namespace boost
+{
+#endif
+
+template<class T> T * get_pointer( Y< T > const & y )
+{
+    return y.get();
+}
+
+#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x620 ) )
+} // namespace boost
+#endif
+
+int detect_errors(bool x)
+{
+    if( x )
+    {
+        std::cerr << "no errors detected.\n";
+        return 0;
+    }
+    else
+    {
+        std::cerr << "test failed.\n";
+        return 1;
+    }
+}
+
+int main()
+{
+    using boost::mem_fn;
+
+    X x;
+
+    Y<X> px( &x );
+    Y<X const> pcx( &x );
+
+    mem_fn(&X::f0)( px );
+    mem_fn(&X::g0)( pcx );
+
+    mem_fn(&X::f1)( px, 1 );
+    mem_fn(&X::g1)( pcx, 1 );
+
+    mem_fn(&X::f2)( px, 1, 2 );
+    mem_fn(&X::g2)( pcx, 1, 2 );
+
+    mem_fn(&X::f3)( px, 1, 2, 3 );
+    mem_fn(&X::g3)( pcx, 1, 2, 3 );
+
+    mem_fn(&X::f4)( px, 1, 2, 3, 4 );
+    mem_fn(&X::g4)( pcx, 1, 2, 3, 4 );
+
+    mem_fn(&X::f5)( px, 1, 2, 3, 4, 5 );
+    mem_fn(&X::g5)( pcx, 1, 2, 3, 4, 5 );
+
+    mem_fn(&X::f6)( px, 1, 2, 3, 4, 5, 6 );
+    mem_fn(&X::g6)( pcx, 1, 2, 3, 4, 5, 6 );
+
+    mem_fn(&X::f7)( px, 1, 2, 3, 4, 5, 6, 7 );
+    mem_fn(&X::g7)( pcx, 1, 2, 3, 4, 5, 6, 7 );
+
+    mem_fn(&X::f8)( px, 1, 2, 3, 4, 5, 6, 7, 8 );
+    mem_fn(&X::g8)( pcx, 1, 2, 3, 4, 5, 6, 7, 8 );
+
+    return detect_errors( hash == 2155 );
+}
=======================================
--- /dev/null
+++ /trunk/libs/bind/test/protect_test.cpp      Sun Feb  7 21:50:27 2010
@@ -0,0 +1,281 @@
+//  protect_test.cpp
+//
+//  Copyright (c) 2009 Steven Watanabe
+//
+// 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/bind/protect.hpp>
+#include <boost/bind/bind.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int f(int x)
+{
+    return x;
+}
+
+int& g(int& x)
+{
+    return x;
+}
+
+template<class T>
+const T& constify(const T& arg)
+{
+    return arg;
+}
+
+int main()
+{
+    int i[9] = {0,1,2,3,4,5,6,7,8};
+
+    // non-const
+
+    // test nullary
+    BOOST_TEST(boost::protect(boost::bind(f, 1))() == 1);
+
+    // test lvalues
+
+    BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0]) == &i[0]);
+
+    BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1]) == &i[0]);
+    BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1]) == &i[1]);
+
+ BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2]) == &i[2]);
+
+ BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3]) == &i[3]);
+
+ BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4]) == &i[4]);
+
+ BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]);
+
+ BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]); + BOOST_TEST(&boost::protect(boost::bind(g, _7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]);
+
+ BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]); + BOOST_TEST(&boost::protect(boost::bind(g, _7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]); + BOOST_TEST(&boost::protect(boost::bind(g, _8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]);
+
+ BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]); + BOOST_TEST(&boost::protect(boost::bind(g, _7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]); + BOOST_TEST(&boost::protect(boost::bind(g, _8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]); + BOOST_TEST(&boost::protect(boost::bind(g, _9))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]);
+
+    // test rvalues
+
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(0) == 0);
+
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1) == 0);
+    BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1) == 1);
+
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2) == 0);
+    BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2) == 1);
+    BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2) == 2);
+
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3) == 0);
+    BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3) == 1);
+    BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3) == 2);
+    BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3) == 3);
+
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4) == 0);
+    BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4) == 1);
+    BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4) == 2);
+    BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4) == 3);
+    BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4) == 4);
+
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5) == 0);
+    BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5) == 1);
+    BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5) == 2);
+    BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5) == 3);
+    BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5) == 4);
+    BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5) == 5);
+
+ BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5, 6) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5, 6) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5, 6) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5, 6) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5, 6) == 4); + BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5, 6) == 5); + BOOST_TEST(boost::protect(boost::bind(f, _7))(0, 1, 2, 3, 4, 5, 6) == 6);
+
+ BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5, 6, 7) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5, 6, 7) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5, 6, 7) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5, 6, 7) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5, 6, 7) == 4); + BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5, 6, 7) == 5); + BOOST_TEST(boost::protect(boost::bind(f, _7))(0, 1, 2, 3, 4, 5, 6, 7) == 6); + BOOST_TEST(boost::protect(boost::bind(f, _8))(0, 1, 2, 3, 4, 5, 6, 7) == 7);
+
+ BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4); + BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5); + BOOST_TEST(boost::protect(boost::bind(f, _7))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6); + BOOST_TEST(boost::protect(boost::bind(f, _8))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7); + BOOST_TEST(boost::protect(boost::bind(f, _9))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8);
+
+    // test mixed perfect forwarding
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(i[0], 1) == 0);
+    BOOST_TEST(boost::protect(boost::bind(f, _2))(i[0], 1) == 1);
+    BOOST_TEST(boost::protect(boost::bind(f, _1))(0, i[1]) == 0);
+    BOOST_TEST(boost::protect(boost::bind(f, _2))(0, i[1]) == 1);
+
+    // const
+
+    // test nullary
+ BOOST_TEST(constify(constify(boost::protect(boost::bind(f, 1))))() == 1);
+
+    // test lvalues
+ BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _1))))(i[0]) == &i[0]);
+
+ BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _1))))(i[0], i[1]) == &i[0]); + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _2))))(i[0], i[1]) == &i[1]);
+
+ BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _1))))(i[0], i[1], i[2]) == &i[0]); + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _2))))(i[0], i[1], i[2]) == &i[1]); + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _3))))(i[0], i[1], i[2]) == &i[2]);
+
+ BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3]) == &i[3]);
+
+ BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4]) == &i[4]);
+
+ BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]);
+
+ BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]);
+
+ BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]);
+
+ BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _9)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]);
+
+    // test rvalues
+
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0) == 0);
+
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1) == 0);
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1) == 1);
+
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2) == 0);
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2) == 1);
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2) == 2);
+
+ BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3) == 3);
+
+ BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4) == 4);
+
+ BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5) == 5);
+
+ BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5, 6) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5, 6) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5, 6) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5, 6) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5, 6) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5, 6) == 5); + BOOST_TEST(constify(boost::protect(boost::bind(f, _7)))(0, 1, 2, 3, 4, 5, 6) == 6);
+
+ BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5, 6, 7) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5, 6, 7) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5, 6, 7) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5, 6, 7) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5, 6, 7) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5, 6, 7) == 5); + BOOST_TEST(constify(boost::protect(boost::bind(f, _7)))(0, 1, 2, 3, 4, 5, 6, 7) == 6); + BOOST_TEST(constify(boost::protect(boost::bind(f, _8)))(0, 1, 2, 3, 4, 5, 6, 7) == 7);
+
+ BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5); + BOOST_TEST(constify(boost::protect(boost::bind(f, _7)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6); + BOOST_TEST(constify(boost::protect(boost::bind(f, _8)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7); + BOOST_TEST(constify(boost::protect(boost::bind(f, _9)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8);
+
+    // test mixed perfect forwarding
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(i[0], 1) == 0);
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(i[0], 1) == 1);
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, i[1]) == 0);
+    BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, i[1]) == 1);
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/circular_buffer/test/Jamfile.v2 Sun Feb  7 21:50:27 2010
@@ -0,0 +1,30 @@
+# Boost circular_buffer test Jamfile.
+#
+# Copyright (c) 2003-2008 Jan Gaspar
+#
+# 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)
+
+# Added warning supression Paul A. Bristow 25 Nov 2008
+
+# Bring in rules for testing.
+import testing ;
+
+project
+    : requirements
+      <toolset>msvc:<warnings>all
+      <toolset>msvc:<asynch-exceptions>on
+      <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+      <toolset>msvc:<cxxflags>/wd4996 # 'function': was declared deprecated
+ <toolset>msvc:<cxxflags>/wd4244 # conversion from 'int' to 'unsigned short', possible loss of data
+      # in date-time
+      ;
+
+test-suite "circular_buffer"
+  : [ run base_test.cpp : <threading>single : ]
+    [ run space_optimized_test.cpp : <threading>single : ]
+    [ run soft_iterator_invalidation.cpp : <threading>single : ]
+    [ run constant_erase_test.cpp : <threading>single : ]
+    [ compile bounded_buffer_comparison.cpp : <threading>multi : ]
+  ;
=======================================
--- /dev/null
+++ /trunk/libs/circular_buffer/test/constant_erase_test.cpp Sun Feb 7 21:50:27 2010
@@ -0,0 +1,187 @@
+// Special tests for erase_begin, erase_end and clear methods.
+
+// Copyright (c) 2009 Jan Gaspar
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CB_DISABLE_DEBUG
+
+#include "test.hpp"
+
+int MyInteger::ms_exception_trigger = 0;
+int InstanceCounter::ms_count = 0;
+
+void erase_begin_test() {
+
+    circular_buffer<int> cb1(5);
+    cb1.push_back(1);
+    cb1.push_back(2);
+    cb1.push_back(3);
+    cb1.push_back(4);
+    cb1.push_back(5);
+    cb1.push_back(6);
+
+    circular_buffer<int>::pointer p = &cb1[0];
+
+    cb1.erase_begin(2);
+
+    BOOST_CHECK(cb1.size() == 3);
+    BOOST_CHECK(cb1[0] == 4);
+    BOOST_CHECK(cb1[1] == 5);
+    BOOST_CHECK(cb1[2] == 6);
+
+    cb1.erase_begin(3);
+    BOOST_CHECK(cb1.empty());
+    BOOST_CHECK(*p == 2);
+    BOOST_CHECK(*(p + 1) == 3);
+    BOOST_CHECK(*(p + 2) == 4);
+
+    cb1.push_back(10);
+    cb1.push_back(11);
+    cb1.push_back(12);
+
+    BOOST_CHECK(cb1.size() == 3);
+    BOOST_CHECK(cb1[0] == 10);
+    BOOST_CHECK(cb1[1] == 11);
+    BOOST_CHECK(cb1[2] == 12);
+
+    circular_buffer<InstanceCounter> cb2(5, InstanceCounter());
+
+    BOOST_CHECK(cb2.size() == 5);
+    BOOST_CHECK(InstanceCounter::count() == 5);
+
+    cb2.erase_begin(2);
+
+    BOOST_CHECK(cb2.size() == 3);
+    BOOST_CHECK(InstanceCounter::count() == 3);
+
+    circular_buffer<MyInteger> cb3(5);
+    cb3.push_back(1);
+    cb3.push_back(2);
+    cb3.push_back(3);
+    cb3.push_back(4);
+    cb3.push_back(5);
+    cb3.push_back(6);
+    cb3.erase_begin(2);
+
+    BOOST_CHECK(cb3.size() == 3);
+    BOOST_CHECK(cb3[0] == 4);
+    BOOST_CHECK(cb3[1] == 5);
+    BOOST_CHECK(cb3[2] == 6);
+}
+
+void erase_end_test() {
+
+    circular_buffer<int> cb1(5);
+    cb1.push_back(1);
+    cb1.push_back(2);
+    cb1.push_back(3);
+    cb1.push_back(4);
+    cb1.push_back(5);
+    cb1.push_back(6);
+
+    circular_buffer<int>::pointer p = &cb1[3];
+
+    cb1.erase_end(2);
+
+    BOOST_CHECK(cb1.size() == 3);
+    BOOST_CHECK(cb1[0] == 2);
+    BOOST_CHECK(cb1[1] == 3);
+    BOOST_CHECK(cb1[2] ==4);
+
+    cb1.erase_end(3);
+    BOOST_CHECK(cb1.empty());
+    BOOST_CHECK(*p == 5);
+    BOOST_CHECK(*(p - 1) == 4);
+    BOOST_CHECK(*(p - 2) == 3);
+
+    cb1.push_back(10);
+    cb1.push_back(11);
+    cb1.push_back(12);
+
+    BOOST_CHECK(cb1.size() == 3);
+    BOOST_CHECK(cb1[0] == 10);
+    BOOST_CHECK(cb1[1] == 11);
+    BOOST_CHECK(cb1[2] == 12);
+
+    circular_buffer<InstanceCounter> cb2(5, InstanceCounter());
+
+    BOOST_CHECK(cb2.size() == 5);
+    BOOST_CHECK(InstanceCounter::count() == 5);
+
+    cb2.erase_end(2);
+
+    BOOST_CHECK(cb2.size() == 3);
+    BOOST_CHECK(InstanceCounter::count() == 3);
+
+    circular_buffer<MyInteger> cb3(5);
+    cb3.push_back(1);
+    cb3.push_back(2);
+    cb3.push_back(3);
+    cb3.push_back(4);
+    cb3.push_back(5);
+    cb3.push_back(6);
+    cb3.erase_end(2);
+
+    BOOST_CHECK(cb3.size() == 3);
+    BOOST_CHECK(cb3[0] == 2);
+    BOOST_CHECK(cb3[1] == 3);
+    BOOST_CHECK(cb3[2] == 4);
+}
+
+void clear_test() {
+
+    circular_buffer<int> cb1(5);
+    cb1.push_back(1);
+    cb1.push_back(2);
+    cb1.push_back(3);
+    cb1.push_back(4);
+    cb1.push_back(5);
+    cb1.push_back(6);
+
+    circular_buffer<int>::pointer p = &cb1[0];
+
+    cb1.clear();
+
+    BOOST_CHECK(cb1.empty());
+    BOOST_CHECK(*p == 2);
+    BOOST_CHECK(*(p + 1) == 3);
+    BOOST_CHECK(*(p + 2) == 4);
+    BOOST_CHECK(*(p + 3) == 5);
+    BOOST_CHECK(*(p - 1) == 6);
+
+    circular_buffer<InstanceCounter> cb2(5, InstanceCounter());
+
+    BOOST_CHECK(cb2.size() == 5);
+    BOOST_CHECK(InstanceCounter::count() == 5);
+
+    cb2.clear();
+
+    BOOST_CHECK(cb2.empty());
+    BOOST_CHECK(InstanceCounter::count() == 0);
+
+    circular_buffer<MyInteger> cb3(5);
+    cb3.push_back(1);
+    cb3.push_back(2);
+    cb3.push_back(3);
+    cb3.push_back(4);
+    cb3.push_back(5);
+    cb3.push_back(6);
+    cb3.clear();
+
+    BOOST_CHECK(cb3.empty());
+}
+
+// test main
+test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[]) {
+
+ test_suite* tests = BOOST_TEST_SUITE("Unit tests for erase_begin/end and clear methods of the circular_buffer.");
+
+    tests->add(BOOST_TEST_CASE(&erase_begin_test));
+    tests->add(BOOST_TEST_CASE(&erase_end_test));
+    tests->add(BOOST_TEST_CASE(&clear_test));
+
+    return tests;
+}
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/Jamfile       Sun Feb  7 21:50:27 2010
@@ -0,0 +1,16 @@
+# Boost Exception Library example Jamfile
+#
+# Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+#
+# 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)
+
+exe example_io : example_io.cpp ;
+obj error_info_1 : error_info_1.cpp ;
+obj error_info_2 : error_info_2.cpp ;
+obj cloning_1 : cloning_1.cpp ;
+obj cloning_2 : cloning_2.cpp : <threading>multi ;
+obj info_tuple : info_tuple.cpp ;
+obj enable_error_info : enable_error_info.cpp ;
+obj logging : logging.cpp ;
+obj errinfos : errinfos.cpp ;
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/cloning_1.cpp Sun Feb  7 21:50:27 2010
@@ -0,0 +1,21 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example shows how to enable cloning when throwing a boost::exception.
+
+#include <boost/exception/info.hpp>
+#include <boost/exception/errinfo_errno.hpp>
+#include <stdio.h>
+#include <errno.h>
+
+struct file_read_error: virtual boost::exception { };
+
+void
+file_read( FILE * f, void * buffer, size_t size )
+    {
+    if( size!=fread(buffer,1,size,f) )
+        throw boost::enable_current_exception(file_read_error()) <<
+            boost::errinfo_errno(errno);
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/cloning_2.cpp Sun Feb  7 21:50:27 2010
@@ -0,0 +1,39 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example shows how to transport cloning-enabled boost::exceptions between threads.
+
+#include <boost/exception_ptr.hpp>
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
+
+void do_work(); //throws cloning-enabled boost::exceptions
+
+void
+worker_thread( boost::exception_ptr & error )
+    {
+    try
+        {
+        do_work();
+        error = boost::exception_ptr();
+        }
+    catch(
+    ... )
+        {
+        error = boost::current_exception();
+        }
+    }
+
+// ...continued
+
+void
+work()
+    {
+    boost::exception_ptr error;
+    boost::thread t( boost::bind(worker_thread,boost::ref(error)) );
+    t.join();
+    if( error )
+        boost::rethrow_exception(error);
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/enable_error_info.cpp Sun Feb 7 21:50:27 2010
@@ -0,0 +1,35 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example shows how to throw exception objects that support
+//transporting of arbitrary data to the catch site, even for types
+//that do not derive from boost::exception.
+
+#include <boost/exception/all.hpp>
+#include <stdexcept>
+
+typedef boost::error_info<struct tag_std_range_min,size_t> std_range_min;
+typedef boost::error_info<struct tag_std_range_max,size_t> std_range_max;
+typedef boost::error_info<struct tag_std_range_index,size_t> std_range_index;
+
+template <class T>
+class
+my_container
+    {
+    public:
+
+    size_t size() const;
+
+    T const &
+    operator[]( size_t i ) const
+        {
+        if( i > size() )
+ throw boost::enable_error_info(std::range_error("Index out of range")) <<
+                std_range_min(0) <<
+                std_range_max(size()) <<
+                std_range_index(i);
+        //....
+        }
+    };
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/errinfos.cpp  Sun Feb  7 21:50:27 2010
@@ -0,0 +1,53 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example demonstrates the intended use of various commonly used
+//error_info typedefs provided by Boost Exception.
+
+#include <boost/exception/errinfo_api_function.hpp>
+#include <boost/exception/errinfo_at_line.hpp>
+#include <boost/exception/errinfo_errno.hpp>
+#include <boost/exception/errinfo_file_handle.hpp>
+#include <boost/exception/errinfo_file_name.hpp>
+#include <boost/exception/errinfo_file_open_mode.hpp>
+#include <boost/exception/info.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <stdio.h>
+#include <errno.h>
+#include <exception>
+
+struct error : virtual std::exception, virtual boost::exception { };
+struct file_error : virtual error { };
+struct file_open_error: virtual file_error { };
+struct file_read_error: virtual file_error { };
+
+boost::shared_ptr<FILE>
+open_file( char const * file, char const * mode )
+    {
+    if( FILE * f=fopen(file,mode) )
+        return boost::shared_ptr<FILE>(f,fclose);
+    else
+        BOOST_THROW_EXCEPTION(
+            file_open_error() <<
+            boost::errinfo_api_function("fopen") <<
+            boost::errinfo_errno(errno) <<
+            boost::errinfo_file_name(file) <<
+            boost::errinfo_file_open_mode(mode) );
+    }
+
+size_t
+read_file( boost::shared_ptr<FILE> const & f, void * buf, size_t size )
+    {
+    size_t nr=fread(buf,1,size,f.get());
+    if( ferror(f.get()) )
+        BOOST_THROW_EXCEPTION(
+            file_read_error() <<
+            boost::errinfo_api_function("fread") <<
+            boost::errinfo_errno(errno) <<
+            boost::errinfo_file_handle(f) );
+    return nr;
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/error_info_1.cpp      Sun Feb  7 21:50:27 2010
@@ -0,0 +1,35 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example shows how to add data to boost::exception objects at the
+//point of the throw, and how to retrieve that data at the point of the catch.
+
+#include <boost/exception/all.hpp>
+#include <iostream>
+
+typedef boost::error_info<struct tag_my_info,int> my_info; //(1)
+
+struct my_error: virtual boost::exception, virtual std::exception { }; //(2)
+
+void
+f()
+    {
+    throw my_error() << my_info(42); //(3)
+    }
+
+void
+g()
+    {
+    try
+        {
+        f();
+        }
+    catch(
+    my_error & x )
+        {
+        if( int const * mi=boost::get_error_info<my_info>(x) )
+            std::cerr << "My info: " << *mi;
+        }
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/error_info_2.cpp      Sun Feb  7 21:50:27 2010
@@ -0,0 +1,45 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example shows how to add arbitrary data to active exception objects.
+
+#include <boost/exception/all.hpp>
+#include <boost/shared_ptr.hpp>
+#include <stdio.h>
+#include <errno.h>
+
+//
+
+struct file_read_error: virtual boost::exception { };
+
+void
+file_read( FILE * f, void * buffer, size_t size )
+    {
+    if( size!=fread(buffer,1,size,f) )
+        throw file_read_error() << boost::errinfo_errno(errno);
+    }
+
+//
+
+boost::shared_ptr<FILE> file_open( char const * file_name, char const * mode );
+void file_read( FILE * f, void * buffer, size_t size );
+
+void
+parse_file( char const * file_name )
+    {
+    boost::shared_ptr<FILE> f = file_open(file_name,"rb");
+    assert(f);
+    try
+        {
+        char buf[1024];
+        file_read( f.get(), buf, sizeof(buf) );
+        }
+    catch(
+    boost::exception & e )
+        {
+        e << boost::errinfo_file_name(file_name);
+        throw;
+        }
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/example_io.cpp        Sun Feb  7 21:50:27 2010
@@ -0,0 +1,209 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This program simulates errors on copying simple data files. It demonstrates
+//typical Boost Exception usage.
+
+//The output from this program can vary depending on the platform.
+
+#include <boost/throw_exception.hpp>
+#include <boost/exception/info.hpp>
+#include <boost/exception/get_error_info.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/exception/errinfo_file_open_mode.hpp>
+#include <boost/exception/errinfo_file_handle.hpp>
+#include <boost/exception/errinfo_file_name.hpp>
+#include <boost/exception/errinfo_api_function.hpp>
+#include <boost/exception/errinfo_errno.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <iostream>
+
+typedef boost::error_info<struct tag_file_name_src,std::string> errinfo_src_file_name; +typedef boost::error_info<struct tag_file_name_dst,std::string> errinfo_dst_file_name;
+
+char const data[] = "example";
+size_t const data_size = sizeof(data);
+
+class
+error: //Base for all exception objects we throw.
+    public virtual std::exception,
+    public virtual boost::exception
+    {
+    public:
+
+    char const *
+    what() const throw()
+        {
+        return "example_io error";
+        }
+
+    protected:
+
+    ~error() throw()
+        {
+        }
+    };
+
+struct open_error: virtual error { };
+struct read_error: virtual error { };
+struct write_error: virtual error { };
+struct fopen_error: virtual open_error { };
+struct fread_error: virtual read_error { };
+struct fwrite_error: virtual write_error { };
+
+boost::shared_ptr<FILE>
+my_fopen( char const * name, char const * mode )
+    {
+    if( FILE * f = ::fopen(name,mode) )
+        return boost::shared_ptr<FILE>(f,fclose);
+    else
+        BOOST_THROW_EXCEPTION(fopen_error() <<
+            boost::errinfo_errno    (errno) <<
+            boost::errinfo_file_name(name) <<
+            boost::errinfo_file_open_mode(mode) <<
+            boost::errinfo_api_function("fopen"));
+    }
+
+void
+my_fread( void * buffer, size_t size, size_t count, boost::shared_ptr<FILE> const & stream )
+    {
+    assert(stream);
+ if( count!=fread(buffer,size,count,stream.get()) || ferror(stream.get()) )
+        BOOST_THROW_EXCEPTION(fread_error() <<
+            boost::errinfo_api_function("fread") <<
+            boost::errinfo_errno(errno) <<
+            boost::errinfo_file_handle(boost::weak_ptr<FILE>(stream)));
+    }
+
+void
+my_fwrite( void const * buffer, size_t size, size_t count, boost::shared_ptr<FILE> const & stream )
+    {
+    assert(stream);
+ if( count!=fwrite(buffer,size,count,stream.get()) || ferror(stream.get()) )
+        BOOST_THROW_EXCEPTION(fwrite_error() <<
+            boost::errinfo_api_function("fwrite") <<
+            boost::errinfo_errno(errno) <<
+            boost::errinfo_file_handle(boost::weak_ptr<FILE>(stream)));
+    }
+
+void
+reset_file( char const * file_name )
+    {
+    (void) my_fopen(file_name,"wb");
+    }
+
+void
+create_data( char const * file_name )
+    {
+    boost::shared_ptr<FILE> f = my_fopen(file_name,"wb");
+    my_fwrite( data, 1, data_size, f );
+    }
+
+void
+copy_data( char const * src_file_name, char const * dst_file_name )
+    {
+    boost::shared_ptr<FILE> src = my_fopen(src_file_name,"rb");
+    boost::shared_ptr<FILE> dst = my_fopen(dst_file_name,"wb");
+    try
+        {
+        char buffer[data_size];
+        my_fread( buffer, 1, data_size, src );
+        my_fwrite( buffer, 1, data_size, dst );
+        }
+    catch(
+    boost::exception & x )
+        {
+ if( boost::weak_ptr<FILE> const * f=boost::get_error_info<boost::errinfo_file_handle>(x) )
+            if( boost::shared_ptr<FILE> fs = f->lock() )
+                {
+                if( fs==src )
+                    x << boost::errinfo_file_name(src_file_name);
+                else if( fs==dst )
+                    x << boost::errinfo_file_name(dst_file_name);
+                }
+        x <<
+            errinfo_src_file_name(src_file_name) <<
+            errinfo_dst_file_name(dst_file_name);
+        throw;
+        }
+    }
+
+void
+dump_copy_info( boost::exception const & x )
+    {
+ if( std::string const * src = boost::get_error_info<errinfo_src_file_name>(x) )
+        std::cerr << "Source file name: " << *src << "\n";
+ if( std::string const * dst = boost::get_error_info<errinfo_dst_file_name>(x) )
+        std::cerr << "Destination file name: " << *dst << "\n";
+    }
+
+void
+dump_file_info( boost::exception const & x )
+    {
+ if( std::string const * fn = boost::get_error_info<boost::errinfo_file_name>(x) )
+        std::cerr << "File name: " << *fn << "\n";
+    }
+
+void
+dump_clib_info( boost::exception const & x )
+    {
+    if( int const * err=boost::get_error_info<boost::errinfo_errno>(x) )
+        std::cerr << "OS error: " << *err << "\n";
+ if( char const * const * fn=boost::get_error_info<boost::errinfo_api_function>(x) )
+        std::cerr << "Failed function: " << *fn << "\n";
+    }
+
+void
+dump_all_info( boost::exception const & x )
+    {
+    std::cerr << "-------------------------------------------------\n";
+    dump_copy_info(x);
+    dump_file_info(x);
+    dump_clib_info(x);
+    std::cerr << "\nOutput from diagnostic_information():\n";
+    std::cerr << diagnostic_information(x);
+    }
+
+int
+main()
+    {
+    try
+        {
+        create_data( "tmp1.txt" );
+        copy_data( "tmp1.txt", "tmp2.txt" ); //This should succeed.
+
+        reset_file( "tmp1.txt" ); //Creates empty file.
+        try
+            {
+ copy_data( "tmp1.txt", "tmp2.txt" ); //This should fail, tmp1.txt is empty.
+            }
+        catch(
+        read_error & x )
+            {
+            std::cerr << "\nCaught 'read_error' exception.\n";
+            dump_all_info(x);
+            }
+
+        remove( "tmp1.txt" );
+        remove( "tmp2.txt" );
+        try
+            {
+ copy_data( "tmp1.txt", "tmp2.txt" ); //This should fail, tmp1.txt does not exist.
+            }
+        catch(
+        open_error & x )
+            {
+            std::cerr << "\nCaught 'open_error' exception.\n";
+            dump_all_info(x);
+            }
+        }
+    catch(
+    ... )
+        {
+        std::cerr << "\nCaught unexpected exception!\n";
+        std::cerr << boost::current_exception_diagnostic_information();
+        }
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/info_tuple.cpp        Sun Feb  7 21:50:27 2010
@@ -0,0 +1,31 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example shows how boost::tuple can be used to bundle the
+//name of the function that fails together with the reported errno.
+
+#include <boost/exception/info_tuple.hpp>
+#include <boost/exception/errinfo_file_name.hpp>
+#include <boost/exception/errinfo_api_function.hpp>
+#include <boost/exception/errinfo_errno.hpp>
+#include <boost/shared_ptr.hpp>
+#include <stdio.h>
+#include <string>
+#include <errno.h>
+
+typedef boost::tuple<boost::errinfo_api_function,boost::errinfo_errno> clib_failure;
+
+struct file_open_error: virtual boost::exception { };
+
+boost::shared_ptr<FILE>
+file_open( char const * name, char const * mode )
+    {
+    if( FILE * f=fopen(name,mode) )
+        return boost::shared_ptr<FILE>(f,fclose);
+    else
+        throw file_open_error() <<
+            boost::errinfo_file_name(name) <<
+            clib_failure("fopen",errno);
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/example/logging.cpp   Sun Feb  7 21:50:27 2010
@@ -0,0 +1,25 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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)
+
+//This example shows how to print all data contained in a boost::exception.
+
+#include <boost/exception/all.hpp>
+#include <iostream>
+
+void f(); //throws unknown types that derive from boost::exception.
+
+void
+g()
+    {
+    try
+        {
+        f();
+        }
+    catch(
+    boost::exception & e )
+        {
+        std::cerr << diagnostic_information(e);
+        }
+    }
=======================================
--- /dev/null
+++ /trunk/libs/exception/test/1-throw_exception_test.cpp Sun Feb 7 21:50:27 2010
@@ -0,0 +1,31 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//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/throw_exception.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/config.hpp>
+
+class my_exception: public std::exception { };
+
+int
+main()
+    {
+    try
+        {
+        boost::throw_exception(my_exception());
+        BOOST_ERROR("boost::throw_exception failed to throw.");
+        }
+    catch(
+    my_exception & )
+        {
+        }
+    catch(
+    ... )
+        {
+        BOOST_ERROR("boost::throw_exception malfunction.");
+        }
+    return boost::report_errors();
+    }
=======================================
***Additional files exist in this changeset.***

Other related posts:

  • » [boost-doc-zh] r376 committed - 升级至1.41.0,第二批,libs/目录下b-e子目录 - boost-doc-zh