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.***