diff --git a/doc/acknowledgements.qbk b/doc/acknowledgements.qbk new file mode 100755 index 0000000..72b653e --- /dev/null +++ b/doc/acknowledgements.qbk @@ -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 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 library was coded using Blade, a full +open-source development environment composed, in my opinion, of the best +tools for software building. The list of names is infinitely long, so I +give a general huge thanks here. + +__BOOST_BLADE_LOGO__ + +The icons in the TOC of the main page are from [@http://www.kde-look.org/kde-look.org kde-look.org]. +I want to thank them for their effort in making the open-source world a beautiful +place. When I find time, I will look for the authors' names. Please +forgive me for omitting them for the moment. + +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] \ No newline at end of file diff --git a/doc/bimap.hdf b/doc/bimap.hdf new file mode 100755 index 0000000..2ab400b --- /dev/null +++ b/doc/bimap.hdf @@ -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 diff --git a/doc/bimap.qbk b/doc/bimap.qbk new file mode 100755 index 0000000..7091298 --- /dev/null +++ b/doc/bimap.qbk @@ -0,0 +1,166 @@ +[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 __BOOST_BLADE_LOGO__ [$images/extern/boost.blade.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: 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` +can be thought of as a combination of a `std::map` and a `std::map`. +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] diff --git a/doc/bimap_and_boost.qbk b/doc/bimap_and_boost.qbk new file mode 100755 index 0000000..747e575 --- /dev/null +++ b/doc/bimap_and_boost.qbk @@ -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/regression-logs/cs-win32_metacomm/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 `` +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().find("john"); + +instead of the more verbose + + bm_type::map_by::iterator iter = bm.by().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 + #include + +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] \ No newline at end of file diff --git a/doc/compiler_specifics.qbk b/doc/compiler_specifics.qbk new file mode 100755 index 0000000..55dfda0 --- /dev/null +++ b/doc/compiler_specifics.qbk @@ -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] \ No newline at end of file diff --git a/doc/directdoxygen.jam b/doc/directdoxygen.jam new file mode 100644 index 0000000..c674d93 --- /dev/null +++ b/doc/directdoxygen.jam @@ -0,0 +1,13 @@ +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" > "$(<)" +} diff --git a/doc/examples.qbk b/doc/examples.qbk new file mode 100755 index 0000000..5f05e2d --- /dev/null +++ b/doc/examples.qbk @@ -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` 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] \ No newline at end of file diff --git a/doc/future_work.qbk b/doc/future_work.qbk new file mode 100755 index 0000000..9118de5 --- /dev/null +++ b/doc/future_work.qbk @@ -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] \ No newline at end of file diff --git a/doc/history.qbk b/doc/history.qbk new file mode 100755 index 0000000..5f3074b --- /dev/null +++ b/doc/history.qbk @@ -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 +struct Node; +template +struct ptree_gen { + typedef std::pair > mi_value; + typedef multi_index_container > type; +}; +template +struct Node { + ValueType v; + ptree_gen::type children; +}; +// serialization support +template +void serialize(Archive & ar, Node& n, + const unsigned int version) +{ + ar & n.v; + ar & n.children; +} +// some access methods +template +ValueType const& +get( string const& keys, ptree_gen::type const& src ) +{ + std::pait 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::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 + 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] diff --git a/doc/html/boost_bimap/acknowledgements.html b/doc/html/boost_bimap/acknowledgements.html new file mode 100644 index 0000000..c74196f --- /dev/null +++ b/doc/html/boost_bimap/acknowledgements.html @@ -0,0 +1,109 @@ + + + +Acknowledgements + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHome +
+
+ +

+ 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! +

+

+ googlesoc +

+

+ 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 library was coded using Blade, a full open-source development + environment composed, in my opinion, of the best tools for software building. + The list of names is infinitely long, so I give a general huge thanks here. +

+

+ boost.blade.logo +

+

+ The icons in the TOC of the main page are from kde-look.org. + I want to thank them for their effort in making the open-source world a beautiful + place. When I find time, I will look for the authors' names. Please forgive + me for omitting them for the moment. +

+

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

+

+ + Boost.Bimap Team +

+

+ From Argentina... Matias and Mafalda and from Spain... Joaquin and Hector +

+

+ matias mafalda joaquin hector +

+

+ Luckily, the distance helps team members avoid eating each other. +

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHome +
+ + diff --git a/doc/html/boost_bimap/bimap_and_boost.html b/doc/html/boost_bimap/bimap_and_boost.html new file mode 100644 index 0000000..5ae0c43 --- /dev/null +++ b/doc/html/boost_bimap/bimap_and_boost.html @@ -0,0 +1,174 @@ + + + +Bimap and Boost + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

+ MISC - Multi-Index Specialized + Containers +

+
+

+

+

+ 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? + +

+

+

+
+

+ miBimapFramework +

+

+ 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 + [2] + . 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. +

+ + +

+ You can also read Additional + Information for more information about the relation of this two libraries. +

+
+
+

+

[2] + In the same fashion, Boost.MRU will allow the creation of most + recent updated aware containers, hiding the complexity of + Boost.MultiIndex. +

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/bimap_and_boost/boost_libraries_that_work_well_with_boost_bimap.html b/doc/html/boost_bimap/bimap_and_boost/boost_libraries_that_work_well_with_boost_bimap.html new file mode 100644 index 0000000..9065b97 --- /dev/null +++ b/doc/html/boost_bimap/bimap_and_boost/boost_libraries_that_work_well_with_boost_bimap.html @@ -0,0 +1,1065 @@ + + + +Boost + Libraries that work well with Boost.Bimap + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ 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.PropertyMap +

+
+

+ Concepts defining interfaces which map key objects to value objects +

+
+

+ Jeremy Siek +

+
+

+ Integration with BGL +

+
+
+
+ +

+ 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: +

+

+ Go to source + code +

+

+

+

+ +

+
+typedef bimap< std::string, int > bm_type;
+
+// Create a bimap and serialize it to a file
+{
+    bm_type bm;
+    bm.insert( bm_type::value_type("one",1) );
+    bm.insert( bm_type::value_type("two",2) );
+
+    std::ofstream ofs("data");
+    boost::archive::text_oarchive oa(ofs);
+
+    oa << const_cast<const bm_type&>(bm); 1
+
+    2const bm_type::left_iterator left_iter = bm.left.find("two");
+    oa << left_iter;
+
+    const bm_type::right_iterator right_iter = bm.right.find(1);
+    oa << right_iter;
+}
+
+// Load the bimap back
+{
+    bm_type bm;
+
+    std::ifstream ifs("data", std::ios::binary);
+    boost::archive::text_iarchive ia(ifs);
+
+    ia >> bm;
+
+    assert( bm.size() == 2 );
+
+    bm_type::left_iterator left_iter;
+    ia >> left_iter;
+
+    assert( left_iter->first == "two" );
+
+    bm_type::right_iterator right_iter;
+    ia >> right_iter;
+
+    assert( right_iter->first == 1 );
+}
+
+

+

+

+

+

+

+
+ + + + + + + + +
+1

+ We must do a const cast because Boost.Serialization archives only save + const objects. Read Boost.Serializartion docs for the rationale behind + this decision

+2

We can only serialize iterators if the bimap was serialized + first. Note that the const cast is not requiered here because we create + our iterators as const.

+

+

+

+

+

+ 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]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. +

+
+
+ +

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

+

+ Go to source code +

+

+

+

+ +

+
+ typedef bimap< multiset_of< int >, list_of< std::string > > bm_type;
+
+ // We can use assign::list_of to initialize the container.
+
+ bm_type bm = assign::list_of< bm_type::relation > 1
+     ( 1, "one"   )
+     ( 2, "two"   )
+     ( 3, "three" );
+
+ // The left map view is a multiset, again we use insert
+
+ assign::insert( bm.left )
+     ( 4, "four" )
+     ( 5, "five" )
+     ( 6, "six"  );
+
+ // The right map view is a list so we use push_back here
+ // Note the order of the elements in the list!
+
+ assign::push_back( bm.right )
+     ( "seven" , 7 )
+     ( "eight" , 8 );
+
+ assign::push_front( bm.right )
+     ( "nine"  ,  9 )
+     ( "ten"   , 10 )
+     ( "eleven", 11 );
+
+// Since it is left_based the main view is a multiset, so we use insert
+
+ assign::insert( bm )
+     ( 12, "twelve"   )
+     ( 13, "thirteen" );
+ 
+

+

+

+

+

+

+
+ + +
+1

+ Note that bm_type::relation has to be used instead of + bm_type::value_type. Contrary to value_type, relation + type stores the elements as non const, a requirement of assign::list_of

+

+

+

+

+
+
+ +

+ 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 extended + for custom data types, enabling to use the default parameter of + the unordered set types with any user types. +

+
+
+ +

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

+

+ Go to source code +

+

+

+

+ +

+
+typedef bimap< std::string, int > bm_type;
+
+bm_type bm;
+bm.insert( bm_type::value_type("one",1) );
+bm.insert( bm_type::value_type("two",2) );
+
+bm.right.range( 5 < _key, _key < 10 );
+
+bm.left.modify_key( bm.left.find("one"), _key = "1" );
+
+bm.left.modify_data( bm.left.begin(), _data *= 10 );
+
+

+

+

+

+

+

+
+

+

+

+

+
+
+ +

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

+

+ If we have some generic functions that accepts ranges: +

+

+

+

+ +

+
+template< class ForwardReadableRange, class UnaryFunctor >
+UnaryFunctor for_each(const ForwardReadableRange & r, UnaryFunctor func)
+{
+    typedef typename 
+    boost::range_const_iterator<ForwardReadableRange>::type const_iterator;
+
+    for(const_iterator i= boost::begin(r), iend= boost::end(r); i!=iend; ++i )
+    {
+        func(*i);
+    }
+
+    return func;
+}
+
+template< class ForwardReadableRange, class Predicate >
+typename boost::range_difference<ForwardReadableRange>::type
+    count_if(const ForwardReadableRange & r, Predicate pred)
+{
+    typedef typename
+    boost::range_const_iterator<ForwardReadableRange>::type const_iterator;
+
+    typename boost::range_difference<ForwardReadableRange>::type c = 0;
+
+    for( const_iterator i = boost::begin(r), iend = boost::end(r); i != iend; ++i )
+    {
+        if( pred(*i) ) ++c;
+    }
+
+    return c;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

+ We can use them with Boost.Bimap with the help of the range + function. +

+

+

+

+ +

+
+struct pair_printer
+{
+    pair_printer(std::ostream & o) : os(o) {}
+    template< class Pair >
+    void operator()(const Pair & p)
+    {
+        os << "(" << p.first << "," << p.second << ")";
+    }
+    private:
+    std::ostream & os;
+};
+
+struct second_extractor
+{
+    template< class Pair >
+    const typename Pair::second_type & operator()(const Pair & p)
+    {
+        return p.second;
+    }
+};
+
+int main()
+{
+    typedef bimap< double, multiset_of<int> > bm_type;
+
+    bm_type bm;
+    bm.insert( bm_type::value_type(2.5 , 1) );
+    bm.insert( bm_type::value_type(3.1 , 2) );
+    //...
+    bm.insert( bm_type::value_type(6.4 , 4) );
+    bm.insert( bm_type::value_type(1.7 , 2) );
+
+    // Print all the elements of the left map view
+
+    for_each( bm.left, pair_printer(std::cout) );
+
+    // Print a range of elements of the right map view
+
+    for_each( bm.right.range( 2 <= _key, _key < 6 ), pair_printer(std::cout) );
+
+    // Count the number of elements where the data is equal to 2 from a
+    // range of elements of the left map view
+
+    count_if( bm.left.range( 2.3 < _key, _key < 5.4 ),
+              bind<int>( second_extractor(), _1 ) == 2 );
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

+ Go to source code +

+
+
+ +

+ 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: +

+

+

+

+ +

+
+typedef bimap< std::string, list_of<int> > bm_type;
+
+bm_type bm;
+bm.insert( bm_type::value_type("1", 1) );
+bm.insert( bm_type::value_type("2", 2) );
+bm.insert( bm_type::value_type("3", 4) );
+bm.insert( bm_type::value_type("4", 2) );
+
+BOOST_FOREACH( bm_type::left_reference p, bm.left )
+{
+    ++p.second; 1
+}
+
+BOOST_FOREACH( bm_type::right_const_reference p, bm.right )
+{
+    std::cout << p.first << "-->" << p.second << std::endl;
+}
+
+
+

+

+

+

+

+

+
+ + +
+1

We can modify the right element because we have use a mutable collection + type in the right side.

+

+

+

+

+

+ You can use it directly with ranges too: +

+

+

+

+ +

+
+BOOST_FOREACH( bm_type::left_reference p,
+             ( bm.left.range( "1" <= _key, _key < "3" ) ))
+{
+    ++p.second;
+}
+
+BOOST_FOREACH( bm_type::left_const_reference p,
+             ( bm.left.range( "1" <= _key, _key < "3" ) ))
+{
+    std::cout << p.first << "-->" << p.second << std::endl;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

+ Go to source code +

+
+
+ +

+ 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 +

+

+

+

+ +

+
+typedef bimap< tagged<std::string,name>, tagged<int,number> > bm_type;
+bm_type bm;
+bm.insert( bm_type::value_type("one"  ,1) );
+bm.insert( bm_type::value_type("two"  ,2) );
+
+

+

+

+

+

+

+
+

+

+

+

+

+ The following code snippet +

+

+

+

+ +

+
+for( bm_type::map_by<name>::iterator iter = bm.by<name>().begin();
+     iter!=bm.by<name>().end(); ++iter)
+{
+    std::cout << iter->first << " --> " << iter->second << std::endl;
+}
+
+bm_type::map_by<number>::iterator iter = bm.by<number>().find(2);
+std::cout << "2: " << iter->get<name>();
+
+

+

+

+

+

+

+
+

+

+

+

+

+ can be rewrited as +

+

+

+

+ +

+
+for( BOOST_AUTO(iter, bm.by<name>().begin()); iter!=bm.by<name>().end(); ++iter)
+{
+    std::cout << iter->first << " --> " << iter->second << std::endl;
+}
+
+BOOST_AUTO( iter, bm.by<number>().find(2) );
+std::cout << "2: " << iter->get<name>();
+
+

+

+

+

+

+

+
+

+

+

+

+

+ Go to source code +

+
+
+ +

+ 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) +

+

+

+

+ +

+
+typedef bimap< std::string, int > bm_type;
+bm_type bm;
+
+std::string rel_str("one <--> 1     two <--> 2      three <--> 3");
+
+sregex rel = ( (s1= +_w) >> " <--> " >> (s2= +_d) )
+[
+    xp::ref(bm)->*insert( construct<bm_type::value_type>(s1, as<int>(s2)) )
+];
+
+sregex relations = rel >> *(+_s >> rel);
+
+regex_match(rel_str, relations);
+
+assert( bm.size() == 3 );
+
+

+

+

+

+

+

+
+

+

+

+

+

+ Go to source code +

+
+
+ +

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

+

+ Go to source + code +

+

+

+

+ +

+
+template <typename AddressMap>
+void foo(AddressMap & address_map)
+{
+    typedef typename boost::property_traits<AddressMap>::value_type value_type;
+    typedef typename boost::property_traits<AddressMap>::key_type key_type;
+
+    value_type address;
+    key_type fred = "Fred";
+    std::cout << get(address_map, fred);
+}
+
+int main()
+{
+    typedef bimap<std::string, multiset_of<std::string> > Name2Address;
+    typedef Name2Address::value_type location;
+
+    Name2Address name2address;
+    name2address.insert( location("Fred", "710 West 13th Street") );
+    name2address.insert( location( "Joe", "710 West 13th Street") );
+
+    foo( name2address.left );
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/bimap_and_boost/dependencies.html b/doc/html/boost_bimap/bimap_and_boost/dependencies.html new file mode 100644 index 0000000..0c00672 --- /dev/null +++ b/doc/html/boost_bimap/bimap_and_boost/dependencies.html @@ -0,0 +1,417 @@ + + + +Dependencies + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ 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 1.4. Boost Libraries needed by Boost.Bimap

+
+++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Name +

+
+

+ Description +

+
+

+ author +

+
+

+ Boost.MultiIndex +

+
+

+ 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.TypeTraits +

+
+

+ 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.StaticAssert +

+
+

+ Static assertions (compile time assertions). +

+
+

+ John Maddock +

+
+
+
+

Table 1.5. 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.PropertyMap +

+
+

+ Concepts defining interfaces which map key objects to value objects +

+
+

+ Jeremy Siek +

+
+

+ Integration with BGL +

+
+
+
+

Table 1.6. 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 +

+
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/compiler_specifics.html b/doc/html/boost_bimap/compiler_specifics.html new file mode 100644 index 0000000..8395e60 --- /dev/null +++ b/doc/html/boost_bimap/compiler_specifics.html @@ -0,0 +1,366 @@ + + + +Compiler specifics + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +
+++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ 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 +

+
+

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

+

+ + 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
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/examples.html b/doc/html/boost_bimap/examples.html new file mode 100644 index 0000000..61d3362 --- /dev/null +++ b/doc/html/boost_bimap/examples.html @@ -0,0 +1,439 @@ + + + +Examples + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

+ In the folder libs/bimap/example you can + find all the examples used in bimap documentation. Here is a list of them: +

+
+

Table 1.7. Tutorial examples

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Program +

+
+

+ Description +

+
+

+ simple_bimap.cpp +

+
+

+ Soccer world cup example +

+
+

+ tagged_simple_bimap.cpp + +

+
+

+ Soccer world cup example using user defined names +

+
+

+ step_by_step.cpp +

+
+

+ Basic example of the three views of bimap +

+
+

+ population_bimap.cpp + +

+
+

+ Countries populations, using unordered_set_of + and multiset_of +

+
+

+ repetitions_counter.cpp + +

+
+

+ Word repetitions counter, using unordered_set_of + and list_of +

+
+

+ mighty_bimap.cpp +

+
+

+ Dictionary using list_of_relation +

+
+

+ user_defined_names.cpp + +

+
+

+ Equivalence between code with tagged and untagged code +

+
+

+ standard_map_comparison.cpp + +

+
+

+ Comparison between standard maps and bimap map views +

+
+

+ at_function_examples.cpp + +

+
+

+ Functions at(key) + and operator[](key) + examples +

+
+

+ tutorial_modify_and_replace.cpp + +

+
+

+ modify and replace examples +

+
+

+ tutorial_range.cpp +

+
+

+ range() + tutorial +

+
+

+ tutorial_info_hook.cpp + +

+
+

+ Additional information hooking +

+
+

+ unconstrained_collection.cpp + +

+
+

+ Using unconstrained_set_of + collection type +

+
+
+
+

Table 1.8. Bimap and Boost examples

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Program +

+
+

+ Description +

+
+

+ assign.cpp +

+
+

+ Bimap and Boost.Assign: Methods to insert elements +

+
+

+ lambda.cpp +

+
+

+ Bimap and Boost.Lambda: new lambda placeholders +

+
+

+ property_map.cpp + +

+
+

+ Bimap and Boost.PropertyMap: PropertyMap support +

+
+

+ range.cpp +

+
+

+ Bimap and Boost.Range: Using bimaps in the new range framework +

+
+

+ foreach.cpp + +

+
+

+ Bimap and Boost.Foreach: Iterating over bimaps +

+
+

+ typeof.cpp +

+
+

+ Bimap and Boost.Typeof: using BOOST_AUTO while we wait for C++0x +

+
+

+ xpressive.cpp + +

+
+

+ Bimap and Boost.Xpressive: Inserting elements in a bimap +

+
+

+ serialization.cpp: + +

+
+

+ Bimap and Boost.Serialization: Load and save bimaps and iterators +

+
+
+
+

Table 1.9. Boost.MultiIndex to Boost.Bimap path examples

+
++++ + + + + + + + + + + + + + + + + + + +
+

+ Program +

+
+

+ Description +

+
+

+ bidirectional_map.cpp + +

+
+

+ Boost.MultiIndex to Boost.Bimap path example +

+
+

+ hashed_indices.cpp + +

+
+

+ Boost.MultiIndex to Boost.Bimap path example +

+
+

+ tagged_bidirectional_map.cpp + +

+
+

+ Boost.MultiIndex to Boost.Bimap path example +

+
+
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/examples/mighty_bimap.html b/doc/html/boost_bimap/examples/mighty_bimap.html new file mode 100644 index 0000000..fc7b5fb --- /dev/null +++ b/doc/html/boost_bimap/examples/mighty_bimap.html @@ -0,0 +1,148 @@ + + + +Mighty Bimap + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

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

+

+ Go to source code +

+

+

+

+ +

+
+#include <iostream>
+#include <string>
+#include <boost/bimap/bimap.hpp>
+#include <boost/bimap/list_of.hpp>
+#include <boost/bimap/unordered_set_of.hpp>
+
+struct english {};
+struct spanish {};
+
+int main()
+{
+    using namespace boost::bimaps;
+
+    typedef bimap
+    <
+        unordered_set_of< tagged< std::string, spanish > >,
+        unordered_set_of< tagged< std::string, english > >,
+        list_of_relation
+
+    > translator;
+
+    translator trans;
+
+    // We have to use `push_back` because the collection of relations is
+    // a `list_of_relation`
+
+    trans.push_back( translator::value_type("hola"  ,"hello"   ) );
+    trans.push_back( translator::value_type("adios" ,"goodbye" ) );
+    trans.push_back( translator::value_type("rosa"  ,"rose"    ) );
+    trans.push_back( translator::value_type("mesa"  ,"table"   ) );
+
+    std::cout << "enter a word" << std::endl;
+    std::string word;
+    std::getline(std::cin,word);
+
+    // Search the queried word on the from index (Spanish)
+
+    translator::map_by<spanish>::const_iterator is
+        = trans.by<spanish>().find(word);
+
+    if( is != trans.by<spanish>().end() )
+    {
+        std::cout << word << " is said "
+                  << is->get<english>()
+                  << " in English" << std::endl;
+    }
+    else
+    {
+        // Word not found in Spanish, try our luck in English
+
+        translator::map_by<english>::const_iterator ie
+            = trans.by<english>().find(word);
+
+        if( ie != trans.by<english>().end() )
+        {
+            std::cout << word << " is said "
+                      << ie->get<spanish>()
+                      << " in Spanish" << std::endl;
+        }
+        else
+        {
+            // Word not found, show the possible translations
+
+            std::cout << "No such word in the dictionary"      << std::endl;
+            std::cout << "These are the possible translations" << std::endl;
+
+            for( translator::const_iterator
+                    i = trans.begin(),
+                    i_end = trans.end();
+
+                    i != i_end ; ++i )
+            {
+                std::cout << i->get<spanish>()
+                          << " <---> "
+                          << i->get<english>()
+                          << std::endl;
+            }
+        }
+    }
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/examples/multiindex_to_bimap_path___bidirectional_map.html b/doc/html/boost_bimap/examples/multiindex_to_bimap_path___bidirectional_map.html new file mode 100644 index 0000000..8274f8c --- /dev/null +++ b/doc/html/boost_bimap/examples/multiindex_to_bimap_path___bidirectional_map.html @@ -0,0 +1,363 @@ + + + +MultiIndex + to Bimap Path - Bidirectional Map + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ This is example 4 in Boost.MultiIndex documentation. +

+ +
+ + Boost.MultiIndex +
+

+ Go to source + code +

+

+

+

+ +

+
+#include <iostream>
+#include <boost/tokenizer.hpp>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+
+using namespace boost;
+using namespace boost::multi_index;
+
+// tags for accessing both sides of a bidirectional map
+
+struct from {};
+struct to   {};
+
+// The class template bidirectional_map wraps the specification
+// of a bidirectional map based on multi_index_container.
+
+template<typename FromType,typename ToType>
+struct bidirectional_map
+{
+    typedef std::pair<FromType,ToType> value_type;
+
+    typedef multi_index_container<
+        value_type,
+        indexed_by
+        <
+            ordered_unique
+            <
+                tag<from>, member<value_type,FromType,&value_type::first>
+            >,
+            ordered_unique
+            <
+                tag<to>, member<value_type,ToType,&value_type::second>
+            >
+        >
+
+  > type;
+
+};
+
+// A dictionary is a bidirectional map from strings to strings
+
+typedef bidirectional_map<std::string,std::string>::type dictionary;
+
+int main()
+{
+    dictionary d;
+
+    // Fill up our microdictionary.
+    // first members Spanish, second members English.
+
+    d.insert(dictionary::value_type("hola","hello"));
+    d.insert(dictionary::value_type("adios","goodbye"));
+    d.insert(dictionary::value_type("rosa","rose"));
+    d.insert(dictionary::value_type("mesa","table"));
+
+    std::cout << "enter a word" << std::endl;
+    std::string word;
+    std::getline(std::cin,word);
+
+    // search the queried word on the from index (Spanish)
+
+    dictionary::iterator it = d.get<from>().find(word);
+
+    if( it != d.end() )
+    {
+        // the second part of the element is the equivalent in English
+
+        std::cout << word << " is said "
+                  << it->second << " in English" << std::endl;
+    }
+    else
+    {
+        // word not found in Spanish, try our luck in English
+
+        dictionary::index_iterator<to>::type it2 = d.get<to>().find(word);
+        if( it2 != d.get<to>().end() )
+        {
+            std::cout << word << " is said "
+                      << it2->first << " in Spanish" << std::endl;
+        }
+        else
+        {
+            std::cout << "No such word in the dictionary" << std::endl;
+        }
+    }
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+ + Boost.Bimap +
+

+ Go to source + code +

+

+

+

+ +

+
+#include <iostream>
+#include <boost/tokenizer.hpp>
+#include <boost/bimap/bimap.hpp>
+
+using namespace boost::bimaps;
+
+// A dictionary is a bidirectional map from strings to strings
+
+typedef bimap<std::string,std::string> dictionary;
+typedef dictionary::value_type translation;
+
+int main()
+{
+    dictionary d;
+
+    // Fill up our microdictionary.
+    // first members Spanish, second members English.
+
+    d.insert( translation("hola" ,"hello"  ));
+    d.insert( translation("adios","goodbye"));
+    d.insert( translation("rosa" ,"rose"   ));
+    d.insert( translation("mesa" ,"table"  ));
+
+    std::cout << "enter a word" << std::endl;
+    std::string word;
+    std::getline(std::cin,word);
+
+    // search the queried word on the from index (Spanish)
+
+    dictionary::left_const_iterator it = d.left.find(word);
+
+    if( it != d.left.end() )
+    {
+        // the second part of the element is the equivalent in English
+
+        std::cout << word << " is said "
+                  << it->second 1
+                  << " in English" << std::endl;
+    }
+    else
+    {
+        // word not found in Spanish, try our luck in English
+
+        dictionary::right_const_iterator it2 = d.right.find(word);
+        if( it2 != d.right.end() )
+        {
+            std::cout << word << " is said "
+                      << it2->second 2
+                      << " in Spanish" << std::endl;
+        }
+        else
+        {
+            std::cout << "No such word in the dictionary" << std::endl;
+        }
+    }
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+ + + + + + + + +
+1

it is an iterator of the + left view, so it->second refers to the right element of + the relation, the word in english

+2

it2 + is an iterator of the right view, so it2->second + refers to the left element of the relation, the word in spanish

+

+

+

+

+

+ Or better, using tags... +

+

+ Go to + source code +

+

+

+

+ +

+
+#include <iostream>
+
+#include <boost/bimap/bimap.hpp>
+
+using namespace boost::bimaps;
+
+// tags
+
+struct spanish {};
+struct english {};
+
+// A dictionary is a bidirectional map from strings to strings
+
+typedef bimap
+<
+    tagged< std::string,spanish >, tagged< std::string,english >
+
+> dictionary;
+
+typedef dictionary::value_type translation;
+
+int main()
+{
+    dictionary d;
+
+    // Fill up our microdictionary. 
+    // first members Spanish, second members English.
+
+    d.insert( translation("hola" ,"hello"  ));
+    d.insert( translation("adios","goodbye"));
+    d.insert( translation("rosa" ,"rose"   ));
+    d.insert( translation("mesa" ,"table"  ));
+
+    std::cout << "enter a word" << std::endl;
+    std::string word;
+    std::getline(std::cin,word);
+
+    // search the queried word on the from index (Spanish) */
+
+    dictionary::map_by<spanish>::const_iterator it =
+        d.by<spanish>().find(word);
+
+    if( it != d.by<spanish>().end() )
+    {
+        std::cout << word << " is said " 
+                  << it->get<english>() << " in English" << std::endl;
+    }
+    else
+    {
+        // word not found in Spanish, try our luck in English
+
+        dictionary::map_by<english>::const_iterator it2 =
+            d.by<english>().find(word);
+
+        if( it2 != d.by<english>().end() )
+        {
+            std::cout << word << " is said "
+                      << it2->get<spanish>() << " in Spanish" << std::endl;
+        }
+        else
+        {
+            std::cout << "No such word in the dictionary" << std::endl;
+        }
+    }
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/examples/multiindex_to_bimap_path___hashed_indices.html b/doc/html/boost_bimap/examples/multiindex_to_bimap_path___hashed_indices.html new file mode 100644 index 0000000..1bbbe68 --- /dev/null +++ b/doc/html/boost_bimap/examples/multiindex_to_bimap_path___hashed_indices.html @@ -0,0 +1,260 @@ + + + +MultiIndex + to Bimap Path - Hashed indices + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ This is example 8 of Boost.MultiIndex. +

+ +
+ + Boost.MultiIndex +
+

+ Go to source + code +

+

+

+

+ +

+
+#include <iostream>
+#include <iomanip>
+
+#include <boost/tokenizer.hpp>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/lambda/lambda.hpp>
+
+using namespace boost::multi_index;
+namespace bl = boost::lambda;
+
+// word_counter keeps the ocurrences of words inserted. A hashed
+// index allows for fast checking of preexisting entries.
+
+struct word_counter_entry
+{
+    std::string  word;
+    unsigned int occurrences;
+
+    word_counter_entry( std::string word_ ) : word(word_), occurrences(0) {}
+};
+
+typedef multi_index_container
+<
+    word_counter_entry,
+    indexed_by
+    <
+        ordered_non_unique
+        <
+            BOOST_MULTI_INDEX_MEMBER(
+                word_counter_entry,unsigned int,occurrences),
+            std::greater<unsigned int>
+        >,
+        hashed_unique
+        <
+            BOOST_MULTI_INDEX_MEMBER(word_counter_entry,std::string,word)
+        >
+  >
+
+> word_counter;
+
+typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
+
+int main()
+{
+    std::string text=
+        "En un lugar de la Mancha, de cuyo nombre no quiero acordarme... "
+        "...snip..."
+        "...no se salga un punto de la verdad.";
+
+    // feed the text into the container
+
+    word_counter   wc;
+    text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
+    unsigned int   total_occurrences = 0;
+
+    for( text_tokenizer::iterator it = tok.begin(), it_end = tok.end();
+         it != it_end ; ++it )
+    {
+        ++total_occurrences;
+        word_counter::iterator wit = wc.insert(*it).first;
+        wc.modify_key( wit, ++ bl::_1 );
+    }
+
+    // list words by frequency of appearance
+
+    std::cout << std::fixed << std::setprecision(2);
+
+    for( word_counter::iterator wit = wc.begin(), wit_end=wc.end();
+         wit != wit_end; ++wit )
+    {
+        std::cout << std::setw(11) << wit->word << ": "
+                  << std::setw(5)
+                  << 100.0 * wit->occurrences / total_occurrences << "%"
+                  << std::endl;
+    }
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+ + Boost.Bimap +
+

+ Go to source code +

+

+

+

+ +

+
+#include <iostream>
+#include <iomanip>
+
+#include <boost/tokenizer.hpp>
+
+#include <boost/bimap/bimap.hpp>
+#include <boost/bimap/unordered_set_of.hpp>
+#include <boost/bimap/multiset_of.hpp>
+#include <boost/bimap/support/lambda.hpp>
+
+using namespace boost::bimaps;
+
+struct word        {};
+struct occurrences {};
+
+typedef bimap
+<
+    
+     multiset_of< tagged<unsigned int,occurrences>, std::greater<unsigned int> >, 
+unordered_set_of< tagged< std::string,       word>                             >
+
+> word_counter;
+
+typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
+
+int main()
+{
+
+    std::string text=
+        "Relations between data in the STL are represented with maps."
+        "A map is a directed relation, by using it you are representing "
+        "a mapping. In this directed relation, the first type is related to "
+        "the second type but it is not true that the inverse relationship "
+        "holds. This is useful in a lot of situations, but there are some "
+        "relationships that are bidirectional by nature.";
+
+    // feed the text into the container
+
+    word_counter   wc;
+    text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
+    unsigned int   total_occurrences = 0;
+
+    for( text_tokenizer::const_iterator it = tok.begin(), it_end = tok.end();
+         it != it_end ; ++it )
+    {
+        ++total_occurrences;
+
+        word_counter::map_by<occurrences>::iterator wit =
+            wc.by<occurrences>().insert(
+                 word_counter::map_by<occurrences>::value_type(0,*it)
+            ).first;
+
+        wc.by<occurrences>().modify_key( wit, ++_key);
+    }
+
+    // list words by frequency of appearance
+
+    std::cout << std::fixed << std::setprecision(2);
+
+    for( word_counter::map_by<occurrences>::const_iterator
+            wit     = wc.by<occurrences>().begin(),
+            wit_end = wc.by<occurrences>().end();
+
+         wit != wit_end; ++wit )
+    {
+        std::cout << std::setw(15) << wit->get<word>() << ": "
+                  << std::setw(5)
+                  << 100.0 * wit->get<occurrences>() / total_occurrences << "%"
+                  << std::endl;
+    }
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/examples/simple_bimap.html b/doc/html/boost_bimap/examples/simple_bimap.html new file mode 100644 index 0000000..98bcafa --- /dev/null +++ b/doc/html/boost_bimap/examples/simple_bimap.html @@ -0,0 +1,223 @@ + + + +Simple Bimap + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ This is the example from the one minute tutorial section. +

+

+ Go to source code +

+

+

+

+ +

+
+#include <string>
+#include <iostream>
+
+#include <boost/bimap.hpp>
+
+template< class MapType >
+void print_map(const MapType & map,
+               const std::string & separator,
+               std::ostream & os )
+{
+    typedef typename MapType::const_iterator const_iterator;
+
+    for( const_iterator i = map.begin(), iend = map.end(); i != iend; ++i )
+    {
+        os << i->first << separator << i->second << std::endl;
+    }
+}
+
+int main()
+{
+    // Soccer World cup
+
+    typedef boost::bimap< std::string, int > results_bimap;
+    typedef results_bimap::value_type position;
+
+    results_bimap results;
+    results.insert( position("Argentina"    ,1) );
+    results.insert( position("Spain"        ,2) );
+    results.insert( position("Germany"      ,3) );
+    results.insert( position("France"       ,4) );
+
+    std::cout << "The number of countries is " << results.size()
+              << std::endl;
+
+    std::cout << "The winner is " << results.right.at(1)
+              << std::endl
+              << std::endl;
+
+    std::cout << "Countries names ordered by their final position:"
+              << std::endl;
+
+    // results.right works like a std::map< int, std::string >
+
+    print_map( results.right, ") ", std::cout );
+
+    std::cout << std::endl
+              << "Countries names ordered alphabetically along with"
+                    "their final position:"
+              << std::endl;
+
+    // results.left works like a std::map< std::string, int >
+
+    print_map( results.left, " ends in position ", std::cout );
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

+ You can rewrite it using tags to gain readability. +

+

+ Go to source code +

+

+

+

+ +

+
+#include <iostream>
+
+#include <boost/bimap.hpp>
+
+struct country  {};
+struct place    {};
+
+int main()
+{
+    using namespace boost::bimaps;
+
+    // Soccer World cup.
+
+    typedef bimap
+    <
+        tagged< std::string, country >,
+        tagged< int        , place   >
+
+    > results_bimap;
+
+    typedef results_bimap::value_type position;
+
+    results_bimap results;
+    results.insert( position("Argentina"    ,1) );
+    results.insert( position("Spain"        ,2) );
+    results.insert( position("Germany"      ,3) );
+    results.insert( position("France"       ,4) );
+
+    std::cout << "Countries names ordered by their final position:"
+                << std::endl;
+
+    1for( results_bimap::map_by<place>::const_iterator
+            i    = results.by<place>().begin(),
+            iend = results.by<place>().end() ;
+            i != iend; ++i )
+    {
+        2std::cout << i->get<place  >() << ") "
+                  << i->get<country>() << std::endl;
+    }
+
+    std::cout << std::endl
+              << "Countries names ordered alfabetically along with"
+                 "their final position:"
+              << std::endl;
+
+    3for( results_bimap::map_by<country>::const_iterator
+            i    = results.by<country>().begin(),
+            iend = results.by<country>().end() ;
+            i != iend; ++i )
+    {
+        std::cout << i->get<country>() << " ends "
+                  << i->get<place  >() << "º"
+                  << std::endl;
+    }
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+ + + + + + + + + + + + +
+1

results.by<place>() + is equivalent to results.right +

+2

get<Tag> + works for each view of the bimap

+3

results.by<country>() + is equivalent to results.left +

+

+

+

+

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/future_work.html b/doc/html/boost_bimap/future_work.html new file mode 100644 index 0000000..4075174 --- /dev/null +++ b/doc/html/boost_bimap/future_work.html @@ -0,0 +1,49 @@ + + + +Future work + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ + Rearrange Function +

+

+ Boost.MultiIndex includes some others functions that can be included in the + views. +

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/history.html b/doc/html/boost_bimap/history.html new file mode 100644 index 0000000..e3a8d15 --- /dev/null +++ b/doc/html/boost_bimap/history.html @@ -0,0 +1,111 @@ + + + +History + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+

+
+
2002 - bimap at Code Project
+
+ Joaquin Lopez Muñoz posted his first bimap + library in 2002. Tons of users have been using it. He then 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. +
+
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/history/multiindex_and_bimap.html b/doc/html/boost_bimap/history/multiindex_and_bimap.html new file mode 100644 index 0000000..e77dde0 --- /dev/null +++ b/doc/html/boost_bimap/history/multiindex_and_bimap.html @@ -0,0 +1,711 @@ + + + +MultiIndex + and Bimap + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ 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: +

+

+

+
+ +

+ 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 +

+

+

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/introduction.html b/doc/html/boost_bimap/introduction.html new file mode 100644 index 0000000..4f76abb --- /dev/null +++ b/doc/html/boost_bimap/introduction.html @@ -0,0 +1,201 @@ + + + +Introduction + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ + 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: +

+
+

+
+
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 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 The + tutorial and skim through some of the 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]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]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 track bugs and + features + requests, and using it is the best way of dealing with them as + soon as possible. +

+

+

+
+

+ + 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 +
    • +
    +
  • +
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/one_minute_tutorial.html b/doc/html/boost_bimap/one_minute_tutorial.html new file mode 100644 index 0000000..5a4f964 --- /dev/null +++ b/doc/html/boost_bimap/one_minute_tutorial.html @@ -0,0 +1,497 @@ + + + +One minute tutorial + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ + 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. + [1] +

+
    +
  • +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 +

+
1 --> one
+2 --> two
+...
+one --> 1
+two --> 2
+...
+
+

+ + 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 +

+

+ + Step by step +

+

+ A convinience header is avaiable in the boost directory: +

+
+#include <boost/bimap.hpp>
+
+

+ Lets define a bidirectional map between integers and strings: +

+

+

+

+ +

+
+typedef boost::bimap< int, std::string > bm_type;
+bm_type bm;
+
+

+

+

+

+

+

+
+

+

+

+

+

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

+

+

+

+ +

+
+bm.insert( bm_type::value_type(1, "one" ) );
+bm.insert( bm_type::value_type(2, "two" ) );
+
+std::cout << "There are " << bm.size() << "relations" << std::endl;
+
+for( bm_type::const_iterator iter = bm.begin(), iend = bm.end(); 
+    iter != iend; ++iter )
+{
+    // iter->left  : data : int
+    // iter->right : data : std::string
+
+    std::cout << iter->left << " <--> " << iter->right << std::endl;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

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

+

+

+

+ +

+
+1typedef bm_type::left_map::const_iterator left_const_iterator;
+
+for( left_const_iterator left_iter = bm.left.begin(), iend = bm.left.end();
+     left_iter != iend; ++left_iter )
+{
+    // left_iter->first  : key  : int
+    // left_iter->second : data : std::string
+
+    std::cout << left_iter->first << " --> " << left_iter->second << std::endl;
+}
+
+2bm_type::left_const_iterator left_iter = bm.left.find(2);
+assert( left_iter->second ==  "two" );
+
+3bm.left.insert( bm_type::left_value_type( 3, "three" ) );
+
+

+

+

+

+

+

+
+ + + + + + + + + + + + +
+1

The type of bm.left is bm_type::left_map + and the type of bm.right is bm_type::right_map +

+2

bm_type::left_-type- can be used as a shortcut for + the more verbose bm_type::left_map::-type-

+3

This line produces the same effect + of bm.insert( bm_type::value_type(3,"three") );

+

+

+

+

+

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

+

+

+

+ +

+
+bm_type::right_const_iterator right_iter = bm.right.find("two");
+
+// right_iter->first  : key  : std::string
+// right_iter->second : data : int
+
+assert( right_iter->second ==  2 );
+
+assert( bm.right.at("one") == 1 );
+
+bm.right.erase("two");
+
+1bm.right.insert( bm_type::right_value_type( "four", 4 ) );
+
+

+

+

+

+

+

+
+ + +
+1

This line produces the same effect of bm.insert( bm_type::value_type(4,"four") + );

+

+

+

+

+

+ + 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 );
+
+

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

+

+ Go to source code +

+

+

+

+ +

+
+#include <string>
+#include <iostream>
+
+#include <boost/bimap.hpp>
+
+template< class MapType >
+void print_map(const MapType & map,
+               const std::string & separator,
+               std::ostream & os )
+{
+    typedef typename MapType::const_iterator const_iterator;
+
+    for( const_iterator i = map.begin(), iend = map.end(); i != iend; ++i )
+    {
+        os << i->first << separator << i->second << std::endl;
+    }
+}
+
+int main()
+{
+    // Soccer World cup
+
+    typedef boost::bimap< std::string, int > results_bimap;
+    typedef results_bimap::value_type position;
+
+    results_bimap results;
+    results.insert( position("Argentina"    ,1) );
+    results.insert( position("Spain"        ,2) );
+    results.insert( position("Germany"      ,3) );
+    results.insert( position("France"       ,4) );
+
+    std::cout << "The number of countries is " << results.size()
+              << std::endl;
+
+    std::cout << "The winner is " << results.right.at(1)
+              << std::endl
+              << std::endl;
+
+    std::cout << "Countries names ordered by their final position:"
+              << std::endl;
+
+    // results.right works like a std::map< int, std::string >
+
+    print_map( results.right, ") ", std::cout );
+
+    std::cout << std::endl
+              << "Countries names ordered alphabetically along with"
+                    "their final position:"
+              << std::endl;
+
+    // results.left works like a std::map< std::string, int >
+
+    print_map( results.left, " ends in position ", std::cout );
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

+ The output of this program will be the following: +

+
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
+
+

+ + Continuing + the journey +

+

+ For information on function signatures, see any standard library documentation + or read the reference section + of this documentation. +

+
+ + + + + +
[Caution]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 The full tutorial + if you intend to use a bimap in a serious project. +

+

+

+
+
+

+

[1] + 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. +

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/performance.html b/doc/html/boost_bimap/performance.html new file mode 100644 index 0000000..04c5e2b --- /dev/null +++ b/doc/html/boost_bimap/performance.html @@ -0,0 +1,44 @@ + + + +Performance + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ Section under construction. +

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/rationale.html b/doc/html/boost_bimap/rationale.html new file mode 100644 index 0000000..a7b7f15 --- /dev/null +++ b/doc/html/boost_bimap/rationale.html @@ -0,0 +1,312 @@ + + + +Rationale + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +

+ 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]Note
+

+

+

+ To browse the code, you can use the Bimap + Complete Reference, a doxygen-powered document targeted + at developers. +

+

+

+
+
+ +

+ 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: +

+
    +
  1. +bm.left is signature-compatible with a + std::map<A,B> +
  2. +
  3. +bm.right is signature-compatible with a + std::map<B,A> +
  4. +
  5. +bm is signature-compatible + with a std::set<relation<A,B> > +
  6. +
+

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

+
+ + 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]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. +

+

+

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

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/rationale/additional_features.html b/doc/html/boost_bimap/rationale/additional_features.html new file mode 100644 index 0000000..7c09b39 --- /dev/null +++ b/doc/html/boost_bimap/rationale/additional_features.html @@ -0,0 +1,139 @@ + + + +Additional + Features + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +
+ + 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 +

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

+
+ + 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 +

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/rationale/code.html b/doc/html/boost_bimap/rationale/code.html new file mode 100644 index 0000000..9a795c8 --- /dev/null +++ b/doc/html/boost_bimap/rationale/code.html @@ -0,0 +1,200 @@ + + + +Code + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+

+Code +

+

+ You can browse the code using the Boost.Bimap doxygen docs. +

+

+ The code follows the Boost + Library Requirement and Guidelines as closely as possible. +

+
+

Table 1.10. 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 1.11. 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 +

+
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/rationale/the_student_and_the_mentor.html b/doc/html/boost_bimap/rationale/the_student_and_the_mentor.html new file mode 100644 index 0000000..ebd0aab --- /dev/null +++ b/doc/html/boost_bimap/rationale/the_student_and_the_mentor.html @@ -0,0 +1,1396 @@ + + + +The + student and the mentor + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +
+ + + + + +
[Tip]Tip
+

+

+

+ It is a good idea to read the original Boost.Misc + SoC proposal first. +

+

+

+
+
+

+

+

+ - The discussion starts with Joaquin trying to strip out the + "misc" name out of the library - +

+

+

+
+

+ joaquin +

+

+ 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 +

+

+ 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/docsisocpp). + 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;? +

+

+

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/reference.html b/doc/html/boost_bimap/reference.html new file mode 100644 index 0000000..9626a31 --- /dev/null +++ b/doc/html/boost_bimap/reference.html @@ -0,0 +1,179 @@ + + + +Reference + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

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

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/reference/bimap_reference.html b/doc/html/boost_bimap/reference/bimap_reference.html new file mode 100644 index 0000000..72a2382 --- /dev/null +++ b/doc/html/boost_bimap/reference/bimap_reference.html @@ -0,0 +1,990 @@ + + + +Bimap Reference + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

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

+
+

+

+
+ +

+ 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) ]
  • +
+
+
+ +

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

+
+++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ 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 +

+
+
+
+

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

+
+
+ +
+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
+
+
+
+ + +

+ This is the main component of Boost.Bimap. +

+
+ +

+ In the descriptions of the operations of bimap, + we adopt the scheme outlined in the complexity signature section. +

+
+
+ +

+ bimap is instantiated + with the following types: +

+
    +
  1. + LeftCollectionType and RightCollectionType are collection type specifications + optionally tagged, or any type optionally tagged, in which case that + side acts as a set. +
  2. +
  3. + AdditionalParameter_{1/2} can be any ordered subset of: +
      +
    • + CollectionTypeOfRelation specification +
    • +
    • + Allocator +
    • +
    +
  4. +
+
+
+ +
+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. +

+

+

+
+
+
+ +
+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. +
  • +
  • +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. +
  • +
+
+

+

+
+ +

+ 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. +
  • +
+
+

+

+
+ +
+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. +
  • +
+
+
+ +

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

+ +
    +
  • +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. +
  • +
+ +
    +
  • +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. +
  • +
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/reference/list_of_reference.html b/doc/html/boost_bimap/reference/list_of_reference.html new file mode 100644 index 0000000..7cf7458 --- /dev/null +++ b/doc/html/boost_bimap/reference/list_of_reference.html @@ -0,0 +1,1337 @@ + + + +list_of Reference + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+namespace boost {
+namespace bimaps {
+
+
+template< class KeyType >
+struct list_of;
+
+struct list_of_relation;
+
+
+} // namespace bimap
+} // namespace boost
+
+
+
+ + +

+ 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 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 Reversible Container, + Front + Insertion Sequence and 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 assign(InputIterator first, InputIterator last);
+
+    void 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 resize(size_type n, const value_type & x = value_type());
+
+    // access
+
+    const_reference front() const;
+    const_reference back() const;
+
+    // modifiers
+
+    std::pair<iterator,bool> push_front(const value_type & x);
+    void                     pop_front();
+
+    std::pair<iterator,bool> push_back(const value_type & x);
+    void                     pop_back();
+
+    std::pair<iterator,bool> insert(iterator position, const value_type & x);
+
+    void insert(iterator position, size_type n, const value_type & x);
+
+    template< class InputIterator >
+    void insert(iterator position, InputIterator first, InputIterator last);
+
+    iterator erase(iterator position);
+    iterator erase(iterator first, iterator last);
+
+    bool replace(iterator position, const value_type & x);
+
+    // Only in map views
+    // {
+
+      template< class CompatibleKey >
+      bool replace_key(iterator position, const CompatibleKey & x);
+
+      template< class CompatibleData >
+      bool replace_data(iterator position, const CompatibleData & x);
+
+      template< class KeyModifier >
+      bool modify_key(iterator position, KeyModifier mod);
+
+      template< class DataModifier >
+      bool modify_data(iterator position, DataModifier mod);
+
+    // }
+
+
+    void clear();
+
+    // list operations
+
+    void splice(iterator position, this_type & x);
+    void splice(iterator position, this_type & x, iterator i);
+    void splice(
+        iterator position, this_type & x, iterator first, iterator last);
+
+    void remove(const value_type & value);
+
+    template< class Predicate >
+    void remove_if(Predicate pred);
+
+    void unique();
+
+    template< class BinaryPredicate >
+    void unique(BinaryPredicate binary_pred);
+
+    void merge(this_type & x);
+
+    template< class Compare >
+    void merge(this_type & x,Compare comp);
+
+    void sort();
+
+    template< class Compare >
+    void sort(Compare comp);
+
+    void 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;
+
+

+

+
+ +

+ Here and in the descriptions of operations of list_of + views, we adopt the scheme outlined in the 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). +
  • +
+
+
+ +

+ 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, +
  • +
+
+
+ +

+ 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. +
  • +
+

+

+
+template< class InputIterator >
+void assign(InputIterator first, InputIterator last);
+
+
    +
  • +Requires: InputIterator + is a model of 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); +
  • +
+

+

+
+void assign(size_type n, const value_type & value);
+
+
  • +Effects: clear(); for(size_type + i = + 0; + i < + n ; + ++n) push_back(v); +
+
+
+ +

+

+
+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.) +
  • +
+
+
+ +

+

+
+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. +
  • +
  • +Complexity: + O(I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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); +
  • +
+

+

+
+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 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++); +
  • +
  • +Complexity: + O(m*I(n+m)), where m is the number of elements in [first,last). +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(D(n)). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(m*D(n)), where m is the number of elements in [first,last). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+template< class KeyModifier >
+bool modify_key(iterator position, KeyModifier mod);
+
+
    +
  • +Requires: KeyModifier + is a model of 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. +
  • +
  • +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. +
  • +
+

+

+
+template< class DataModifier >
+bool modify_data(iterator position, DataModifier mod);
+
+
    +
  • +Requires: DataModifier + is a model of 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. +
  • +
  • +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. +
  • +
+
+
+ +

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

+

+

+
+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. +
  • +
  • +Complexity: + O(x.size()*I(n+x.size()) + + x.size()*D(x.size())). +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + If &x==this, + constant; otherwise O(I(n) + D(n)). +
  • +
  • +Exception safety: If &x==this, + nothrow; otherwise, strong. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+void remove(const value_type & value);
+
+
    +
  • +Effects: Erases all elements of the + view which compare equal to value. +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+template< class Predicate >
+void remove_if(Predicate pred);
+
+
    +
  • +Effects: Erases all elements x of the view for which pred(x) + holds. +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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). +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+void merge(this_type & x);
+
+
    +
  • +Requires: std::less<value_type> is a 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. +
  • +
  • +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. +
  • +
+

+

+
+template< class Compare >
+void merge(this_type & x, Compare comp);
+
+
    +
  • +Requires: Compare is a 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. +
  • +
  • +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. +
  • +
+

+

+
+void sort();
+
+
    +
  • +Requires: std::less<value_type> is a 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. +
  • +
+

+

+
+template< typename Compare >
+void sort(Compare comp);
+
+
    +
  • +Requires: Compare is a 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. +
  • +
+

+

+
+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. +
  • +
+
+
+ +

+ These operations, without counterpart in std::list + (although splice provides partially overlapping functionality), perform + individual and global repositioning of elements inside the index. +

+

+

+
+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. +
  • +
+

+

+
+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. +
  • +
+
+
+ +

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

+ +
  • +Requires: No additional requirements + to those imposed by the container. +
+ +
  • +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. +
+ +
  • +Requires: it + is a valid iterator of the view. The associated bimap + has been previously saved. +
+ +
    +
  • +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. +
  • +
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/reference/set_of_reference.html b/doc/html/boost_bimap/reference/set_of_reference.html new file mode 100644 index 0000000..fa411e7 --- /dev/null +++ b/doc/html/boost_bimap/reference/set_of_reference.html @@ -0,0 +1,1333 @@ + + + +set_of Reference + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+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
+
+
+
+ +
+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
+
+
+
+ +

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

+
+
+ + +

+ 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> insert(const value_type & x);
+
+    iterator insert(iterator position, const value_type & x);
+
+    template< class InputIterator>
+    void insert(InputIterator first,  InputIterator last);
+
+    iterator erase(iterator position);
+
+    template< class CompatibleKey >
+    size_type erase(const CompatibleKey & x);
+
+    iterator erase(iterator first,  iterator last);
+
+    bool replace(iterator position, const value_type& x);
+
+    // Only in map views
+    // {
+
+      template< class CompatibleKey >
+      bool replace_key(iterator position, const CompatibleKey & x);
+
+      template< class CompatibleData >
+      bool replace_data(iterator position, const CompatibleData & x);
+
+      template< class KeyModifier >
+      bool modify_key(iterator position, KeyModifier mod);
+
+      template< class DataModifier >
+      bool 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 find(const CompatibleKey & x);
+
+    template< class CompatibleKey >
+    const_iterator find(const CompatibleKey & x) const;
+
+
+    template< class CompatibleKey >
+    size_type count(const CompatibleKey & x) const;
+
+
+    template< class CompatibleKey >
+    iterator lower_bound(const CompatibleKey & x);
+
+    template< class CompatibleKey >
+    const_iterator lower_bound(const CompatibleKey & x) const;
+
+
+    template< class CompatibleKey >
+    iterator upper_bound(const CompatibleKey & x);
+
+    template< class CompatibleKey >
+    const_iterator upper_bound(const CompatibleKey & x) const;
+
+
+    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;
+
+    // Only in maps views
+    // {
+
+    template< class LowerBounder, class UpperBounder>
+    std::pair<iterator,iterator> range(
+        LowerBounder lower, UpperBounder upper);
+
+    template< class LowerBounder, class UpperBounder>
+    std::pair<const_iterator,const_iterator> range(
+        LowerBounder lower, UpperBounder upper) const;
+
+    typedef -unspecified- data_type;
+
+      // Only in for `set_of` collection type
+      // {
+
+      template< class CompatibleKey >
+      const data_type & at(const CompatibleKey & k) const;
+
+        // Only if the other collection type is mutable
+        // {
+
+        template< class CompatibleKey >
+        data_type & operator[](const CompatibleKey & k);
+
+        template< class CompatibleKey >
+        data_type & at(const CompatibleKey & k);
+
+        // }
+
+        // Only if info_hook is used
+        // {
+
+        template< class CompatibleKey >
+        info_type & info_at(const CompatibleKey & k);
+
+        template< class CompatibleKey >
+        const info_type & 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
+
+

+ 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;
+
+

+

+
+ +

+ Here and in the descriptions of operations of this view, we adopt the + scheme outlined in the 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. +
  • +
+
+
+ +

+ 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 Strict + Weak Ordering on elements of Value. +

+
+
+ +

+ 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. +
  • +
+
+
+ +

+

+
+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. +
  • +
  • +Complexity: + O(I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(H(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+template< class InputIterator >
+void insert(InputIterator first, InputIterator last);
+
+
    +
  • +Requires: InputIterator + is a model of 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++ ); +
  • +
  • +Complexity: + O(m*H(n+m)), where m is the number of elements in [first, + last). +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(D(n)). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(log(n) + m*D(n)), where m is the number of elements deleted. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(log(n) + m*D(n)), where m is the number of elements in [first,last). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+template< class KeyModifier >
+bool modify_key(iterator position, KeyModifier mod);
+
+
    +
  • +Requires: KeyModifier + is a model of 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. +
  • +
  • +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. +
  • +
+

+

+
+template< class DataModifier >
+bool modify_data(iterator position, DataModifier mod);
+
+
    +
  • +Requires: DataModifier + is a model of 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. +
  • +
  • +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. +
  • +
+
+
+ +

+ [multi]set_of + views provide the full lookup functionality required by Sorted + Associative Container and 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. +

+

+ 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(). +

+

+

+
+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 >
+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 >
+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)). +
  • +
+

+

+
+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)). +
  • +
+

+

+
+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)). +
  • +
+
+
+ +

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

+

+

+
+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. +
  • +
+
+
+ +

+

+
+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). +

+

+

+
+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. +
  • +
+

+

+
+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. +
  • +
+

+

+
+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 +
  • +
+
+
+ +

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

+ +
  • +Requires: No additional requirements + to those imposed by the container. +
+ +
    +
  • +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()). +
  • +
+ +
  • +Requires: it + is a valid iterator of the view. The associated bimap + has been previously saved. +
+ +
    +
  • +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. +
  • +
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/reference/unconstrained_set_of_reference.html b/doc/html/boost_bimap/reference/unconstrained_set_of_reference.html new file mode 100644 index 0000000..18a8e76 --- /dev/null +++ b/doc/html/boost_bimap/reference/unconstrained_set_of_reference.html @@ -0,0 +1,201 @@ + + + +unconstrained_set_of + Reference + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+namespace boost {
+namespace bimaps {
+
+
+template< class KeyType >
+struct unconstrained_set_of;
+
+struct unconstrained_set_of_relation;
+
+
+} // namespace bimap
+} // namespace boost
+
+
+
+ + +

+ 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;
+
+

+

+
+ +

+ We adopt the scheme outlined in the 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 +
  • +
+
+
+ +

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

+ +
  • +Requires: No additional requirements + to those imposed by the container. +
+ +
  • +Requires: No additional requirements + to those imposed by the container. +
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/reference/unordered_set_of_reference.html b/doc/html/boost_bimap/reference/unordered_set_of_reference.html new file mode 100644 index 0000000..e99e639 --- /dev/null +++ b/doc/html/boost_bimap/reference/unordered_set_of_reference.html @@ -0,0 +1,1303 @@ + + + +unordered_set_of + Reference + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+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
+
+
+
+ +
+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
+
+
+
+ +

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

+
+
+ + +

+ 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 C++ + 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 > insert(const value_type & x);
+
+    iterator insert(iterator position, const value_type & x);
+
+    template< class InputIterator >
+    void insert(InputIterator first, InputIterator last);
+
+    iterator erase(iterator position);
+
+    template< class CompatibleKey >
+    size_type erase(const CompatibleKey & x);
+
+    iterator erase(iterator first, iterator last);
+
+    bool replace(iterator position, const value_type & x);
+
+    // Only in map views
+    // {
+
+      template< class CompatibleKey >
+      bool replace_key(iterator position, const CompatibleKey & x);
+
+      template< class CompatibleData >
+      bool replace_data(iterator position, const CompatibleData & x);
+
+      template< class KeyModifier >
+      bool modify_key(iterator position, KeyModifier mod);
+
+      template< class DataModifier >
+      bool 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 find(const CompatibleKey & x);
+
+    template< class CompatibleKey >
+    const_iterator find(const CompatibleKey & x) const;
+
+    template< class CompatibleKey >
+    size_type count(const CompatibleKey & x) const;
+
+    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;
+
+    // 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  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 & at(const CompatibleKey & k) const;
+
+        // Only if the other collection type is mutable
+        // {
+
+        template<class CompatibleKey>
+        data_type & operator[](const CompatibleKey & k);
+
+        template<class CompatibleKey>
+        data_type & at(const CompatibleKey & k);
+
+        // }
+
+        // Only if info_hook is used
+        // {
+
+        template< class CompatibleKey >
+        info_type & info_at(const CompatibleKey & k);
+
+        template< class CompatibleKey >
+        const info_type & 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;
+
+

+

+
+ +

+ Here and in the descriptions of operations of unordered_[multi]set_of + views, we adopt the scheme outlined in the 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. +
  • +
+
+
+ +

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

+
+
+ +
+iterator
+const_iterator
+local_iterator
+const_local_iterator
+
+
+

+

+

+ These types are models of Forward + Iterator. +

+

+

+
+
+
+ +

+ 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. +
  • +
+
+
+ +

+

+
+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. +
  • +
  • +Complexity: + O(I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(H(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+template< class InputIterator>
+void insert(InputIterator first, InputIterator last);
+
+
    +
  • +Requires: InputIterator + is a model of 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++); +
  • +
  • +Complexity: + O(m*H(n+m)), where m is the number of elements in [first, + last). +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(D(n)). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+template< class CompatibleKey >
+size_type erase(const CompatibleKey & x);
+
+
    +
  • +Effects: Deletes the elements with + key equivalent to x. +
  • +
  • +Returns: Number of elements deleted. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(m*D(n)), where m is the number of elements in [first,last). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+template< class KeyModifier >
+bool modify_key(iterator position, KeyModifier mod);
+
+
    +
  • +Requires: KeyModifier + is a model of 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. +
  • +
  • +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. +
  • +
+

+

+
+template< class DataModifier >
+bool modify_data(iterator position, DataModifier mod);
+
+
    +
  • +Requires: DataModifier + is a model of 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. +
  • +
  • +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. +
  • +
+
+
+
+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. +

+

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

+

+

+
+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). +
  • +
+

+

+
+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). +
  • +
+

+

+
+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). +
  • +
+
+
+ +

+

+
+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). +

+

+

+
+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. +
  • +
+

+

+
+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. +
  • +
+

+

+
+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 +
  • +
+
+
+ +

+

+
+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. +
  • +
+
+
+ +

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

+ +
  • +Requires: No additional requirements + to those imposed by the container. +
+ +
    +
  • +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. +
  • +
+ +
  • +Requires: it + is a valid iterator + of the view. The associated bimap + has been previously saved. +
+ +
    +
  • +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. +
  • +
+ +
  • +Requires: it + is a valid local iterator of the view. The associated bimap has been previously saved. +
+ +
    +
  • +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. +
  • +
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/reference/vector_of_reference.html b/doc/html/boost_bimap/reference/vector_of_reference.html new file mode 100644 index 0000000..bc43ffc --- /dev/null +++ b/doc/html/boost_bimap/reference/vector_of_reference.html @@ -0,0 +1,1408 @@ + + + +vector_of + Reference + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+namespace boost {
+namespace bimaps {
+
+
+template< class KeyType >
+struct vector_of;
+
+struct vector_of_relation;
+
+
+} // namespace bimap
+} // namespace boost
+
+
+
+ + +

+ 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 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 + Random + Access Container and Back + Insertion Sequence. Although these views do not model 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 assign(InputIterator first, InputIterator last);
+
+    void 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 capacity() const;
+
+    void reserve(size_type m);
+
+    void 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> push_front(const value_type & x);
+    void                     pop_front();
+
+    std::pair<iterator,bool> push_back(const value_type & x);
+    void                     pop_back();
+
+    std::pair<iterator,bool> insert(iterator position, const value_type & x);
+
+    void insert(iterator position, size_type m, const value_type & x);
+
+    template< class InputIterator>
+    void insert(iterator position, InputIterator first, InputIterator last);
+
+    iterator erase(iterator position);
+    iterator erase(iterator first, iterator last);
+
+    bool replace(iterator position, const value_type & x);
+
+    // Only in map views
+    // {
+
+      template< class CompatibleKey >
+      bool replace_key(iterator position, const CompatibleKey & x);
+
+      template< class CompatibleData >
+      bool replace_data(iterator position, const CompatibleData & x);
+
+      template< class KeyModifier >
+      bool modify_key(iterator position, KeyModifier mod);
+
+      template< class DataModifier >
+      bool modify_data(iterator position, DataModifier mod);
+
+    // }
+
+
+    void clear();
+
+    // list operations
+
+    void splice(iterator position, this_type & x);
+    void splice(iterator position, this_type & x, iterator i);
+    void splice(
+        iterator position, this_type & x, iterator first, iterator last);
+
+    void remove(const value_type & value);
+
+    template< class Predicate >
+    void remove_if(Predicate pred);
+
+    void unique();
+
+    template< class BinaryPredicate >
+    void unique(BinaryPredicate binary_pred);
+
+    void merge(this_type & x);
+
+    template< typename Compare >
+    void merge(this_type & x, Compare comp);
+
+    void sort();
+
+    template< typename Compare >
+    void sort(Compare comp);
+
+    void 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< 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;
+
+

+

+
+ +

+ Here and in the descriptions of operations of vector_of + views, we adopt the scheme outlined in the 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: +

+ +

+ (shl and rel stand for shift left + and relocate, respectively.) +

+
+
+ +

+ 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, +
  • +
+
+
+ +

+ 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. +
  • +
+

+

+
+template< class InputIterator >
+void assign(InputIterator first, InputIterator last);
+
+
    +
  • +Requires: InputIterator + is a model of 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); +
  • +
+

+

+
+void assign(size_type n, const value_type & value);
+
+
  • +Effects: clear(); for(size_type + i = + 0; + i < + n; + ++n) push_back(v); +
+
+
+ +

+

+
+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. +
  • +
+

+

+
+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. +
  • +
+

+

+
+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.) +
  • +
+
+
+ +

+

+
+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. +
  • +
  • +Complexity: + O(n+I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(shl(end()-position,1) + I(n)). +
  • +
  • +Exception safety: Strong. +
  • +
+

+

+
+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); +
  • +
  • +Complexity: + O(shl(end()-position,m) + m*I(n+m)). +
  • +
+

+

+
+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 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++); +
  • +
  • +Complexity: + O(shl(end()-position,m) + m*I(n+m)), where m is the number of elements + in [first,last). +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(D(n)). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(m*D(n)), where m is the number of elements in [first,last). +
  • +
  • +Exception safety: nothrow. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+template< class KeyModifier >
+bool modify_key(iterator position, KeyModifier mod);
+
+
    +
  • +Requires: KeyModifier + is a model of 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. +
  • +
  • +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. +
  • +
+

+

+
+template< class DataModifier >
+bool modify_data(iterator position, DataModifier mod);
+
+
    +
  • +Requires: DataModifier + is a model of 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. +
  • +
  • +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. +
  • +
+
+
+ +

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

+

+

+
+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. +
  • +
  • +Complexity: + O(shl(end()-position,x.size()) + x.size()*I(n+x.size()) + x.size()*D(x.size())). +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+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. +
  • +
  • +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. +
  • +
+

+

+
+void remove(const value_type & value);
+
+
    +
  • +Effects: Erases all elements of the + view which compare equal to value. +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+template< class Predicate >
+void remove_if(Predicate pred);
+
+
    +
  • +Effects: Erases all elements x of the view for which pred(x) + holds. +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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). +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+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. +
  • +
  • +Complexity: + O(n + m*D(n)), where m is the number of elements erased. +
  • +
  • +Exception safety: Basic. +
  • +
+

+

+
+void merge(this_type & x);
+
+
    +
  • +Requires: std::less<value_type> is a 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. +
  • +
  • +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. +
  • +
+

+

+
+template< class Compare >
+void merge(this_type & x, Compare comp);
+
+
    +
  • +Requires: Compare + is a 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. +
  • +
  • +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. +
  • +
+

+

+
+void sort();
+
+
    +
  • +Requires: std::less<value_type> is a 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. +
  • +
+

+

+
+template< class Compare >
+void sort(Compare comp);
+
+
    +
  • +Requires: Compare is a 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. +
  • +
+

+

+
+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. +
  • +
+
+
+ +

+ These operations, without counterpart in std::list + (although splice provides partially overlapping functionality), perform + individual and global repositioning of elements inside the index. +

+

+

+
+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. +
  • +
+

+

+
+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. +
  • +
+
+
+ +

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

+ +
  • +Requires: No additional requirements + to those imposed by the container. +
+ +
    +
  • +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. +
  • +
+ +
  • +Requires: it + is a valid iterator of the view. The associated bimap + has been previously saved. +
+ +
    +
  • +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. +
  • +
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/release_notes.html b/doc/html/boost_bimap/release_notes.html new file mode 100644 index 0000000..77eec38 --- /dev/null +++ b/doc/html/boost_bimap/release_notes.html @@ -0,0 +1,44 @@ + + + +Release notes + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ Not yet released. +

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/test_suite.html b/doc/html/boost_bimap/test_suite.html new file mode 100644 index 0000000..a7238c6 --- /dev/null +++ b/doc/html/boost_bimap/test_suite.html @@ -0,0 +1,457 @@ + + + +Test suite + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

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

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Program +

+
+

+ Description +

+
+

+ test_tagged.cpp +

+
+

+ Tagged idiom checks +

+
+

+ test_mutant.cpp +

+
+

+ Test the mutant idiom +

+
+

+ test_structured_pair.cpp + +

+
+

+ Test structured pair class +

+
+

+ test_mutant_relation.cpp + +

+
+

+ Test the relation class +

+
+

+ test_bimap_set_of.cpp + +

+
+

+ Library interface check +

+
+

+ test_bimap_multiset_of.cpp + +

+
+

+ Library interface check +

+
+

+ test_bimap_unordered_set_of.cpp + +

+
+

+ Library interface check +

+
+

+ test_bimap_unordered_multiset_of.cpp + +

+
+

+ Library interface check +

+
+

+ test_bimap_list_of.cpp + +

+
+

+ Library interface check +

+
+

+ test_bimap_vector_of.cpp + +

+
+

+ Library interface check +

+
+

+ test_bimap_convenience_header.cpp + +

+
+

+ Library interface check +

+
+

+ test_bimap_ordered.cpp + +

+
+

+ Test set and multiset based bimaps +

+
+

+ test_bimap_unordered.cpp + +

+
+

+ Test unordered_set and unordered_multiset based bimaps +

+
+

+ test_bimap_sequenced.cpp + +

+
+

+ Test list and vector based bimaps +

+
+

+ test_bimap_unconstrained.cpp + +

+
+

+ Test bimaps with unconstrained views +

+
+

+ test_bimap_serialization.cpp + +

+
+

+ Serialization support checks +

+
+

+ test_bimap_property_map.cpp + +

+
+

+ Property map concepts for the set and unordered set views +

+
+

+ test_bimap_modify.cpp + +

+
+

+ replace, modify and operator[] +

+
+

+ test_bimap_lambda.cpp + +

+
+

+ Test lambda modified idom support +

+
+

+ test_bimap_assign.cpp + +

+
+

+ Test Boost.Assign support +

+
+

+ test_bimap_project.cpp + +

+
+

+ Projection of iterators support +

+
+

+ test_bimap_operator_bracket.cpp + +

+
+

+ operator[] + and at() + functions +

+
+

+ test_bimap_info.cpp +

+
+

+ Information hooking support +

+
+

+ test_bimap_extra.cpp + +

+
+

+ Additional checks +

+
+

+ test_bimap_info_1.cpp + +

+
+

+ Information hooking compilation fail test +

+
+

+ test_bimap_info_2.cpp + +

+
+

+ Information hooking compilation fail test +

+
+

+ test_bimap_info_3.cpp + +

+
+

+ Information hooking compilation fail test +

+
+

+ test_bimap_mutable_1.cpp + +

+
+

+ Mutable members compilation fail test +

+
+

+ test_bimap_mutable_2.cpp + +

+
+

+ Mutable members compilation fail test +

+
+

+ test_bimap_mutable_3.cpp + +

+
+

+ Mutable members compilation fail test +

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial.html b/doc/html/boost_bimap/the_tutorial.html new file mode 100644 index 0000000..2c5ff76 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial.html @@ -0,0 +1,167 @@ + + + +The tutorial + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
    +
  1. + 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 (Discovering + the bimap framework) aims to explain this. +
  2. +
  3. + 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 (Controlling + collection types) explains how to instantiate a bimap with different + collection constraints. +
  4. +
  5. + The section (The + "collection of relations" type) explains how to create + new types of bidirectional maps using custom collection types. +
  6. +
  7. + In the section Differences + with standard maps we will learn about the subtle differences between + a bimap map view and a standard map. +
  8. +
  9. + The section Useful + functions provides information about functions of a bimap that are + not found in the STL. +
  10. +
  11. + 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 (Bimaps + with user defined names) shows how to use this feature. +
  12. +
  13. + The bimap mapping framework allows to disable a view of a bimap, including + the standard mapping containers as a particular case. The section Unconstrained Sets + explains how they work. +
  14. +
  15. + The section Additional + information explains how to attach information to each relation + of a bimap. +
  16. +
  17. + The final section (Complete + Instantiation Scheme) summarizes bimap instantiation and explains + how change the allocator type to be used. +
  18. +
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/bimaps_with_user_defined_names.html b/doc/html/boost_bimap/the_tutorial/bimaps_with_user_defined_names.html new file mode 100644 index 0000000..8147ffa --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/bimaps_with_user_defined_names.html @@ -0,0 +1,408 @@ + + + +Bimaps + with user defined names + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ In the following example, the library user inserted comments to guide future + programmers: +

+

+ Go to source code +

+

+

+

+ +

+
+typedef bimap
+<
+    multiset_of<std::string>,
+    int
+
+> People;
+
+People people;
+
+// ...
+
+int user_id;
+std::cin >> user_id;
+
+// people.right : map<id,name>
+
+People::right_const_iterator id_iter = people.right.find(user_id);
+if( id_iter != people.right.end() )
+{
+    // first  : id
+    // second : name
+
+    std::cout << "name: " << id_iter->second << std::endl
+              << "id:   " << id_iter->first  << std::endl;
+}
+else
+{
+    std::cout << "Unknown id, users are:" << std::endl;
+
+    // people.left : map<name,id>
+
+    for( People::left_const_iterator
+            name_iter = people.left.begin(),
+            iend      = people.left.end();
+
+         name_iter != iend; ++name_iter )
+    {
+        // first  : name
+        // second : id
+
+        std::cout << "name: " << name_iter->first  << std::endl
+                  << "id:   " << name_iter->second << std::endl;
+    }
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

+ 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: +

+

+ Go to source code +

+

+

+

+ +

+
+struct id   {}; // Tag for the identification number
+struct name {}; // Tag for the name of the person
+
+typedef bimap
+<
+	 tagged< int        , id   >  ,
+    multiset_of< tagged< std::string, name > >
+
+> People;
+
+People people;
+
+// ...
+
+int user_id;
+std::cin >> user_id;
+
+People::map_by<id>::const_iterator id_iter = people.by<id>().find(user_id);
+if( id_iter != people.by<id>().end() )
+{
+    std::cout << "name: " << id_iter->get<name>() << std::endl
+              << "id:   " << id_iter->get<id>()   << std::endl;
+}
+else
+{
+    std::cout << "Unknown id, users are:" << std::endl;
+
+    for( People::map_by<name>::const_iterator
+            name_iter = people.by<name>().begin(),
+            iend      = people.by<name>().end();
+
+        name_iter != iend; ++name_iter )
+    {
+        std::cout << "name: " << name_iter->get<name>() << std::endl
+                  << "id:   " << name_iter->get<id>()   << std::endl;
+    }
+}
+
+

+

+

+

+

+

+
+

+

+

+

+

+ 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 1.3. 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) +

+
+
+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/complete_instantiation_scheme.html b/doc/html/boost_bimap/the_tutorial/complete_instantiation_scheme.html new file mode 100644 index 0000000..87bf1d5 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/complete_instantiation_scheme.html @@ -0,0 +1,253 @@ + + + +Complete + instantiation scheme + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ 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 >
+
+
    +
  • + set_of_relation_type: based on the left key type +
  • +
  • + info: no info +
  • +
  • + allocator: std::allocator +
  • +
+
+bimap< L, R ,SetOfRelationType>
+
+
    +
  • + set_of_relation_type: SetOfRelationType +
  • +
  • + info: no info +
  • +
  • + allocator: std::allocator +
  • +
+
+bimap< L, R , SetOfRelationType, with_info<Info> >
+
+
    +
  • + set_of_relation_type: SetOfRelationType +
  • +
  • + info: Info +
  • +
  • + allocator: std::allocator +
  • +
+
+bimap< L, R , SetOfRelationType, with_info<Info>, Allocator>
+
+
    +
  • + set_of_relation_type: SetOfRelationType +
  • +
  • + info: Info +
  • +
  • + allocator: Allocator +
  • +
+
+bimap< L, R , SetOfRelationType, Allocator>
+
+
    +
  • + set_of_relation_type: SetOfRelationType +
  • +
  • + info: no info +
  • +
  • + allocator: Allocator +
  • +
+
+bimap< L, R , with_info<Info> >
+
+
    +
  • + set_of_relation_type: based on the left key type +
  • +
  • + info: Info +
  • +
  • + allocator: std::allocator +
  • +
+
+bimap< L, R , with_info<Info>, Allocator>
+
+
    +
  • + set_of_relation_type: based on the left key type +
  • +
  • + allocator: Allocator +
  • +
+
+bimap< L, R , Allocator>
+
+
    +
  • + set_of_relation_type: based on the left key type +
  • +
  • + info: no info +
  • +
  • + allocator: Allocator +
  • +
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/controlling_collection_types.html b/doc/html/boost_bimap/the_tutorial/controlling_collection_types.html new file mode 100644 index 0000000..f178e49 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/controlling_collection_types.html @@ -0,0 +1,565 @@ + + + +Controlling + collection types + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

+ 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 1.2. 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> +
  • +
+
+
+ +

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

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

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

+
+
+
+ +
+ + Countries + Populations +
+

+ We want to store countries populations. The requeriments are: +

+
    +
  1. + Get a list of countries in decresing order of their populations. +
  2. +
  3. + Given a countrie, get their population. +
  4. +
+

+ 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 multiset_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 +

+

+ Go to source code +

+

+

+

+ +

+
+typedef bimap<
+
+    unordered_set_of< std::string >,
+    multiset_of< long, std::greater<long> >
+
+> population_bimap;
+
+typedef population_bimap::value_type population;
+
+population_bimap pop;
+pop.insert( population("China",          1321000000) );
+pop.insert( population("India",          1129000000) );
+pop.insert( population("United States",   301950000) );
+pop.insert( population("Indonesia",       234950000) );
+pop.insert( population("Brazil",          186500000) );
+pop.insert( population("Pakistan",        163630000) );
+
+std::cout << "Countries by their population:" << std::endl;
+
+// First requirement
+1for( population_bimap::right_const_iterator
+        i = pop.right.begin(), iend = pop.right.end();
+        i != iend ; ++i )
+{
+    std::cout << i->second << " with " << i->first << std::endl;
+}
+
+// Second requirement
+2std::cout << "Population of China: " << pop.left.at("China") << std::endl;
+
+

+

+

+

+

+

+
+ + + + + + + + +
+1

The right map view works like a std::multimap< long, std::string, std::greater<long> >, + We can iterate over it to print the results in the required order.

+2

The + left map view works like a std::unordered_map< std::string, long >, given the name of the country we + can use it to search for the population in constant time

+

+

+

+

+
+ + Repetitions + counter +
+

+ We want to count the repetitions for each word in a text and print them + in order of appearance. +

+

+ Go to source code +

+

+

+

+ +

+
+typedef bimap
+<
+    unordered_set_of< std::string >,
+    list_of< counter > 1
+
+> word_counter;
+
+typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
+
+std::string text=
+    "Relations between data in the STL are represented with maps."
+    "A map is a directed relation, by using it you are representing "
+    "a mapping. In this directed relation, the first type is related to "
+    "the second type but it is not true that the inverse relationship "
+    "holds. This is useful in a lot of situations, but there are some "
+    "relationships that are bidirectional by nature.";
+
+// feed the text into the container
+word_counter   wc;
+text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
+
+for( text_tokenizer::const_iterator it = tok.begin(), it_end = tok.end();
+     it != it_end ; ++it )
+{
+    2++ wc.left[*it];
+}
+
+// list words with counters by order of appearance
+3for( word_counter::right_const_iterator
+        wit = wc.right.begin(), wit_end = wc.right.end();
+
+     wit != wit_end; ++wit )
+{
+    std::cout << wit->second << ": " << wit->first;
+}
+
+

+

+

+

+

+

+
+ + + + + + + + + + + + +
+1

counter is an integer + that is initialized in zero in the constructor

+2

Because the right collection + type is list_of, the + right data is not used a key and can be modified in the same way as with + standard maps.

+3

When we insert the elements using the left map view, the + element is inserted at the end of the list.

+

+

+

+

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/differences_with_standard_maps.html b/doc/html/boost_bimap/the_tutorial/differences_with_standard_maps.html new file mode 100644 index 0000000..d24aa84 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/differences_with_standard_maps.html @@ -0,0 +1,481 @@ + + + +Differences + with standard maps + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

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

+
+
+ +

+ 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: +

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

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

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ 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> +

+
+
+
+ +

+ 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) +

+

+ Go to source code +

+

+

+

+ +

+
+typedef bimap< set_of< std::string >, list_of< int > > bm_type;
+bm_type bm;
+
+try
+{
+    bm.left.at("one") = 1; // throws std::out_of_range
+}
+catch( std::out_of_range & e ) {}
+
+assert( bm.empty() );
+
+bm.left["one"] = 1; // Ok
+
+assert( bm.left.at("one") == 1 ); // Ok
+
+

+

+

+

+

+

+
+

+

+

+

+

+

+

+ +

+
+typedef bimap< multiset_of<std::string>, unordered_set_of<int> > bm_type;
+bm_type bm;
+
+bm.right[1] = "one"; // compilation error
+
+bm.right.insert( bm_type::right_value_type(1,"one") );
+
+assert( bm.right.at(1) == "one" ); // Ok
+
+try
+{
+    std::cout << bm.right.at(2); // throws std::out_of_range
+}
+catch( std::out_of_range & e ) {}
+
+bm.right.at(1) = "1"; // compilation error
+
+
+

+

+

+

+

+

+
+

+

+

+

+
+
+ +

+ The complexity of some operations is different in bimaps. Read the + reference to find the complexity of each function. +

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/discovering_the_bimap_framework.html b/doc/html/boost_bimap/the_tutorial/discovering_the_bimap_framework.html new file mode 100644 index 0000000..16362b0 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/discovering_the_bimap_framework.html @@ -0,0 +1,343 @@ + + + +Discovering + the bimap framework + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

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

+
+
+ +

+ 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 1.1. 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 +

+
+
+
+
+
+ +

+ 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]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. +

+

+

+
+

+ Go to source code +

+

+

+

+ +

+
+template< class Map, class CompatibleKey, class CompatibleData >
+void use_it( Map & m,
+             const CompatibleKey  & key,
+             const CompatibleData & data )
+{
+    typedef typename Map::value_type value_type;
+    typedef typename Map::const_iterator const_iterator;
+
+    m.insert( value_type(key,data) );
+    const_iterator iter = m.find(key);
+    if( iter != m.end() )
+    {
+        assert( iter->first  == key  );
+        assert( iter->second == data );
+
+        std::cout << iter->first << " --> " << iter->second;
+    }
+    m.erase(key);
+}
+
+int main()
+{
+    typedef bimap< set_of<std::string>, set_of<int> > bimap_type;
+    bimap_type bm;
+
+    // Standard map
+    {
+        typedef std::map< std::string, int > map_type;
+        map_type m;
+
+        use_it( m, "one", 1 );
+    }
+
+    // Left map view
+    {
+        typedef bimap_type::left_map map_type;
+        map_type & m = bm.left;
+
+        use_it( m, "one", 1 );
+    }
+
+    // Reverse standard map
+    {
+        typedef std::map< int, std::string > reverse_map_type;
+        reverse_map_type rm;
+
+        use_it( rm, 1, "one" );
+    }
+
+    // Right map view
+    {
+        typedef bimap_type::right_map reverse_map_type;
+        reverse_map_type & rm = bm.right;
+
+        use_it( rm, 1, "one" );
+    }
+
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/hooking_information.html b/doc/html/boost_bimap/the_tutorial/hooking_information.html new file mode 100644 index 0000000..41df430 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/hooking_information.html @@ -0,0 +1,221 @@ + + + +Hooking + Information + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ Bidirectional maps may have associated information about each relation. Suppose + we want to represent a books and author bidirectional map. +

+

+

+

+ +

+
+typedef bimap<
+
+    multiset_of< std::string >, // author
+         set_of< std::string >  // book name
+
+> bm_type;
+typedef bm_type::value_type book;
+
+bm_type bm;
+
+bm.insert( book( "Bjarne Stroustrup"   , "The C++ Programming Language" ) );
+bm.insert( book( "Scott Meyers"        , "Effective C++"                ) );
+bm.insert( book( "Andrei Alexandrescu" , "Modern C++ Design"            ) );
+
+// Print the author of Modern C++
+std::cout << bm.right.at( "Modern C++ Design" );
+
+

+

+

+

+

+

+
+

+

+

+

+

+ Suppose now that we want to store abstract of each book. We have two options: +

+
    +
  1. + Books name are unique identifiers, so we can create a separate std::map< string, string > + that relates books names with abstracts. +
  2. +
  3. + We can use Boost.MultiIndex for the new beast. +
  4. +
+

+ 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 information + hooking. You can pass an extra parameter to a bimap with the type info_hook< + InfoType > + and an info member of type + InfoType will appear in the + relation and bimap pairs. +

+

+ Relations and bimap pairs constructors can take an extra argument. If only + two arguments are used, the information will be initialized with their default + constructor. +

+

+

+

+ +

+
+typedef bimap<
+
+    multiset_of< std::string >, // author
+         set_of< std::string >, // book name
+
+      with_info< std::string >  // abstract
+
+> bm_type;
+typedef bm_type::value_type book;
+
+bm_type bm;
+
+bm.insert(
+
+    book( "Bjarne Stroustrup"   , "The C++ Programming Language",
+
+          "For C++ old-timers, the first edition of this book is"
+          "the one that started it all—the font of our knowledge." )
+);
+
+
+// Print the abstract of the bible
+std::cout << bm.right.at("The C++ Programming Language");
+
+// Print the abstract of this book
+bm_type::left_iterator i = bm.left.find("Bjarne Stroustrup");
+std::cout << i->info;
+
+

+

+

+

+

+

+
+

+

+

+

+

+ Contrary to the two key types, the information will be mutable using iterators. +

+

+

+

+ +

+
+i->info += "More details about this book";
+
+

+

+

+

+

+

+
+

+

+

+

+

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

+

+

+

+ +

+
+// Print the new abstract
+std::cout << bm.right.info_at("The C++ Programming Language");
+
+

+

+

+

+

+

+
+

+

+

+

+

+ Go to source code +

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/the_collection_of_relations_type.html b/doc/html/boost_bimap/the_tutorial/the_collection_of_relations_type.html new file mode 100644 index 0000000..01a7363 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/the_collection_of_relations_type.html @@ -0,0 +1,432 @@ + + + +The + collection of relations type + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

+ 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]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. +

+

+ Go to source code +

+

+

+

+ +

+
+#include <iostream>
+#include <string>
+#include <boost/bimap/bimap.hpp>
+#include <boost/bimap/list_of.hpp>
+#include <boost/bimap/unordered_set_of.hpp>
+
+struct english {};
+struct spanish {};
+
+int main()
+{
+    using namespace boost::bimaps;
+
+    typedef bimap
+    <
+        unordered_set_of< tagged< std::string, spanish > >,
+        unordered_set_of< tagged< std::string, english > >,
+        list_of_relation
+
+    > translator;
+
+    translator trans;
+
+    // We have to use `push_back` because the collection of relations is
+    // a `list_of_relation`
+
+    trans.push_back( translator::value_type("hola"  ,"hello"   ) );
+    trans.push_back( translator::value_type("adios" ,"goodbye" ) );
+    trans.push_back( translator::value_type("rosa"  ,"rose"    ) );
+    trans.push_back( translator::value_type("mesa"  ,"table"   ) );
+
+    std::cout << "enter a word" << std::endl;
+    std::string word;
+    std::getline(std::cin,word);
+
+    // Search the queried word on the from index (Spanish)
+
+    translator::map_by<spanish>::const_iterator is
+        = trans.by<spanish>().find(word);
+
+    if( is != trans.by<spanish>().end() )
+    {
+        std::cout << word << " is said "
+                  << is->get<english>()
+                  << " in English" << std::endl;
+    }
+    else
+    {
+        // Word not found in Spanish, try our luck in English
+
+        translator::map_by<english>::const_iterator ie
+            = trans.by<english>().find(word);
+
+        if( ie != trans.by<english>().end() )
+        {
+            std::cout << word << " is said "
+                      << ie->get<spanish>()
+                      << " in Spanish" << std::endl;
+        }
+        else
+        {
+            // Word not found, show the possible translations
+
+            std::cout << "No such word in the dictionary"      << std::endl;
+            std::cout << "These are the possible translations" << std::endl;
+
+            for( translator::const_iterator
+                    i = trans.begin(),
+                    i_end = trans.end();
+
+                    i != i_end ; ++i )
+            {
+                std::cout << i->get<spanish>()
+                          << " <---> "
+                          << i->get<english>()
+                          << std::endl;
+            }
+        }
+    }
+    return 0;
+}
+
+

+

+

+

+

+

+
+

+

+

+

+
+
+ +

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

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

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

+
+
+
+ +

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

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/unconstrained_sets.html b/doc/html/boost_bimap/the_tutorial/unconstrained_sets.html new file mode 100644 index 0000000..12244b2 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/unconstrained_sets.html @@ -0,0 +1,195 @@ + + + +Unconstrained + Sets + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ 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. +
  • +
+

+ Given this bimap instance, +

+

+

+

+ +

+
+typedef bimap< std::string, unconstrained_set_of<int> > bm_type;
+typedef bm_type::left_map map_type;
+
+bm_type bm;
+map_type & m = bm.left;
+
+

+

+

+

+

+

+
+

+

+

+

+

+ or this standard map one +

+

+

+

+ +

+
+typedef std::map< std::string, int > map_type;
+
+map_type m;
+
+

+

+

+

+

+

+
+

+

+

+

+

+ The following code snippet is valid +

+

+

+

+ +

+
+m["one"] = 1;
+
+assert( m.find("one") != m.end() );
+
+for( map_type::iterator i = m.begin(), iend = m.end(); i != iend; ++i )
+{
+    1++(i->second);
+}
+
+m.erase("one");
+
+

+

+

+

+

+

+
+ + +
+1

The right collection of the bimap is mutable so its elements can be modified + using iterators.

+

+

+

+

+

+ But using a bimap has some benefits +

+

+

+

+ +

+
+typedef map_type::const_iterator const_iterator;
+typedef std::pair<const_iterator,const_iterator> const_range;
+
+1const_range r = m.range( "one" <= _key, _key <= "two" );
+for( const_iterator i = r.first; i != r.second; ++i )
+{
+    std::cout << i->first << "-->" << i->second << std::endl;
+}
+
+m.modify_key( m.begin(), _key = "1" );
+
+

+

+

+

+

+

+
+ + +
+1

This range is a model of BidirectionalRange, read the docs of Boost.Range + for more information.

+

+

+

+

+

+ Go to source code +

+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bimap/the_tutorial/useful_functions.html b/doc/html/boost_bimap/the_tutorial/useful_functions.html new file mode 100644 index 0000000..f40a862 --- /dev/null +++ b/doc/html/boost_bimap/the_tutorial/useful_functions.html @@ -0,0 +1,454 @@ + + + +Useful functions + + + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

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

+

+ Here is an example that uses projection: +

+

+ Go to source code +

+

+

+

+ +

+
+typedef bimap<std::string,multiset_of<int,std::greater<int> > > bm_type;
+
+bm_type bm;
+bm.insert( bm_type::value_type("John" ,34) );
+bm.insert( bm_type::value_type("Peter",24) );
+bm.insert( bm_type::value_type("Mary" ,12) );
+
+// Find the name of the next younger person after Peter
+
+bm_type::left_const_iterator name_iter = bm.left.find("Peter");
+
+bm_type::right_const_iterator years_iter = bm.project_right(name_iter);
+
+++years_iter;
+
+std::cout << "The next younger person after Peter is " << years_iter->second;
+
+

+

+

+

+

+

+
+

+

+

+

+
+
+ +

+ 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: +

+

+ Go to source + code +

+

+

+

+ +

+
+typedef bimap< int, std::string > bm_type;
+bm_type bm;
+
+bm.insert( bm_type::value_type(1,"one") );
+
+// Replace (1,"one") with (1,"1") using the right map view
+{
+    bm_type::right_iterator it = bm.right.find("one");
+
+    bool successful_replace = bm.right.replace_key( it, "1" );
+
+    assert( successful_replace );
+}
+
+bm.insert( bm_type::value_type(2,"two") );
+
+// Fail to replace (1,"1") with (1,"two") using the left map view
+{
+    assert( bm.size() == 2 );
+
+    bm_type::left_iterator it = bm.left.find(1);
+
+    bool successful_replace = bm.left.replace_data( it, "two" );
+
+    1assert( ! successful_replace );
+    assert( bm.size() == 2 );
+}
+
+

+

+

+

+

+

+
+ + +
+1

it is still valid here, + and the bimap was left unchanged

+

+

+

+

+

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

+

+ Go to source + code +

+

+

+

+ +

+
+typedef bimap< int, std::string > bm_type;
+bm_type bm;
+bm.insert( bm_type::value_type(1,"one") );
+
+// Modify (1,"one") to (1,"1") using the right map view
+{
+    bm_type::right_iterator it = bm.right.find("one");
+
+    bool successful_modify = bm.right.modify_key( it , _key = "1" );
+
+    assert( successful_modify );
+}
+
+bm.insert( bm_type::value_type(2,"two") );
+
+// Fail to modify (1,"1") to (1,"two") using the left map view
+{
+    assert( bm.size() == 2 );
+
+    bm_type::left_iterator it = bm.left.find(1);
+
+    bool successful_modify = bm.left.modify_data( it, _data = "two" );
+
+    1assert( ! successful_modify );
+    assert( bm.size() == 1 );
+}
+
+

+

+

+

+

+

+
+ + +
+1

it is not longer valid + and (1,"1") is removed from the bimap

+

+

+

+

+
+
+ +

+ 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] +

+

+

+

+ +

+
+typedef bimap<int,std::string> bm_type;
+bm_type bm;
+
+// ...
+
+bm_type::left_iterator iter_first  = bm.left.lower_bound(20);
+bm_type::left_iterator iter_second = bm.left.upper_bound(50);
+
+// range [iter_first,iter_second) contains the elements in [20,50]
+
+

+

+

+

+

+

+
+

+

+

+

+

+ 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 +

+

+

+

+ +

+
+bm_type::left_iterator iter_first  = bm.left.upper_bound(20);
+bm_type::left_iterator iter_second = bm.left.lower_bound(50);
+
+// range [iter_first,iter_second) contains the elements in (20,50)
+
+

+

+

+

+

+

+
+

+

+

+

+

+ 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: +

+

+

+

+ +

+
+typedef bimap<int,std::string> bm_type;
+bm_type bm;
+
+// ...
+
+1bm_type::left_range_type r;
+
+2r = bm.left.range( 20 <= _key, _key <= 50 ); // [20,50]
+
+r = bm.left.range( 20 <  _key, _key <  50 ); // (20,50)
+
+r = bm.left.range( 20 <= _key, _key <  50 ); // [20,50)
+
+

+

+

+

+

+

+
+ + + + + + + + +
+1

range_type is a handy + typedef equal to std::pair<iterator,iterator>. const_range_type + is provided too, and it is equal to std::pair<const_iterator,const_iterator>

+2

_key is a Boost.Lambda placeholder. + To use it you have to include <boost/bimap/support/lambda.hpp> +

+

+

+

+

+

+ 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: +

+

+

+

+ +

+
+r = bm.left.range( 20 <= _key, unbounded ); // [20,inf)
+
+r = bm.left.range( unbounded , _key < 50 ); // (-inf,50)
+
+1r = bm.left.range( unbounded , unbounded ); // (-inf,inf)
+
+

+

+

+

+

+

+
+ + +
+1

This is equivalent to std::make_pair(s.begin(),s.end())

+

+

+

+

+

+ Go to source code +

+
+
+ + + +
Copyright © 2006 -2007 Matias Capeletto
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css new file mode 100755 index 0000000..e5d7bb5 --- /dev/null +++ b/doc/html/boostbook.css @@ -0,0 +1,582 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + 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) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 10pt; + } + + pre.synopsis + { + font-size: 10pt; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 10pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 10pt; + line-height: 1.15; + } + + .toc-main + { + text-align: center; + margin: 3pc 16% 3pc 16%; + padding: 3pc 1pc 3pc 1pc; + line-height: 0.1; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 120%; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + font-size: 10pt; + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + div.sidebar img + { + padding: 1pt; + } + + + +/*============================================================================= + Callouts +=============================================================================*/ + .line_callout_bug img + { + float: left; + position:relative; + left: 4px; + top: -12px; + clear: left; + margin-left:-22px; + } + + .callout_bug img + { + } + + + +/*============================================================================= + Variable Lists +=============================================================================*/ + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + /* Make the terms in definition lists bold */ + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #0C7445; + } + + a:visited + { + color: #663974; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, + h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited + { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #E8FBE9; } + .dk_grey_bkd { background-color: #A0DAAC; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc-main + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #E3F9E4; + border: 1px solid #DCDCDC; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + background-color: #FAFFFB; + } + + .programlisting, + .screen + { + border: 1px solid gray; + background-color: #FAFFFB; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc-main + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + .informaltable table, + .table table + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + border-collapse: collapse; + background-color: #FAFFFB; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } diff --git a/doc/html/images/bimap/bimap.structures.png b/doc/html/images/bimap/bimap.structures.png new file mode 100755 index 0000000..c605aaf Binary files /dev/null and b/doc/html/images/bimap/bimap.structures.png differ diff --git a/doc/html/images/bimap/boost.bimap.header.png b/doc/html/images/bimap/boost.bimap.header.png new file mode 100755 index 0000000..c868486 Binary files /dev/null and b/doc/html/images/bimap/boost.bimap.header.png differ diff --git a/doc/html/images/bimap/boost.bimap.logo.png b/doc/html/images/bimap/boost.bimap.logo.png new file mode 100755 index 0000000..80bd8f3 Binary files /dev/null and b/doc/html/images/bimap/boost.bimap.logo.png differ diff --git a/doc/html/images/bimap/collection.type.of.relation.png b/doc/html/images/bimap/collection.type.of.relation.png new file mode 100755 index 0000000..d271f76 Binary files /dev/null and b/doc/html/images/bimap/collection.type.of.relation.png differ diff --git a/doc/html/images/bimap/extended.mapping.framework.png b/doc/html/images/bimap/extended.mapping.framework.png new file mode 100644 index 0000000..0115ad2 Binary files /dev/null and b/doc/html/images/bimap/extended.mapping.framework.png differ diff --git a/doc/html/images/bimap/miBimapFramework.png b/doc/html/images/bimap/miBimapFramework.png new file mode 100755 index 0000000..e9050ac Binary files /dev/null and b/doc/html/images/bimap/miBimapFramework.png differ diff --git a/doc/html/images/bimap/more.bimap.structures.png b/doc/html/images/bimap/more.bimap.structures.png new file mode 100755 index 0000000..f7d8fbc Binary files /dev/null and b/doc/html/images/bimap/more.bimap.structures.png differ diff --git a/doc/html/images/bimap/simple.bimap.png b/doc/html/images/bimap/simple.bimap.png new file mode 100644 index 0000000..51506c8 Binary files /dev/null and b/doc/html/images/bimap/simple.bimap.png differ diff --git a/doc/html/images/bimap/standard.mapping.framework.png b/doc/html/images/bimap/standard.mapping.framework.png new file mode 100644 index 0000000..9b5e641 Binary files /dev/null and b/doc/html/images/bimap/standard.mapping.framework.png differ diff --git a/doc/html/images/bimap/tagged.png b/doc/html/images/bimap/tagged.png new file mode 100755 index 0000000..dd40a6f Binary files /dev/null and b/doc/html/images/bimap/tagged.png differ diff --git a/doc/html/images/callouts/1.png b/doc/html/images/callouts/1.png new file mode 100644 index 0000000..6003ad3 Binary files /dev/null and b/doc/html/images/callouts/1.png differ diff --git a/doc/html/images/callouts/10.png b/doc/html/images/callouts/10.png new file mode 100644 index 0000000..0426f51 Binary files /dev/null and b/doc/html/images/callouts/10.png differ diff --git a/doc/html/images/callouts/11.png b/doc/html/images/callouts/11.png new file mode 100644 index 0000000..821afc4 Binary files /dev/null and b/doc/html/images/callouts/11.png differ diff --git a/doc/html/images/callouts/12.png b/doc/html/images/callouts/12.png new file mode 100644 index 0000000..7cec727 Binary files /dev/null and b/doc/html/images/callouts/12.png differ diff --git a/doc/html/images/callouts/13.png b/doc/html/images/callouts/13.png new file mode 100644 index 0000000..5b41e02 Binary files /dev/null and b/doc/html/images/callouts/13.png differ diff --git a/doc/html/images/callouts/14.png b/doc/html/images/callouts/14.png new file mode 100644 index 0000000..de5bdbd Binary files /dev/null and b/doc/html/images/callouts/14.png differ diff --git a/doc/html/images/callouts/15.png b/doc/html/images/callouts/15.png new file mode 100644 index 0000000..3fd6ac3 Binary files /dev/null and b/doc/html/images/callouts/15.png differ diff --git a/doc/html/images/callouts/2.png b/doc/html/images/callouts/2.png new file mode 100644 index 0000000..f7c1578 Binary files /dev/null and b/doc/html/images/callouts/2.png differ diff --git a/doc/html/images/callouts/3.png b/doc/html/images/callouts/3.png new file mode 100644 index 0000000..3ff0a93 Binary files /dev/null and b/doc/html/images/callouts/3.png differ diff --git a/doc/html/images/callouts/4.png b/doc/html/images/callouts/4.png new file mode 100644 index 0000000..6aa29fc Binary files /dev/null and b/doc/html/images/callouts/4.png differ diff --git a/doc/html/images/callouts/5.png b/doc/html/images/callouts/5.png new file mode 100644 index 0000000..36e7858 Binary files /dev/null and b/doc/html/images/callouts/5.png differ diff --git a/doc/html/images/callouts/6.png b/doc/html/images/callouts/6.png new file mode 100644 index 0000000..c943676 Binary files /dev/null and b/doc/html/images/callouts/6.png differ diff --git a/doc/html/images/callouts/7.png b/doc/html/images/callouts/7.png new file mode 100644 index 0000000..20940de Binary files /dev/null and b/doc/html/images/callouts/7.png differ diff --git a/doc/html/images/callouts/8.png b/doc/html/images/callouts/8.png new file mode 100644 index 0000000..d8e34d4 Binary files /dev/null and b/doc/html/images/callouts/8.png differ diff --git a/doc/html/images/callouts/9.png b/doc/html/images/callouts/9.png new file mode 100644 index 0000000..abe6360 Binary files /dev/null and b/doc/html/images/callouts/9.png differ diff --git a/doc/html/images/caution.png b/doc/html/images/caution.png new file mode 100755 index 0000000..3c3b859 Binary files /dev/null and b/doc/html/images/caution.png differ diff --git a/doc/html/images/extern/boost.blade.logo.png b/doc/html/images/extern/boost.blade.logo.png new file mode 100755 index 0000000..f1ac314 Binary files /dev/null and b/doc/html/images/extern/boost.blade.logo.png differ diff --git a/doc/html/images/extern/googlesoc.png b/doc/html/images/extern/googlesoc.png new file mode 100755 index 0000000..5621b67 Binary files /dev/null and b/doc/html/images/extern/googlesoc.png differ diff --git a/doc/html/images/home.png b/doc/html/images/home.png new file mode 100755 index 0000000..f2047b8 Binary files /dev/null and b/doc/html/images/home.png differ diff --git a/doc/html/images/important.png b/doc/html/images/important.png new file mode 100755 index 0000000..54b4846 Binary files /dev/null and b/doc/html/images/important.png differ diff --git a/doc/html/images/next.png b/doc/html/images/next.png new file mode 100755 index 0000000..f3a1221 Binary files /dev/null and b/doc/html/images/next.png differ diff --git a/doc/html/images/note.png b/doc/html/images/note.png new file mode 100755 index 0000000..c3bebc7 Binary files /dev/null and b/doc/html/images/note.png differ diff --git a/doc/html/images/people/hector.png b/doc/html/images/people/hector.png new file mode 100755 index 0000000..40f52da Binary files /dev/null and b/doc/html/images/people/hector.png differ diff --git a/doc/html/images/people/joaquin.png b/doc/html/images/people/joaquin.png new file mode 100755 index 0000000..f0b1a25 Binary files /dev/null and b/doc/html/images/people/joaquin.png differ diff --git a/doc/html/images/people/mafalda.png b/doc/html/images/people/mafalda.png new file mode 100755 index 0000000..00781df Binary files /dev/null and b/doc/html/images/people/mafalda.png differ diff --git a/doc/html/images/people/matias.png b/doc/html/images/people/matias.png new file mode 100755 index 0000000..3fb32c7 Binary files /dev/null and b/doc/html/images/people/matias.png differ diff --git a/doc/html/images/prev.png b/doc/html/images/prev.png new file mode 100755 index 0000000..f7f0361 Binary files /dev/null and b/doc/html/images/prev.png differ diff --git a/doc/html/images/space.png b/doc/html/images/space.png new file mode 100644 index 0000000..8109f30 Binary files /dev/null and b/doc/html/images/space.png differ diff --git a/doc/html/images/tip.png b/doc/html/images/tip.png new file mode 100755 index 0000000..d96e9bd Binary files /dev/null and b/doc/html/images/tip.png differ diff --git a/doc/html/images/toc/acknowledgements.png b/doc/html/images/toc/acknowledgements.png new file mode 100755 index 0000000..7452979 Binary files /dev/null and b/doc/html/images/toc/acknowledgements.png differ diff --git a/doc/html/images/toc/bimap_and_boost.png b/doc/html/images/toc/bimap_and_boost.png new file mode 100755 index 0000000..652ebfc Binary files /dev/null and b/doc/html/images/toc/bimap_and_boost.png differ diff --git a/doc/html/images/toc/compiler_specifics.png b/doc/html/images/toc/compiler_specifics.png new file mode 100755 index 0000000..505f41c Binary files /dev/null and b/doc/html/images/toc/compiler_specifics.png differ diff --git a/doc/html/images/toc/examples.png b/doc/html/images/toc/examples.png new file mode 100755 index 0000000..eacba13 Binary files /dev/null and b/doc/html/images/toc/examples.png differ diff --git a/doc/html/images/toc/future_work.png b/doc/html/images/toc/future_work.png new file mode 100755 index 0000000..4a334d0 Binary files /dev/null and b/doc/html/images/toc/future_work.png differ diff --git a/doc/html/images/toc/history.png b/doc/html/images/toc/history.png new file mode 100755 index 0000000..2746788 Binary files /dev/null and b/doc/html/images/toc/history.png differ diff --git a/doc/html/images/toc/introduction.png b/doc/html/images/toc/introduction.png new file mode 100755 index 0000000..2594bd7 Binary files /dev/null and b/doc/html/images/toc/introduction.png differ diff --git a/doc/html/images/toc/one_minute_tutorial.png b/doc/html/images/toc/one_minute_tutorial.png new file mode 100755 index 0000000..669249c Binary files /dev/null and b/doc/html/images/toc/one_minute_tutorial.png differ diff --git a/doc/html/images/toc/performance.png b/doc/html/images/toc/performance.png new file mode 100755 index 0000000..871fb57 Binary files /dev/null and b/doc/html/images/toc/performance.png differ diff --git a/doc/html/images/toc/rationale.png b/doc/html/images/toc/rationale.png new file mode 100755 index 0000000..276ea6a Binary files /dev/null and b/doc/html/images/toc/rationale.png differ diff --git a/doc/html/images/toc/reference.png b/doc/html/images/toc/reference.png new file mode 100755 index 0000000..4584e37 Binary files /dev/null and b/doc/html/images/toc/reference.png differ diff --git a/doc/html/images/toc/release_notes.png b/doc/html/images/toc/release_notes.png new file mode 100755 index 0000000..5f807be Binary files /dev/null and b/doc/html/images/toc/release_notes.png differ diff --git a/doc/html/images/toc/test_suite.png b/doc/html/images/toc/test_suite.png new file mode 100755 index 0000000..31432e9 Binary files /dev/null and b/doc/html/images/toc/test_suite.png differ diff --git a/doc/html/images/toc/the_tutorial.png b/doc/html/images/toc/the_tutorial.png new file mode 100755 index 0000000..5902655 Binary files /dev/null and b/doc/html/images/toc/the_tutorial.png differ diff --git a/doc/html/images/up.png b/doc/html/images/up.png new file mode 100755 index 0000000..ef43407 Binary files /dev/null and b/doc/html/images/up.png differ diff --git a/doc/html/images/warning.png b/doc/html/images/warning.png new file mode 100755 index 0000000..51a30f7 Binary files /dev/null and b/doc/html/images/warning.png differ diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 0000000..41449f8 --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,160 @@ + + + +Chapter 1. Boost.Bimap + + + + + + + + + + + + + +
+Boost C++ LibrariesChapter Logo +HomeLibrariesPeopleFAQMore
+
+
Next
+
+
+

+Chapter 1. Boost.Bimap

+

+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) +

+
+
+ +
+ +

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

+

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

+
+
+ + + +

Last revised: June 04, 2007 at 19:49:38 GMT

+
+
Next
+ + diff --git a/doc/introduction.qbk b/doc/introduction.qbk new file mode 100755 index 0000000..25c1fa3 --- /dev/null +++ b/doc/introduction.qbk @@ -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] \ No newline at end of file diff --git a/doc/jamfile.v2 b/doc/jamfile.v2 new file mode 100755 index 0000000..b597ddd --- /dev/null +++ b/doc/jamfile.v2 @@ -0,0 +1,37 @@ +# 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 + ; + +boostbook standalone + : + bimap + : + toc.max.depth=2 + toc.section.depth=4 + chunk.section.depth=2 + logo.image.src="'images/bimap/boost.bimap.header.png'" + ; + + +# 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 ; + diff --git a/doc/performance.qbk b/doc/performance.qbk new file mode 100755 index 0000000..3433579 --- /dev/null +++ b/doc/performance.qbk @@ -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] \ No newline at end of file diff --git a/doc/quick_tutorial.qbk b/doc/quick_tutorial.qbk new file mode 100755 index 0000000..bc14fcd --- /dev/null +++ b/doc/quick_tutorial.qbk @@ -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 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` +* `bm.right` is signature-compatible with `std::map` +* `bm` is signature-compatible with `std::set< relation >` + +__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 + +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` iterator is dereferenced the return type is +`std::pair`, so the following code is valid: +`m.begin()->second = new_value;`. +However dereferencing a `bimap::left_iterator` returns a type that is +['signature-compatible] with a `std::pair` + + bm.left.find(1)->second = "1"; // Compilation error + +If you insert `(1,"one")` and `(1,"1")` in a `std::map` the second insertion will have no effect. In a `bimap` 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] diff --git a/doc/rationale.qbk b/doc/rationale.qbk new file mode 100755 index 0000000..4a5028c --- /dev/null +++ b/doc/rationale.qbk @@ -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`, `relation` and `pair`. +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 bm`: + +# `bm.left` is signature-compatible with a `std::map` +# `bm.right` is signature-compatible with a `std::map` +# `bm` is signature-compatible with a `std::set >` + +__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` that has two references +named first and second that bind to `A` and `B`, or to `B` and `A`. + + relation r; + + const_reference_pair pba(r); + const_reference_pair 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(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`, you can build other container that behaves exactly as a +`std::set` 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]] +[:['- bm.right is compatible with std::map]] +[:['- bm is compatible with std::set>]] +[:[' +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 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 >. 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 that have two references named +first and second that bind to A and B, or B and A. +]] +`` +relation r; +const_reference_pair pba(r); +const_reference_pair 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 size equals the pair 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). +]] +[:[' +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] + + + + diff --git a/doc/reference.qbk b/doc/reference.qbk new file mode 100755 index 0000000..63803be --- /dev/null +++ b/doc/reference.qbk @@ -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] \ No newline at end of file diff --git a/doc/reference/bimap.qbk b/doc/reference/bimap.qbk new file mode 100755 index 0000000..737a110 --- /dev/null +++ b/doc/reference/bimap.qbk @@ -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::type by(); + + template< class Tag > + const map_by::type & by() const; + + template< class Tag, class IteratorType > + map_by::iterator project(IteratorType iter); + + template< class Tag, class IteratorType > + map_by::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 + 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 + result_of::get< Tag, Relation>::type get(Relation &r); + + template + 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 ` `left_key_type` is `A` and + `right_key_type` is `B`. + If there are tags, it is better to use: `Bimap::map_by::key_type`. +] + + left_data_type, right_data_type + +[: Data type of each side. In a bimap left_key_type is B and + right_key_type is A. + If there are tags, it is better to use: `Bimap::map_by::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::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::iterator` and + `Bimap::map_by::const_iterator` +] + + + left_map, right_map + +[: Map view type of each side. + If there are tags, it is better to use: + `Bimap::map_by::type`. +] + +[endsect] + +[section Constructors, copy and assignment] + + bimap(); + +* [*Effects:] Constructs an empty `bimap`. +* [*Complexity:] Constant. + + template + 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::type` yields the type of the map view tagged with `Tag`. +`map_by::`['-type name-] is the same as `map_by::type::`['-type name-]. +* [*Requires: ] `Tag` is a valid user defined name of the bimap. + + + template< class Tag > + map_by::type by(); + + template< class Tag > + const map_by::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::iterator project(IteratorType iter); + + template< class Tag, class IteratorType > + map_by::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] \ No newline at end of file diff --git a/doc/reference/list_of.qbk b/doc/reference/list_of.qbk new file mode 100755 index 0000000..b8f495e --- /dev/null +++ b/doc/reference/list_of.qbk @@ -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 ``[link reference_list_of_push_front_value push_front]``(const value_type & x); + void pop_front(); + + std::pair ``[link reference_list_of_push_back_value push_back]``(const value_type & x); + void pop_back(); + + std::pair ``[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, ... >` + +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 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 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 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` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`. +Both the view and `x` are sorted according to `std::less`. +* [*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` is a __SGI_STRICT_WEAK_ORDERING__ over value_type. +* [*Effects:] Sorts the view according to `std::less`. 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` 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().begin(), m.get().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] diff --git a/doc/reference/set_of.qbk b/doc/reference/set_of.qbk new file mode 100755 index 0000000..543a6af --- /dev/null +++ b/doc/reference/set_of.qbk @@ -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 ``[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 + ``[link reference_set_of_equal_range_key equal_range]``(const CompatibleKey & x); + + template< class CompatibleKey > + std::pair + ``[link reference_set_of_equal_range_key equal_range]``(const CompatibleKey & x) const; + + // Only in maps views + // { + + template< class LowerBounder, class UpperBounder> + std::pair ``[link reference_set_of_range_lower_upper range]``( + LowerBounder lower, UpperBounder upper); + + template< class LowerBounder, class UpperBounder> + std::pair ``[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 equal_range( + const CompatibleKey & x, const CompatibleCompare & comp); + + template< class CompatibleKey, class CompatibleCompare > + std::pair equal_range( + const CompatibleKey & x, const CompatibleCompare & comp) const; + +] + + +In the case of a `bimap< {multi}set_of, ... >` + +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 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 + equal_range(const key_type & x); + + template< class CompatibleKey > + std::pair + 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 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().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().begin(), m.get().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] \ No newline at end of file diff --git a/doc/reference/unconstrained_set_of.qbk b/doc/reference/unconstrained_set_of.qbk new file mode 100755 index 0000000..9b487dd --- /dev/null +++ b/doc/reference/unconstrained_set_of.qbk @@ -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, ... >` + +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] + + diff --git a/doc/reference/unordered_set_of.qbk b/doc/reference/unordered_set_of.qbk new file mode 100755 index 0000000..d386b87 --- /dev/null +++ b/doc/reference/unordered_set_of.qbk @@ -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 + ``[link reference_unordered_set_of_equal_range_key equal_range]``(const CompatibleKey & x); + + template< class CompatibleKey > + std::pair + ``[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 + 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 + data_type & ``[link reference_unordered_set_of_operator_bracket_key operator\[\]]``(const CompatibleKey & k); + + template + 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, ... >` + +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::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 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 + equal_range(const CompatibleKey & x); + + template< class CompatibleKey > + std::pair + 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().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().begin(), m.get().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().end(n)` for some n, +then `it`'` == m`'`.get().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] \ No newline at end of file diff --git a/doc/reference/vector_of.qbk b/doc/reference/vector_of.qbk new file mode 100755 index 0000000..882302e --- /dev/null +++ b/doc/reference/vector_of.qbk @@ -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 ``[link reference_vector_of_push_front_value push_front]``(const value_type & x); + void pop_front(); + + std::pair ``[link reference_vector_of_push_back_value push_back]``(const value_type & x); + void pop_back(); + + std::pair ``[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, ... >` + +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 + 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 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 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 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` is a __SGI_STRICT_WEAK_ORDERING__ over +`value_type`. Both the view and `x` are sorted according to `std::less`. +* [*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` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`. +* [*Effects:] Sorts the view according to `std::less`. +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().begin(), m.get().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] \ No newline at end of file diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk new file mode 100755 index 0000000..e093aa2 --- /dev/null +++ b/doc/release_notes.qbk @@ -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] \ No newline at end of file diff --git a/doc/test_suite.qbk b/doc/test_suite.qbk new file mode 100755 index 0000000..c6213b8 --- /dev/null +++ b/doc/test_suite.qbk @@ -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] \ No newline at end of file diff --git a/doc/toolbox.qbk b/doc/toolbox.qbk new file mode 100755 index 0000000..3ced874 --- /dev/null +++ b/doc/toolbox.qbk @@ -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(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] diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk new file mode 100755 index 0000000..2207d71 --- /dev/null +++ b/doc/tutorial.qbk @@ -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, ``*CollectionType*``_of > 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, ``*CollectionType*``_of > bm_type; + bm_type bm; + +The following now describes the resulting map views of the bidirectional +map. + +* `bm.left` is signature-compatible with *LeftMapType*`` +* `bm.right` is signature-compatible with *RightMapType*`` + +[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` + + `multiset_of` ] + +[[*KeyComp ] is a Functor that compares two types using a less-than operator. +By default, this is `std::less`. ]] + +[[`unordered_set_of` + + `unordered_multiset_of`] + +[[*HashFunctor ] converts a `T` object into an `std::size_t` value. By default it is `boost::hash`. + + [*EqualKey ] is a Functor that tests two types for equality. By default, the +equality operator is `std::equal_to`. ]] +[[`list_of` ][No additional parameters.]] +[[`vector_of` ][No additional parameters.]] +[[`unconstrained_set_of` ][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 > + + > 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` + + `multiset_of_relation` ] +[[*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` + + `unordered_multiset_of_relation`] +[[*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 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 > 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` 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`. + +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`][ + `iterator ` *->* `relation` + + `left_iterator ` *->* `pair` + + `right_iterator` *->* `pair` +]] +[[`bimap,unordered_set_of >`][ + `iterator ` *->* `relation` + + `left_iterator ` *->* `pair` + + `right_iterator` *->* `pair` +]] +[[`bimap,list_of >`][ + `iterator ` *->* `relation` + + `left_iterator ` *->* `pair` + + `right_iterator` *->* `pair` +]] +[[`bimap,set_of >`][ + `iterator ` *->* `relation` + + `left_iterator ` *->* `pair` + + `right_iterator` *->* `pair` +]] +[[`bimap,unconstrained_set_of >`][ + `iterator ` *->* `relation` + + `left_iterator ` *->* `pair` + + `right_iterator` *->* `pair` +]] +] + +[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 > 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 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 `` 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` +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()`] ] +[[`bm.right`] [`bm.by()`] ] +[[`bm_type::left_map`] [`bm::map_by::type`] ] +[[`bm_type::right_value_type`] [`bm::map_by::value_type`] ] +[[`bm_type::left_iterator`] [`bm::map_by::iterator`] ] +[[`bm_type::right_const_iterator`][`bm::map_by::const_iterator`]] +[[`iter->left`] [`iter->get()`] ] +[[`iter->right`] [`iter->get()`] ] +[[`left_iter->first`] [`left_iter->get()`] ] +[[`left_iter->second`] [`left_iter->get()`] ] +[[`right_iter->first`] [`right_iter->get()`] ] +[[`right_iter->second`] [`right_iter->get()`] ] +[[`bm.project_left(iter)`] [`bm.project(iter)`] ] +[[`bm.project_right(iter)`] [`bm.project(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`, or can be a `{CollectionType}_of` 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`. 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 > + +* set_of_relation_type: based on the left key type +* info: no info +* allocator: std::allocator + + + bimap< L, R ,SetOfRelationType> + +* set_of_relation_type: SetOfRelationType +* info: no info +* allocator: std::allocator + + + bimap< L, R , SetOfRelationType, with_info > + +* set_of_relation_type: SetOfRelationType +* info: Info +* allocator: std::allocator + + + bimap< L, R , SetOfRelationType, with_info, Allocator> + +* set_of_relation_type: SetOfRelationType +* info: Info +* allocator: Allocator + + + bimap< L, R , SetOfRelationType, Allocator> + +* set_of_relation_type: SetOfRelationType +* info: no info +* allocator: Allocator + + + bimap< L, R , with_info > + +* set_of_relation_type: based on the left key type +* info: Info +* allocator: std::allocator + + + bimap< L, R , with_info, Allocator> + +* set_of_relation_type: based on the left key type +* allocator: Allocator + + + bimap< L, R , Allocator> + +* set_of_relation_type: based on the left key type +* info: no info +* allocator: Allocator + + + + +[endsect] + +[endsect] diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 new file mode 100755 index 0000000..4241629 --- /dev/null +++ b/example/Jamfile.v2 @@ -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 ] + ; diff --git a/example/at_function_examples.cpp b/example/at_function_examples.cpp new file mode 100755 index 0000000..c0b916f --- /dev/null +++ b/example/at_function_examples.cpp @@ -0,0 +1,97 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include +#include + +#include +#include +#include +#include + +using namespace boost::bimaps; + +void first_bimap() +{ + //[ code_at_function_first + + typedef bimap< set_of< std::string >, list_of< int > > bm_type; + bm_type bm; + + try + { + bm.left.at("one") = 1; // throws std::out_of_range + } + catch( std::out_of_range & e ) {} + + assert( bm.empty() ); + + bm.left["one"] = 1; // Ok + + assert( bm.left.at("one") == 1 ); // Ok + //] +} + +void second_bimap() +{ + //[ code_at_function_second + + typedef bimap< multiset_of, unordered_set_of > bm_type; + bm_type bm; + + //<- + /* + //-> + bm.right[1] = "one"; // compilation error + //<- + */ + //-> + + bm.right.insert( bm_type::right_value_type(1,"one") ); + + assert( bm.right.at(1) == "one" ); // Ok + + try + { + std::cout << bm.right.at(2); // throws std::out_of_range + } + catch( std::out_of_range & e ) {} + + //<- + /* + //-> + bm.right.at(1) = "1"; // compilation error + //<- + */ + //-> + + //] +} + +int main() +{ + first_bimap(); + second_bimap(); + return 0; +} + diff --git a/example/bimap_and_boost/assign.cpp b/example/bimap_and_boost/assign.cpp new file mode 100755 index 0000000..7c7652b --- /dev/null +++ b/example/bimap_and_boost/assign.cpp @@ -0,0 +1,79 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include + +#include +#include + +#include +#include +#include + +using namespace boost::bimaps; +using namespace boost; + + +int main() +{ + //[ code_bimap_and_boost_assign + + typedef bimap< multiset_of< int >, list_of< std::string > > bm_type; + + // We can use assign::list_of to initialize the container. + + bm_type bm = assign::list_of< bm_type::relation > /*< + Note that `bm_type::relation` has to be used instead of `bm_type::value_type`. + Contrary to `value_type`, `relation` type stores the elements as non const, a + requirement of `assign::list_of` >*/ + ( 1, "one" ) + ( 2, "two" ) + ( 3, "three" ); + + // The left map view is a multiset, again we use insert + + assign::insert( bm.left ) + ( 4, "four" ) + ( 5, "five" ) + ( 6, "six" ); + + // The right map view is a list so we use push_back here + // Note the order of the elements in the list! + + assign::push_back( bm.right ) + ( "seven" , 7 ) + ( "eight" , 8 ); + + assign::push_front( bm.right ) + ( "nine" , 9 ) + ( "ten" , 10 ) + ( "eleven", 11 ); + + // Since it is left_based the main view is a multiset, so we use insert + + assign::insert( bm ) + ( 12, "twelve" ) + ( 13, "thirteen" ); + //] + + return 0; +} diff --git a/example/bimap_and_boost/foreach.cpp b/example/bimap_and_boost/foreach.cpp new file mode 100755 index 0000000..6fc1514 --- /dev/null +++ b/example/bimap_and_boost/foreach.cpp @@ -0,0 +1,106 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +#include + +#include +#include +#include + +using namespace boost::bimaps; + + +int main() +{ + //[ code_bimap_and_boost_foreach + + typedef bimap< std::string, list_of > bm_type; + + bm_type bm; + bm.insert( bm_type::value_type("1", 1) ); + bm.insert( bm_type::value_type("2", 2) ); + bm.insert( bm_type::value_type("3", 4) ); + bm.insert( bm_type::value_type("4", 2) ); + + BOOST_FOREACH( bm_type::left_reference p, bm.left ) + { + ++p.second; /*< We can modify the right element because we have + use a mutable collection type in the right side. >*/ + } + + BOOST_FOREACH( bm_type::right_const_reference p, bm.right ) + { + std::cout << p.first << "-->" << p.second << std::endl; + } + + //] + + // More examples + + BOOST_FOREACH( bm_type::right_reference p, bm.right ) + { + ++p.first; + } + + BOOST_FOREACH( bm_type::left_const_reference p, bm.left ) + { + std::cout << p.first << "-->" << p.second << std::endl; + } + + BOOST_FOREACH( bm_type::reference p, bm ) + { + ++p.right; + } + + const bm_type & cbm = bm; + BOOST_FOREACH( bm_type::const_reference p, cbm ) + { + std::cout << p.left << "-->" << p.right << std::endl; + } + + BOOST_FOREACH( bm_type::const_reference p, bm ) + { + std::cout << p.left << "-->" << p.right << std::endl; + } + + //[ code_bimap_and_boost_foreach_using_range + + BOOST_FOREACH( bm_type::left_reference p, + ( bm.left.range( "1" <= _key, _key < "3" ) )) + { + ++p.second; + } + + BOOST_FOREACH( bm_type::left_const_reference p, + ( bm.left.range( "1" <= _key, _key < "3" ) )) + { + std::cout << p.first << "-->" << p.second << std::endl; + } + //] + + return 0; +} + + diff --git a/example/bimap_and_boost/lambda.cpp b/example/bimap_and_boost/lambda.cpp new file mode 100755 index 0000000..765503d --- /dev/null +++ b/example/bimap_and_boost/lambda.cpp @@ -0,0 +1,49 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include + +#include +#include + +using namespace boost::bimaps; + +int main() +{ + //[ code_bimap_and_boost_lambda + + typedef bimap< std::string, int > bm_type; + + bm_type bm; + bm.insert( bm_type::value_type("one",1) ); + bm.insert( bm_type::value_type("two",2) ); + + bm.right.range( 5 < _key, _key < 10 ); + + bm.left.modify_key( bm.left.find("one"), _key = "1" ); + + bm.left.modify_data( bm.left.begin(), _data *= 10 ); + //] + return 0; +} + + diff --git a/example/bimap_and_boost/property_map.cpp b/example/bimap_and_boost/property_map.cpp new file mode 100755 index 0000000..298bae8 --- /dev/null +++ b/example/bimap_and_boost/property_map.cpp @@ -0,0 +1,59 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +#include +#include +#include + +using namespace boost::bimaps; + +//[ code_bimap_and_boost_property_map + +template +void foo(AddressMap & address_map) +{ + typedef typename boost::property_traits::value_type value_type; + typedef typename boost::property_traits::key_type key_type; + + value_type address; + key_type fred = "Fred"; + std::cout << get(address_map, fred); +} + +int main() +{ + typedef bimap > Name2Address; + typedef Name2Address::value_type location; + + Name2Address name2address; + name2address.insert( location("Fred", "710 West 13th Street") ); + name2address.insert( location( "Joe", "710 West 13th Street") ); + + foo( name2address.left ); + + return 0; +} +//] + diff --git a/example/bimap_and_boost/range.cpp b/example/bimap_and_boost/range.cpp new file mode 100755 index 0000000..605e86a --- /dev/null +++ b/example/bimap_and_boost/range.cpp @@ -0,0 +1,121 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include + +#include +#include + +//[ code_bimap_and_boost_range_functions + +template< class ForwardReadableRange, class UnaryFunctor > +UnaryFunctor for_each(const ForwardReadableRange & r, UnaryFunctor func) +{ + typedef typename + boost::range_const_iterator::type const_iterator; + + for(const_iterator i= boost::begin(r), iend= boost::end(r); i!=iend; ++i ) + { + func(*i); + } + + return func; +} + +template< class ForwardReadableRange, class Predicate > +typename boost::range_difference::type + count_if(const ForwardReadableRange & r, Predicate pred) +{ + typedef typename + boost::range_const_iterator::type const_iterator; + + typename boost::range_difference::type c = 0; + + for( const_iterator i = boost::begin(r), iend = boost::end(r); i != iend; ++i ) + { + if( pred(*i) ) ++c; + } + + return c; +} +//] + +#include +#include +#include +#include + +using namespace boost::bimaps; +using namespace boost; + +//[ code_bimap_and_boost_range + +struct pair_printer +{ + pair_printer(std::ostream & o) : os(o) {} + template< class Pair > + void operator()(const Pair & p) + { + os << "(" << p.first << "," << p.second << ")"; + } + private: + std::ostream & os; +}; + +struct second_extractor +{ + template< class Pair > + const typename Pair::second_type & operator()(const Pair & p) + { + return p.second; + } +}; + +int main() +{ + typedef bimap< double, multiset_of > bm_type; + + bm_type bm; + bm.insert( bm_type::value_type(2.5 , 1) ); + bm.insert( bm_type::value_type(3.1 , 2) ); + //... + bm.insert( bm_type::value_type(6.4 , 4) ); + bm.insert( bm_type::value_type(1.7 , 2) ); + + // Print all the elements of the left map view + + for_each( bm.left, pair_printer(std::cout) ); + + // Print a range of elements of the right map view + + for_each( bm.right.range( 2 <= _key, _key < 6 ), pair_printer(std::cout) ); + + // Count the number of elements where the data is equal to 2 from a + // range of elements of the left map view + + count_if( bm.left.range( 2.3 < _key, _key < 5.4 ), + bind( second_extractor(), _1 ) == 2 ); + + return 0; +} +//] + diff --git a/example/bimap_and_boost/serialization.cpp b/example/bimap_and_boost/serialization.cpp new file mode 100755 index 0000000..f4791a1 --- /dev/null +++ b/example/bimap_and_boost/serialization.cpp @@ -0,0 +1,89 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include +#include + +#include + +#include +#include + +using namespace boost::bimaps; + +int main() +{ + //[ code_bimap_and_boost_serialization + + typedef bimap< std::string, int > bm_type; + + // Create a bimap and serialize it to a file + { + bm_type bm; + bm.insert( bm_type::value_type("one",1) ); + bm.insert( bm_type::value_type("two",2) ); + + std::ofstream ofs("data"); + boost::archive::text_oarchive oa(ofs); + + oa << const_cast(bm); /*< + We must do a const cast because Boost.Serialization archives + only save const objects. Read Boost.Serializartion docs for the + rationale behind this decision >*/ + + /*<< We can only serialize iterators if the bimap was serialized first. + Note that the const cast is not requiered here because we create + our iterators as const. >>*/ + const bm_type::left_iterator left_iter = bm.left.find("two"); + oa << left_iter; + + const bm_type::right_iterator right_iter = bm.right.find(1); + oa << right_iter; + } + + // Load the bimap back + { + bm_type bm; + + std::ifstream ifs("data", std::ios::binary); + boost::archive::text_iarchive ia(ifs); + + ia >> bm; + + assert( bm.size() == 2 ); + + bm_type::left_iterator left_iter; + ia >> left_iter; + + assert( left_iter->first == "two" ); + + bm_type::right_iterator right_iter; + ia >> right_iter; + + assert( right_iter->first == 1 ); + } + //] + + return 0; +} + diff --git a/example/bimap_and_boost/typeof.cpp b/example/bimap_and_boost/typeof.cpp new file mode 100755 index 0000000..3cd99c6 --- /dev/null +++ b/example/bimap_and_boost/typeof.cpp @@ -0,0 +1,86 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include +#include + +#include + +using namespace boost::bimaps; + +struct name {}; +struct number {}; + +void using_auto() +{ + //[ code_bimap_and_boost_typeof_first + + typedef bimap< tagged, tagged > bm_type; + bm_type bm; + bm.insert( bm_type::value_type("one" ,1) ); + bm.insert( bm_type::value_type("two" ,2) ); + //] + + //[ code_bimap_and_boost_typeof_using_auto + + for( BOOST_AUTO(iter, bm.by().begin()); iter!=bm.by().end(); ++iter) + { + std::cout << iter->first << " --> " << iter->second << std::endl; + } + + BOOST_AUTO( iter, bm.by().find(2) ); + std::cout << "2: " << iter->get(); + //] +} + +void not_using_auto() +{ + typedef bimap< tagged, tagged > bm_type; + bm_type bm; + bm.insert( bm_type::value_type("one" ,1) ); + bm.insert( bm_type::value_type("two" ,2) ); + + //[ code_bimap_and_boost_typeof_not_using_auto + + for( bm_type::map_by::iterator iter = bm.by().begin(); + iter!=bm.by().end(); ++iter) + { + std::cout << iter->first << " --> " << iter->second << std::endl; + } + + bm_type::map_by::iterator iter = bm.by().find(2); + std::cout << "2: " << iter->get(); + //] +} + +int main() +{ + using_auto(); + not_using_auto(); + + return 0; +} + + + + diff --git a/example/bimap_and_boost/xpressive.cpp b/example/bimap_and_boost/xpressive.cpp new file mode 100755 index 0000000..cad0476 --- /dev/null +++ b/example/bimap_and_boost/xpressive.cpp @@ -0,0 +1,57 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include + +#include + +#include +#include + +using namespace boost::bimaps; +using namespace boost::xpressive; +namespace xp = boost::xpressive; + +int main() +{ + //[ code_bimap_and_boost_xpressive + + typedef bimap< std::string, int > bm_type; + bm_type bm; + + std::string rel_str("one <--> 1 two <--> 2 three <--> 3"); + + sregex rel = ( (s1= +_w) >> " <--> " >> (s2= +_d) ) + [ + xp::ref(bm)->*insert( construct(s1, as(s2)) ) + ]; + + sregex relations = rel >> *(+_s >> rel); + + regex_match(rel_str, relations); + + assert( bm.size() == 3 ); + //] + + return 0; +} + diff --git a/example/mi_to_b_path/bidirectional_map.cpp b/example/mi_to_b_path/bidirectional_map.cpp new file mode 100755 index 0000000..20edf94 --- /dev/null +++ b/example/mi_to_b_path/bidirectional_map.cpp @@ -0,0 +1,87 @@ +// 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) + + +// Boost.Bimap Example +//----------------------------------------------------------------------------- +// 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 such that no two elements exists with +// the same first or second value (std::map only guarantees uniqueness of the +// first member). +// Fast lookup is provided for both keys. The program features a tiny +// Spanish-English dictionary with online query of words in both languages. + +#include + +//[ code_mi_to_b_path_bidirectional_map + +#include +#include +#include + +using namespace boost::bimaps; + +// A dictionary is a bidirectional map from strings to strings + +typedef bimap dictionary; +typedef dictionary::value_type translation; + +int main() +{ + dictionary d; + + // Fill up our microdictionary. + // first members Spanish, second members English. + + d.insert( translation("hola" ,"hello" )); + d.insert( translation("adios","goodbye")); + d.insert( translation("rosa" ,"rose" )); + d.insert( translation("mesa" ,"table" )); + + std::cout << "enter a word" << std::endl; + std::string word; + std::getline(std::cin,word); + + // search the queried word on the from index (Spanish) + + dictionary::left_const_iterator it = d.left.find(word); + + if( it != d.left.end() ) + { + // the second part of the element is the equivalent in English + + std::cout << word << " is said " + << it->second /*< `it` is an iterator of the left view, so + `it->second` refers to the right element of + the relation, the word in english >*/ + << " in English" << std::endl; + } + else + { + // word not found in Spanish, try our luck in English + + dictionary::right_const_iterator it2 = d.right.find(word); + if( it2 != d.right.end() ) + { + std::cout << word << " is said " + << it2->second /*< `it2` is an iterator of the right view, so + `it2->second` refers to the left element of + the relation, the word in spanish >*/ + << " in Spanish" << std::endl; + } + else + { + std::cout << "No such word in the dictionary" << std::endl; + } + } + + return 0; +} +//] diff --git a/example/mi_to_b_path/hashed_indices.cpp b/example/mi_to_b_path/hashed_indices.cpp new file mode 100755 index 0000000..22bb391 --- /dev/null +++ b/example/mi_to_b_path/hashed_indices.cpp @@ -0,0 +1,94 @@ +// 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) + + +// Boost.Bimap Example +//----------------------------------------------------------------------------- +// Hashed indices can be used as an alternative to ordered indices when fast +// lookup 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. + +#include + +//[ code_mi_to_b_path_hashed_indices + +#include +#include + +#include + +#include +#include +#include +#include + +using namespace boost::bimaps; + +struct word {}; +struct occurrences {}; + +typedef bimap +< + + multiset_of< tagged, std::greater >, +unordered_set_of< tagged< std::string, word> > + +> word_counter; + +typedef boost::tokenizer > text_tokenizer; + +int main() +{ + + std::string text= + "Relations between data in the STL are represented with maps." + "A map is a directed relation, by using it you are representing " + "a mapping. In this directed relation, the first type is related to " + "the second type but it is not true that the inverse relationship " + "holds. This is useful in a lot of situations, but there are some " + "relationships that are bidirectional by nature."; + + // feed the text into the container + + word_counter wc; + text_tokenizer tok(text,boost::char_separator(" \t\n.,;:!?'\"-")); + unsigned int total_occurrences = 0; + + for( text_tokenizer::const_iterator it = tok.begin(), it_end = tok.end(); + it != it_end ; ++it ) + { + ++total_occurrences; + + word_counter::map_by::iterator wit = + wc.by().insert( + word_counter::map_by::value_type(0,*it) + ).first; + + wc.by().modify_key( wit, ++_key); + } + + // list words by frequency of appearance + + std::cout << std::fixed << std::setprecision(2); + + for( word_counter::map_by::const_iterator + wit = wc.by().begin(), + wit_end = wc.by().end(); + + wit != wit_end; ++wit ) + { + std::cout << std::setw(15) << wit->get() << ": " + << std::setw(5) + << 100.0 * wit->get() / total_occurrences << "%" + << std::endl; + } + + return 0; +} +//] diff --git a/example/mi_to_b_path/mi_bidirectional_map.cpp b/example/mi_to_b_path/mi_bidirectional_map.cpp new file mode 100755 index 0000000..27045d0 --- /dev/null +++ b/example/mi_to_b_path/mi_bidirectional_map.cpp @@ -0,0 +1,107 @@ +// 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) + +/****************************************************************************** +Boost.MultiIndex +******************************************************************************/ + +#include + +//[ code_mi_to_b_path_mi_bidirectional_map + +#include +#include + +#include +#include +#include + +using namespace boost; +using namespace boost::multi_index; + +// tags for accessing both sides of a bidirectional map + +struct from {}; +struct to {}; + +// The class template bidirectional_map wraps the specification +// of a bidirectional map based on multi_index_container. + +template +struct bidirectional_map +{ + typedef std::pair value_type; + + typedef multi_index_container< + value_type, + indexed_by + < + ordered_unique + < + tag, member + >, + ordered_unique + < + tag, member + > + > + + > type; + +}; + +// A dictionary is a bidirectional map from strings to strings + +typedef bidirectional_map::type dictionary; + +int main() +{ + dictionary d; + + // Fill up our microdictionary. + // first members Spanish, second members English. + + d.insert(dictionary::value_type("hola","hello")); + d.insert(dictionary::value_type("adios","goodbye")); + d.insert(dictionary::value_type("rosa","rose")); + d.insert(dictionary::value_type("mesa","table")); + + std::cout << "enter a word" << std::endl; + std::string word; + std::getline(std::cin,word); + + // search the queried word on the from index (Spanish) + + dictionary::iterator it = d.get().find(word); + + if( it != d.end() ) + { + // the second part of the element is the equivalent in English + + std::cout << word << " is said " + << it->second << " in English" << std::endl; + } + else + { + // word not found in Spanish, try our luck in English + + dictionary::index_iterator::type it2 = d.get().find(word); + if( it2 != d.get().end() ) + { + std::cout << word << " is said " + << it2->first << " in Spanish" << std::endl; + } + else + { + std::cout << "No such word in the dictionary" << std::endl; + } + } + + return 0; +} +//] diff --git a/example/mi_to_b_path/mi_hashed_indices.cpp b/example/mi_to_b_path/mi_hashed_indices.cpp new file mode 100755 index 0000000..f91b835 --- /dev/null +++ b/example/mi_to_b_path/mi_hashed_indices.cpp @@ -0,0 +1,100 @@ +// 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) + + +/***************************************************************************** +Boost.MultiIndex +*****************************************************************************/ + +#include + +//[ code_mi_to_b_path_mi_hashed_indices + +#include +#include + +#include + +#include +#include +#include +#include +#include + +using namespace boost::multi_index; +namespace bl = boost::lambda; + +// word_counter keeps the ocurrences of words inserted. A hashed +// index allows for fast checking of preexisting entries. + +struct word_counter_entry +{ + std::string word; + unsigned int occurrences; + + word_counter_entry( std::string word_ ) : word(word_), occurrences(0) {} +}; + +typedef multi_index_container +< + word_counter_entry, + indexed_by + < + ordered_non_unique + < + BOOST_MULTI_INDEX_MEMBER( + word_counter_entry,unsigned int,occurrences), + std::greater + >, + hashed_unique + < + BOOST_MULTI_INDEX_MEMBER(word_counter_entry,std::string,word) + > + > + +> word_counter; + +typedef boost::tokenizer > text_tokenizer; + +int main() +{ + std::string text= + "En un lugar de la Mancha, de cuyo nombre no quiero acordarme... " + "...snip..." + "...no se salga un punto de la verdad."; + + // feed the text into the container + + word_counter wc; + text_tokenizer tok(text,boost::char_separator(" \t\n.,;:!?'\"-")); + unsigned int total_occurrences = 0; + + for( text_tokenizer::iterator it = tok.begin(), it_end = tok.end(); + it != it_end ; ++it ) + { + ++total_occurrences; + word_counter::iterator wit = wc.insert(*it).first; + wc.modify_key( wit, ++ bl::_1 ); + } + + // list words by frequency of appearance + + std::cout << std::fixed << std::setprecision(2); + + for( word_counter::iterator wit = wc.begin(), wit_end=wc.end(); + wit != wit_end; ++wit ) + { + std::cout << std::setw(11) << wit->word << ": " + << std::setw(5) + << 100.0 * wit->occurrences / total_occurrences << "%" + << std::endl; + } + + return 0; +} +//] diff --git a/example/mi_to_b_path/tagged_bidirectional_map.cpp b/example/mi_to_b_path/tagged_bidirectional_map.cpp new file mode 100755 index 0000000..4c0ddb6 --- /dev/null +++ b/example/mi_to_b_path/tagged_bidirectional_map.cpp @@ -0,0 +1,90 @@ +// 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) + + +// Boost.Bimap Example +//----------------------------------------------------------------------------- +// 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 such that no two elements exists with +// the same first or second value (std::map only guarantees uniqueness of the +// first member). +// Fast lookup is provided for both keys. The program features a tiny +// Spanish-English dictionary with online query of words in both languages. + +//[ code_mi_to_b_path_tagged_bidirectional_map + +#include + +#include + +using namespace boost::bimaps; + +// tags + +struct spanish {}; +struct english {}; + +// A dictionary is a bidirectional map from strings to strings + +typedef bimap +< + tagged< std::string,spanish >, tagged< std::string,english > + +> dictionary; + +typedef dictionary::value_type translation; + +int main() +{ + dictionary d; + + // Fill up our microdictionary. + // first members Spanish, second members English. + + d.insert( translation("hola" ,"hello" )); + d.insert( translation("adios","goodbye")); + d.insert( translation("rosa" ,"rose" )); + d.insert( translation("mesa" ,"table" )); + + std::cout << "enter a word" << std::endl; + std::string word; + std::getline(std::cin,word); + + // search the queried word on the from index (Spanish) */ + + dictionary::map_by::const_iterator it = + d.by().find(word); + + if( it != d.by().end() ) + { + std::cout << word << " is said " + << it->get() << " in English" << std::endl; + } + else + { + // word not found in Spanish, try our luck in English + + dictionary::map_by::const_iterator it2 = + d.by().find(word); + + if( it2 != d.by().end() ) + { + std::cout << word << " is said " + << it2->get() << " in Spanish" << std::endl; + } + else + { + std::cout << "No such word in the dictionary" << std::endl; + } + } + + return 0; +} +//] diff --git a/example/mighty_bimap.cpp b/example/mighty_bimap.cpp new file mode 100755 index 0000000..8641ad3 --- /dev/null +++ b/example/mighty_bimap.cpp @@ -0,0 +1,109 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- +// This is the translator example from the tutorial. +// In this example the set type of relation is changed to allow the iteration +// of the container. + +#include + +//[ code_mighty_bimap + +#include +#include +#include +#include +#include + +struct english {}; +struct spanish {}; + +int main() +{ + using namespace boost::bimaps; + + typedef bimap + < + unordered_set_of< tagged< std::string, spanish > >, + unordered_set_of< tagged< std::string, english > >, + list_of_relation + + > translator; + + translator trans; + + // We have to use `push_back` because the collection of relations is + // a `list_of_relation` + + trans.push_back( translator::value_type("hola" ,"hello" ) ); + trans.push_back( translator::value_type("adios" ,"goodbye" ) ); + trans.push_back( translator::value_type("rosa" ,"rose" ) ); + trans.push_back( translator::value_type("mesa" ,"table" ) ); + + std::cout << "enter a word" << std::endl; + std::string word; + std::getline(std::cin,word); + + // Search the queried word on the from index (Spanish) + + translator::map_by::const_iterator is + = trans.by().find(word); + + if( is != trans.by().end() ) + { + std::cout << word << " is said " + << is->get() + << " in English" << std::endl; + } + else + { + // Word not found in Spanish, try our luck in English + + translator::map_by::const_iterator ie + = trans.by().find(word); + + if( ie != trans.by().end() ) + { + std::cout << word << " is said " + << ie->get() + << " in Spanish" << std::endl; + } + else + { + // Word not found, show the possible translations + + std::cout << "No such word in the dictionary" << std::endl; + std::cout << "These are the possible translations" << std::endl; + + for( translator::const_iterator + i = trans.begin(), + i_end = trans.end(); + + i != i_end ; ++i ) + { + std::cout << i->get() + << " <---> " + << i->get() + << std::endl; + } + } + } + return 0; +} +//] diff --git a/example/population_bimap.cpp b/example/population_bimap.cpp new file mode 100755 index 0000000..84c5ecc --- /dev/null +++ b/example/population_bimap.cpp @@ -0,0 +1,121 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +using namespace boost::bimaps; +using namespace boost; +using namespace std; + +int main() +{ + { + + typedef bimap< + + string, + multiset_of< optional > + + > bm_type; + + bm_type bm; + + assign::insert( bm ) + + ( "John" , string("lazarus" ) ) + ( "Peter", string("vinicius") ) + ( "Simon", string("vinicius") ) + ( "Brian", none ) + ; + + cout << "John is working in " + << bm.left.at( "John" ).get_value_or( "no project" ) + << endl; + + cout << "Project vinicius is being developed by " << endl; + BOOST_FOREACH( bm_type::right_reference rp, + bm.right.equal_range( std::string("vinicius") ) ) + { + cout << rp.second << endl; + } + + cout << "This workers need a project " << endl; + BOOST_FOREACH( bm_type::right_reference rp, + bm.right.equal_range(none) ) + { + cout << rp.second << endl; + } + +} + + //[ code_population_bimap + + typedef bimap< + + unordered_set_of< std::string >, + multiset_of< long, std::greater > + + > population_bimap; + + typedef population_bimap::value_type population; + + population_bimap pop; + pop.insert( population("China", 1321000000) ); + pop.insert( population("India", 1129000000) ); + pop.insert( population("United States", 301950000) ); + pop.insert( population("Indonesia", 234950000) ); + pop.insert( population("Brazil", 186500000) ); + pop.insert( population("Pakistan", 163630000) ); + + std::cout << "Countries by their population:" << std::endl; + + // First requirement + /*<< The right map view works like a + `std::multimap< long, std::string, std::greater >`, + We can iterate over it to print the results in the required order. >>*/ + for( population_bimap::right_const_iterator + i = pop.right.begin(), iend = pop.right.end(); + i != iend ; ++i ) + { + std::cout << i->second << " with " << i->first << std::endl; + } + + // Second requirement + /*<< The left map view works like a `std::unordered_map< std::string, long >`, + given the name of the country we can use it to search for the population + in constant time >>*/ + std::cout << "Population of China: " << pop.left.at("China") << std::endl; + //] + + return 0; +} + diff --git a/example/projection.cpp b/example/projection.cpp new file mode 100755 index 0000000..7fa3489 --- /dev/null +++ b/example/projection.cpp @@ -0,0 +1,60 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +#include +#include +using namespace boost::bimaps; + +void years_example() +{ + //[ code_projection_years + + typedef bimap > > bm_type; + + bm_type bm; + bm.insert( bm_type::value_type("John" ,34) ); + bm.insert( bm_type::value_type("Peter",24) ); + bm.insert( bm_type::value_type("Mary" ,12) ); + + // Find the name of the next younger person after Peter + + bm_type::left_const_iterator name_iter = bm.left.find("Peter"); + + bm_type::right_const_iterator years_iter = bm.project_right(name_iter); + + ++years_iter; + + std::cout << "The next younger person after Peter is " << years_iter->second; + //] +} + +int main() +{ + years_example(); + + return 0; +} + + diff --git a/example/repetitions_counter.cpp b/example/repetitions_counter.cpp new file mode 100755 index 0000000..5d93985 --- /dev/null +++ b/example/repetitions_counter.cpp @@ -0,0 +1,91 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +#include +#include +#include + +using namespace boost::bimaps; + +struct counter { + counter() : c(0) {} + counter& operator++() { ++c; return *this; } + unsigned int operator++(int) { return c++; } + operator const unsigned int() const { return c; } + private: + unsigned int c; +}; + +int main() +{ + //[ code_repetitions_counter + + typedef bimap + < + unordered_set_of< std::string >, + list_of< counter > /*< `counter` is an integer that is initialized + in zero in the constructor >*/ + + > word_counter; + + typedef boost::tokenizer > text_tokenizer; + + std::string text= + "Relations between data in the STL are represented with maps." + "A map is a directed relation, by using it you are representing " + "a mapping. In this directed relation, the first type is related to " + "the second type but it is not true that the inverse relationship " + "holds. This is useful in a lot of situations, but there are some " + "relationships that are bidirectional by nature."; + + // feed the text into the container + word_counter wc; + text_tokenizer tok(text,boost::char_separator(" \t\n.,;:!?'\"-")); + + for( text_tokenizer::const_iterator it = tok.begin(), it_end = tok.end(); + it != it_end ; ++it ) + { + /*<< Because the right collection type is `list_of`, the right data + is not used a key and can be modified in the same way as with + standard maps. >>*/ + ++ wc.left[*it]; + } + + // list words with counters by order of appearance + /*<< When we insert the elements using the left map view, the element + is inserted at the end of the list. >>*/ + for( word_counter::right_const_iterator + wit = wc.right.begin(), wit_end = wc.right.end(); + + wit != wit_end; ++wit ) + { + std::cout << wit->second << ": " << wit->first; + } + //] + + return 0; +} + + diff --git a/example/simple_bimap.cpp b/example/simple_bimap.cpp new file mode 100755 index 0000000..28d1e72 --- /dev/null +++ b/example/simple_bimap.cpp @@ -0,0 +1,82 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +//[ code_simple_bimap + +#include +#include + +#include + +template< class MapType > +void print_map(const MapType & map, + const std::string & separator, + std::ostream & os ) +{ + typedef typename MapType::const_iterator const_iterator; + + for( const_iterator i = map.begin(), iend = map.end(); i != iend; ++i ) + { + os << i->first << separator << i->second << std::endl; + } +} + +int main() +{ + // Soccer World cup + + typedef boost::bimap< std::string, int > results_bimap; + typedef results_bimap::value_type position; + + results_bimap results; + results.insert( position("Argentina" ,1) ); + results.insert( position("Spain" ,2) ); + results.insert( position("Germany" ,3) ); + results.insert( position("France" ,4) ); + + std::cout << "The number of countries is " << results.size() + << std::endl; + + std::cout << "The winner is " << results.right.at(1) + << std::endl + << std::endl; + + std::cout << "Countries names ordered by their final position:" + << std::endl; + + // results.right works like a std::map< int, std::string > + + print_map( results.right, ") ", std::cout ); + + std::cout << std::endl + << "Countries names ordered alphabetically along with" + "their final position:" + << std::endl; + + // results.left works like a std::map< std::string, int > + + print_map( results.left, " ends in position ", std::cout ); + + return 0; +} +//] + diff --git a/example/standard_map_comparison.cpp b/example/standard_map_comparison.cpp new file mode 100755 index 0000000..4a757f5 --- /dev/null +++ b/example/standard_map_comparison.cpp @@ -0,0 +1,93 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +#include +#include + +using namespace boost::bimaps; + +//[ code_standard_map_comparison + +template< class Map, class CompatibleKey, class CompatibleData > +void use_it( Map & m, + const CompatibleKey & key, + const CompatibleData & data ) +{ + typedef typename Map::value_type value_type; + typedef typename Map::const_iterator const_iterator; + + m.insert( value_type(key,data) ); + const_iterator iter = m.find(key); + if( iter != m.end() ) + { + assert( iter->first == key ); + assert( iter->second == data ); + + std::cout << iter->first << " --> " << iter->second; + } + m.erase(key); +} + +int main() +{ + typedef bimap< set_of, set_of > bimap_type; + bimap_type bm; + + // Standard map + { + typedef std::map< std::string, int > map_type; + map_type m; + + use_it( m, "one", 1 ); + } + + // Left map view + { + typedef bimap_type::left_map map_type; + map_type & m = bm.left; + + use_it( m, "one", 1 ); + } + + // Reverse standard map + { + typedef std::map< int, std::string > reverse_map_type; + reverse_map_type rm; + + use_it( rm, 1, "one" ); + } + + // Right map view + { + typedef bimap_type::right_map reverse_map_type; + reverse_map_type & rm = bm.right; + + use_it( rm, 1, "one" ); + } + + return 0; +} +//] + diff --git a/example/step_by_step.cpp b/example/step_by_step.cpp new file mode 100755 index 0000000..bd8dd03 --- /dev/null +++ b/example/step_by_step.cpp @@ -0,0 +1,102 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +// A convinience header is avaiable in the boost directory: +#include + +int main() +{ + //[ code_step_by_step_definition + + typedef boost::bimap< int, std::string > bm_type; + bm_type bm; + //] + + //[ code_step_by_step_set_of_relations_view + + bm.insert( bm_type::value_type(1, "one" ) ); + bm.insert( bm_type::value_type(2, "two" ) ); + + std::cout << "There are " << bm.size() << "relations" << std::endl; + + for( bm_type::const_iterator iter = bm.begin(), iend = bm.end(); + iter != iend; ++iter ) + { + // iter->left : data : int + // iter->right : data : std::string + + std::cout << iter->left << " <--> " << iter->right << std::endl; + } + //] + + //[ code_step_by_step_left_map_view + + /*<< The type of `bm.left` is `bm_type::left_map` and the type + of `bm.right` is `bm_type::right_map` >>*/ + typedef bm_type::left_map::const_iterator left_const_iterator; + + for( left_const_iterator left_iter = bm.left.begin(), iend = bm.left.end(); + left_iter != iend; ++left_iter ) + { + // left_iter->first : key : int + // left_iter->second : data : std::string + + std::cout << left_iter->first << " --> " << left_iter->second << std::endl; + } + + /*<< `bm_type::left_`\ -type- can be used as a shortcut for the more verbose + `bm_type::left_map::`\ -type- >>*/ + bm_type::left_const_iterator left_iter = bm.left.find(2); + assert( left_iter->second == "two" ); + + /*<< This line produces the same effect of + `bm.insert( bm_type::value_type(3,"three") );` >>*/ + bm.left.insert( bm_type::left_value_type( 3, "three" ) ); + //] + + + + //[ code_step_by_step_right_map_view + + bm_type::right_const_iterator right_iter = bm.right.find("two"); + + // right_iter->first : key : std::string + // right_iter->second : data : int + + assert( right_iter->second == 2 ); + + assert( bm.right.at("one") == 1 ); + + bm.right.erase("two"); + + /*<< This line produces the same effect of + `bm.insert( bm_type::value_type(4,"four") );` >>*/ + bm.right.insert( bm_type::right_value_type( "four", 4 ) ); + //] + + return 0; +} +//] + diff --git a/example/tagged_simple_bimap.cpp b/example/tagged_simple_bimap.cpp new file mode 100755 index 0000000..b702bc8 --- /dev/null +++ b/example/tagged_simple_bimap.cpp @@ -0,0 +1,86 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +//[ code_tagged_simple_bimap + +#include + +#include + +struct country {}; +struct place {}; + +int main() +{ + using namespace boost::bimaps; + + // Soccer World cup. + + typedef bimap + < + tagged< std::string, country >, + tagged< int , place > + + > results_bimap; + + typedef results_bimap::value_type position; + + results_bimap results; + results.insert( position("Argentina" ,1) ); + results.insert( position("Spain" ,2) ); + results.insert( position("Germany" ,3) ); + results.insert( position("France" ,4) ); + + std::cout << "Countries names ordered by their final position:" + << std::endl; + + /*<< `results.by()` is equivalent to `results.right` >>*/ + for( results_bimap::map_by::const_iterator + i = results.by().begin(), + iend = results.by().end() ; + i != iend; ++i ) + { + /*<< `get` works for each view of the bimap >>*/ + std::cout << i->get() << ") " + << i->get() << std::endl; + } + + std::cout << std::endl + << "Countries names ordered alfabetically along with" + "their final position:" + << std::endl; + + /*<< `results.by()` is equivalent to `results.left` >>*/ + for( results_bimap::map_by::const_iterator + i = results.by().begin(), + iend = results.by().end() ; + i != iend; ++i ) + { + std::cout << i->get() << " ends " + << i->get() << "º" + << std::endl; + } + + return 0; +} +//] + diff --git a/example/tutorial_info_hook.cpp b/example/tutorial_info_hook.cpp new file mode 100755 index 0000000..92f8c74 --- /dev/null +++ b/example/tutorial_info_hook.cpp @@ -0,0 +1,163 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include + +#include +#include + +#include +#include + +using namespace boost::bimaps; + + +void tutorial_about_info_hook() +{ + //[ code_tutorial_info_hook_first + + typedef bimap< + + multiset_of< std::string >, // author + set_of< std::string >, // title + + with_info< std::string > // abstract + + > bm_type; + typedef bm_type::value_type book; + + bm_type bm; + + bm.insert( + + book( "Bjarne Stroustrup" , "The C++ Programming Language", + + "For C++ old-timers, the first edition of this book is" + "the one that started it all—the font of our knowledge." ) + ); + + + // Print the author of the bible + std::cout << bm.right.at("The C++ Programming Language"); + + // Print the abstract of this book + bm_type::left_iterator i = bm.left.find("Bjarne Stroustrup"); + std::cout << i->info; + //] + + // Contrary to the two key types, the information will be mutable + // using iterators. + + //[ code_tutorial_info_hook_mutable + + i->info += "More details about this book"; + //] + + // 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 + + // Print the new abstract + std::cout << bm.right.info_at("The C++ Programming Language"); + //] +} + +struct author {}; +struct title {}; +struct abstract {}; + +void tutorial_about_tagged_info_hook() +{ + //[ code_tutorial_info_hook_tagged_info + + typedef bimap< + + multiset_of< tagged< std::string, author > >, + set_of< tagged< std::string, title > >, + + with_info< tagged< std::string, abstract > > + + > bm_type; + typedef bm_type::value_type book; + + bm_type bm; + + bm.insert( + + book( "Bjarne Stroustrup" , "The C++ Programming Language", + + "For C++ old-timers, the first edition of this book is" + "the one that started it all—the font of our knowledge." ) + ); + + // Print the author of the bible + std::cout << bm.by().at("The C++ Programming Language"); + + // Print the abstract of this book + bm_type::map_by<author>::iterator i = bm.by<author>().find("Bjarne Stroustrup"); + std::cout << i->get<abstract>(); + + // Contrary to the two key types, the information will be mutable + // using iterators. + + i->get<abstract>() += "More details about this book"; + + // Print the new abstract + std::cout << bm.by<title>().info_at("The C++ Programming Language"); + //] +} + + +void bimap_without_an_info_hook() +{ + //[ code_tutorial_info_hook_nothing + + typedef bimap< + + multiset_of< std::string >, // author + set_of< std::string > // title + + > bm_type; + typedef bm_type::value_type book; + + bm_type bm; + + bm.insert( book( "Bjarne Stroustrup" , "The C++ Programming Language" ) ); + bm.insert( book( "Scott Meyers" , "Effective C++" ) ); + bm.insert( book( "Andrei Alexandrescu" , "Modern C++ Design" ) ); + + // Print the author of Modern C++ + std::cout << bm.right.at( "Modern C++ Design" ); + //] +} + + +int main() +{ + tutorial_about_info_hook(); + tutorial_about_tagged_info_hook(); + bimap_without_an_info_hook(); + + return 0; +} + + diff --git a/example/tutorial_modify_and_replace.cpp b/example/tutorial_modify_and_replace.cpp new file mode 100755 index 0000000..c9017cd --- /dev/null +++ b/example/tutorial_modify_and_replace.cpp @@ -0,0 +1,118 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include <boost/config.hpp> + +#include <string> +#include <iostream> + +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/support/lambda.hpp> + +using namespace boost::bimaps; + +void test_replace() +{ + //[ code_tutorial_replace + + typedef bimap< int, std::string > bm_type; + bm_type bm; + + bm.insert( bm_type::value_type(1,"one") ); + + // Replace (1,"one") with (1,"1") using the right map view + { + bm_type::right_iterator it = bm.right.find("one"); + + bool successful_replace = bm.right.replace_key( it, "1" ); + + assert( successful_replace ); + } + + bm.insert( bm_type::value_type(2,"two") ); + + // Fail to replace (1,"1") with (1,"two") using the left map view + { + assert( bm.size() == 2 ); + + bm_type::left_iterator it = bm.left.find(1); + + bool successful_replace = bm.left.replace_data( it, "two" ); + + /*<< `it` is still valid here, and the bimap was left unchanged >>*/ + assert( ! successful_replace ); + assert( bm.size() == 2 ); + } + //] +} + +void test_modify() +{ + //[ code_tutorial_modify + + typedef bimap< int, std::string > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,"one") ); + + // Modify (1,"one") to (1,"1") using the right map view + { + bm_type::right_iterator it = bm.right.find("one"); + + bool successful_modify = bm.right.modify_key( it , _key = "1" ); + + assert( successful_modify ); + } + + bm.insert( bm_type::value_type(2,"two") ); + + // Fail to modify (1,"1") to (1,"two") using the left map view + { + assert( bm.size() == 2 ); + + bm_type::left_iterator it = bm.left.find(1); + + bool successful_modify = bm.left.modify_data( it, _data = "two" ); + + /*<< `it` is not longer valid and `(1,"1")` is removed from the bimap >>*/ + assert( ! successful_modify ); + assert( bm.size() == 1 ); + } + //] + + /* + // Modify (2,"two") to (3,"two") using the set of relations view + { + bm_type::iterator it = bm.begin(); + + bool successful_modify = bm.modify( it, ++_left ); + + assert( successful_modify ); + } + */ +} + +int main() +{ + test_replace(); + test_modify(); + return 0; +} +//] + diff --git a/example/tutorial_range.cpp b/example/tutorial_range.cpp new file mode 100755 index 0000000..543ca96 --- /dev/null +++ b/example/tutorial_range.cpp @@ -0,0 +1,100 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include <boost/config.hpp> + +#include <string> +#include <iostream> + +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/support/lambda.hpp> + +using namespace boost::bimaps; + +void using_upper_and_lower_bound() +{ + //[ code_tutorial_range_standard_way + + typedef bimap<int,std::string> bm_type; + bm_type bm; + + // ... + + bm_type::left_iterator iter_first = bm.left.lower_bound(20); + bm_type::left_iterator iter_second = bm.left.upper_bound(50); + + // range [iter_first,iter_second) contains the elements in [20,50] + //] + + // Subtle changes + { + //[ code_tutorial_range_standard_way_subtle_changes + + bm_type::left_iterator iter_first = bm.left.upper_bound(20); + bm_type::left_iterator iter_second = bm.left.lower_bound(50); + + // range [iter_first,iter_second) contains the elements in (20,50) + //] + } +} + +void using_range() +{ + //[ code_tutorial_range + + typedef bimap<int,std::string> bm_type; + bm_type bm; + + // ... + + /*<< `range_type` is a handy typedef equal to `std::pair<iterator,iterator>`. + `const_range_type` is provided too, and it is equal to + `std::pair<const_iterator,const_iterator>` >>*/ + bm_type::left_range_type r; + + /*<< _key is a Boost.Lambda placeholder. To use it you have to include + `<boost/bimap/support/lambda.hpp>` >>*/ + r = bm.left.range( 20 <= _key, _key <= 50 ); // [20,50] + + r = bm.left.range( 20 < _key, _key < 50 ); // (20,50) + + r = bm.left.range( 20 <= _key, _key < 50 ); // [20,50) + //] + + //[ code_tutorial_range_unbounded + + r = bm.left.range( 20 <= _key, unbounded ); // [20,inf) + + r = bm.left.range( unbounded , _key < 50 ); // (-inf,50) + + /*<< This is equivalent to std::make_pair(s.begin(),s.end()) >>*/ + r = bm.left.range( unbounded , unbounded ); // (-inf,inf) + //] +} + +int main() +{ + using_upper_and_lower_bound(); + using_range(); + + return 0; +} + + diff --git a/example/unconstrained_collection.cpp b/example/unconstrained_collection.cpp new file mode 100755 index 0000000..5248f74 --- /dev/null +++ b/example/unconstrained_collection.cpp @@ -0,0 +1,94 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include <boost/config.hpp> + +#include <string> +#include <iostream> + +#include <map> +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/unconstrained_set_of.hpp> +#include <boost/bimap/support/lambda.hpp> + +using namespace boost::bimaps; + +int main() +{ + // Boost.Bimap + { + //[ code_unconstrained_collection_bimap + + typedef bimap< std::string, unconstrained_set_of<int> > bm_type; + typedef bm_type::left_map map_type; + + bm_type bm; + map_type & m = bm.left; + //] + + //[ code_unconstrained_collection_common + + m["one"] = 1; + + assert( m.find("one") != m.end() ); + + for( map_type::iterator i = m.begin(), iend = m.end(); i != iend; ++i ) + { + /*<< The right collection of the bimap is mutable so its elements + can be modified using iterators. >>*/ + ++(i->second); + } + + m.erase("one"); + //] + + m["one"] = 1; + m["two"] = 2; + + //[ code_unconstrained_collection_only_for_bimap + typedef map_type::const_iterator const_iterator; + typedef std::pair<const_iterator,const_iterator> const_range; + + /*<< This range is a model of BidirectionalRange, read the docs of + Boost.Range for more information. >>*/ + const_range r = m.range( "one" <= _key, _key <= "two" ); + for( const_iterator i = r.first; i != r.second; ++i ) + { + std::cout << i->first << "-->" << i->second << std::endl; + } + + m.modify_key( m.begin(), _key = "1" ); + //] + } + + // Standard map + { + //[ code_unconstrained_collection_map + + typedef std::map< std::string, int > map_type; + + map_type m; + //] + } + + return 0; +} + + diff --git a/example/user_defined_names.cpp b/example/user_defined_names.cpp new file mode 100755 index 0000000..24db784 --- /dev/null +++ b/example/user_defined_names.cpp @@ -0,0 +1,142 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +// Boost.Bimap Example +//----------------------------------------------------------------------------- + +#include <boost/config.hpp> + +#include <string> +#include <iostream> + +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/multiset_of.hpp> + +using namespace boost::bimaps; + +void untagged_version() +{ + //[ code_user_defined_names_untagged_version + + typedef bimap + < + multiset_of<std::string>, + int + + > People; + + People people; + + // ... + + int user_id; + std::cin >> user_id; + + // people.right : map<id,name> + + People::right_const_iterator id_iter = people.right.find(user_id); + if( id_iter != people.right.end() ) + { + // first : id + // second : name + + std::cout << "name: " << id_iter->second << std::endl + << "id: " << id_iter->first << std::endl; + } + else + { + std::cout << "Unknown id, users are:" << std::endl; + + // people.left : map<name,id> + + for( People::left_const_iterator + name_iter = people.left.begin(), + iend = people.left.end(); + + name_iter != iend; ++name_iter ) + { + // first : name + // second : id + + std::cout << "name: " << name_iter->first << std::endl + << "id: " << name_iter->second << std::endl; + } + } + //] +} + +struct id {}; +struct name {}; + +void tagged_version() +{ + //[ code_user_defined_names_tagged_version + + //<- + /* + //-> + struct id {}; // Tag for the identification number + struct name {}; // Tag for the name of the person + //<- + */ + //-> + + typedef bimap + < + tagged< int , id > , + multiset_of< tagged< std::string, name > > + + > People; + + People people; + + // ... + + int user_id; + std::cin >> user_id; + + People::map_by<id>::const_iterator id_iter = people.by<id>().find(user_id); + if( id_iter != people.by<id>().end() ) + { + std::cout << "name: " << id_iter->get<name>() << std::endl + << "id: " << id_iter->get<id>() << std::endl; + } + else + { + std::cout << "Unknown id, users are:" << std::endl; + + for( People::map_by<name>::const_iterator + name_iter = people.by<name>().begin(), + iend = people.by<name>().end(); + + name_iter != iend; ++name_iter ) + { + std::cout << "name: " << name_iter->get<name>() << std::endl + << "id: " << name_iter->get<id>() << std::endl; + } + } + //] +} + +int main() +{ + untagged_version(); + tagged_version(); + + return 0; +} + diff --git a/index.html b/index.html new file mode 100755 index 0000000..84be2fc --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=doc/html/index.html"> +</head> +<body> +Automatic redirection failed, please go to the +<a href="doc/html/index.html">Boost.Bimap documentation</a>. +</body> +</html> diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 new file mode 100755 index 0000000..091e875 --- /dev/null +++ b/test/Jamfile.v2 @@ -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 ] + ; diff --git a/test/compile_fail/test_bimap_info_1.cpp b/test/compile_fail/test_bimap_info_1.cpp new file mode 100755 index 0000000..e253619 --- /dev/null +++ b/test/compile_fail/test_bimap_info_1.cpp @@ -0,0 +1,49 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + + +void test_bimap_info_1() +{ + using namespace boost::bimaps; + + typedef bimap< int, list_of<int>, with_info<int> > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,1) ); + + // fail test + { + const bm_type & cbm = bm; + cbm.begin()->info = 10; + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_info_1(); + return 0; +} + diff --git a/test/compile_fail/test_bimap_info_2.cpp b/test/compile_fail/test_bimap_info_2.cpp new file mode 100755 index 0000000..339344e --- /dev/null +++ b/test/compile_fail/test_bimap_info_2.cpp @@ -0,0 +1,48 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + + +void test_bimap_info_2() +{ + using namespace boost::bimaps; + + typedef bimap< int, list_of<int> > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,1) ); + + // fail test + { + bm.begin()->info; + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_info_2(); + return 0; +} + diff --git a/test/compile_fail/test_bimap_info_3.cpp b/test/compile_fail/test_bimap_info_3.cpp new file mode 100755 index 0000000..4dea3b5 --- /dev/null +++ b/test/compile_fail/test_bimap_info_3.cpp @@ -0,0 +1,48 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + + +void test_bimap_info_3() +{ + using namespace boost::bimaps; + + typedef bimap< int, list_of<int> > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,1) ); + + // fail test + { + bm.left.info_at(1); + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_info_3(); + return 0; +} + diff --git a/test/compile_fail/test_bimap_mutable_1.cpp b/test/compile_fail/test_bimap_mutable_1.cpp new file mode 100755 index 0000000..03587e1 --- /dev/null +++ b/test/compile_fail/test_bimap_mutable_1.cpp @@ -0,0 +1,49 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + + +void test_bimap_mutable_1() +{ + using namespace boost::bimaps; + + typedef bimap< int, list_of<int> > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,1) ); + + // fail test + { + const bm_type & cbm = bm; + cbm.begin()->right = 10; + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_mutable_1(); + return 0; +} + diff --git a/test/compile_fail/test_bimap_mutable_2.cpp b/test/compile_fail/test_bimap_mutable_2.cpp new file mode 100755 index 0000000..4693423 --- /dev/null +++ b/test/compile_fail/test_bimap_mutable_2.cpp @@ -0,0 +1,49 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + + +void test_bimap_mutable_2() +{ + using namespace boost::bimaps; + + typedef bimap< int, list_of<int> > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,1) ); + + // fail test + { + const bm_type & cbm = bm; + cbm.left.find(1)->second = 10; + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_mutable_2(); + return 0; +} + diff --git a/test/compile_fail/test_bimap_mutable_3.cpp b/test/compile_fail/test_bimap_mutable_3.cpp new file mode 100755 index 0000000..8b68990 --- /dev/null +++ b/test/compile_fail/test_bimap_mutable_3.cpp @@ -0,0 +1,48 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + + +void test_bimap_mutable_3() +{ + using namespace boost::bimaps; + + typedef bimap< int, list_of<int> > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,1) ); + + // fail test + { + bm.right.begin()->second = 10; + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_mutable_3(); + return 0; +} + diff --git a/test/test_bimap.hpp b/test/test_bimap.hpp new file mode 100755 index 0000000..5f9298c --- /dev/null +++ b/test/test_bimap.hpp @@ -0,0 +1,488 @@ +// 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) + +#ifndef LIBS_BIMAP_TEST_BIMAP_TEST_HPP +#define LIBS_BIMAP_TEST_BIMAP_TEST_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> + +// std +#include <cassert> +#include <algorithm> + +#include <boost/lambda/lambda.hpp> + +template< class Container, class Data > +void test_container(Container & c, const Data & d) +{ + assert( d.size() > 2 ); + + c.clear(); + + BOOST_CHECK( c.size() == 0 ); + BOOST_CHECK( c.empty() ); + + c.insert( *d.begin() ); + + c.insert( ++d.begin(),d.end() ); + + BOOST_CHECK( c.size() == d.size() ); + + BOOST_CHECK( c.size() <= c.max_size() ); + BOOST_CHECK( ! c.empty() ); + + c.erase( c.begin() ); + + BOOST_CHECK( c.size() == d.size() - 1 ); + + c.erase( c.begin(), c.end() ); + + BOOST_CHECK( c.empty() ); + + c.insert( *d.begin() ); + + BOOST_CHECK( c.size() == 1 ); + + c.insert( c.begin(), *(++d.begin()) ); + + BOOST_CHECK( c.size() == 2 ); + + BOOST_CHECK( c.begin() != c.end() ); + +} + +template< class Container, class Data > +void test_sequence_container(Container & c, const Data & d) +{ + assert( d.size() > 2 ); + + c.clear(); + + BOOST_CHECK( c.size() == 0 ); + BOOST_CHECK( c.empty() ); + + c.push_front( * d.begin() ); + c.push_back ( *(++d.begin()) ); + + BOOST_CHECK( c.front() == * c.begin() ); + BOOST_CHECK( c.back () == *(++c.begin()) ); + + BOOST_CHECK( c.size() == 2 ); + + BOOST_CHECK( c.size() <= c.max_size() ); + BOOST_CHECK( ! c.empty() ); + + c.erase( c.begin() ); + + BOOST_CHECK( c.size() == 1 ); + + c.insert( c.begin(), *(++d.begin()) ); + + c.erase( c.begin(), c.end() ); + + BOOST_CHECK( c.empty() ); + + c.push_front( *d.begin() ); + + BOOST_CHECK( c.size() == 1 ); + + BOOST_CHECK( c.begin() != c.end() ); + +} + +template< class Container, class Data > +void test_associative_container(Container & c, const Data & d) +{ + assert( d.size() > 2 ); + + c.clear(); + c.insert(d.begin(),d.end()); + + for( typename Data::const_iterator di = d.begin(), de = d.end(); + di != de; ++di ) + { + BOOST_CHECK( c.find(*di) != c.end() ); + } + + typename Data::const_iterator da = d.begin(); + typename Data::const_iterator db = ++d.begin(); + + c.erase(*da); + + BOOST_CHECK( c.size() == d.size()-1 ); + + BOOST_CHECK( c.count(*da) == 0 ); + BOOST_CHECK( c.count(*db) == 1 ); + + BOOST_CHECK( c.find(*da) == c.end() ); + BOOST_CHECK( c.find(*db) != c.end() ); + + BOOST_CHECK( c.equal_range(*db).first != c.end() ); + + c.clear(); + + BOOST_CHECK( c.equal_range(*da).first == c.end() ); +} + + +template< class Container, class Data > +void test_pair_associative_container(Container & c, const Data & d) +{ + assert( d.size() > 2 ); + + c.clear(); + c.insert(d.begin(),d.end()); + + for( typename Data::const_iterator di = d.begin(), de = d.end(); + di != de; ++di ) + { + BOOST_CHECK( c.find(di->first) != c.end() ); + } + + typename Data::const_iterator da = d.begin(); + typename Data::const_iterator db = ++d.begin(); + + c.erase(da->first); + + BOOST_CHECK( c.size() == d.size()-1 ); + + BOOST_CHECK( c.count(da->first) == 0 ); + BOOST_CHECK( c.count(db->first) == 1 ); + + BOOST_CHECK( c.find(da->first) == c.end() ); + BOOST_CHECK( c.find(db->first) != c.end() ); + + BOOST_CHECK( c.equal_range(db->first).first != c.end() ); + + c.clear(); + + BOOST_CHECK( c.equal_range(da->first).first == c.end() ); +} + + +template< class Container, class Data > +void test_simple_ordered_associative_container_equality(Container & c, const Data & d) +{ + BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) ); + BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) ); + + BOOST_CHECK( c.lower_bound( *d.begin() ) == c.begin() ); + BOOST_CHECK( c.upper_bound( *d.begin() ) == ++c.begin() ); +} + +template< class Container, class Data > +void test_simple_ordered_associative_container(Container & c, const Data & d) +{ + assert( d.size() > 2 ); + + c.clear(); + c.insert(d.begin(),d.end()); + + for( typename Data::const_iterator di = d.begin(), de = d.end(); + di != de; ++di ) + { + typename Container::const_iterator ci = c.find(*di); + BOOST_CHECK( ci != c.end() ); + + BOOST_CHECK( ! c.key_comp()(*ci,*di) ); + BOOST_CHECK( ! c.value_comp()(*ci,*di) ); + } + + test_simple_ordered_associative_container_equality(c, d); + + const Container & cr = c; + + test_simple_ordered_associative_container_equality(cr, d); + + /* + BOOST_CHECK( c.range( *c.begin() <= ::boost::lambda::_1, + ::boost::lambda::_1 <= *(++c.begin()) ). + first == c.begin() + ); + */ +} + +template< class Container, class Data > +void test_simple_unordered_associative_container(Container & c, const Data & d) +{ + c.clear(); + c.insert( d.begin(), d.end() ); + + BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() ); + BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() ); + + for( typename Data::const_iterator di = d.begin(), de = d.end() ; + di != de ; ++di ) + { + // non const + { + typename Container::size_type nb = c.bucket(*c.find(*di)); + + BOOST_CHECK( c.begin(nb) != c.end(nb) ); + } + + // const + { + const Container & const_c = c; + + BOOST_CHECK( + const_c.bucket_size(const_c.bucket(*di)) == 1 + ); + + typename Container::size_type nb = + const_c.bucket(*const_c.find(*di)); + + BOOST_CHECK( + const_c.begin(nb) != const_c.end(nb) + ); + } + } + + + BOOST_CHECK( c.load_factor() < c.max_load_factor() ); + + c.max_load_factor(0.75); + + BOOST_CHECK( c.max_load_factor() == 0.75 ); + + c.rehash(10); +} + + +template< class Container, class Data > +void test_pair_ordered_associative_container_equality(Container & c, const Data & d) +{ + BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) ); + BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) ); + + BOOST_CHECK( c.lower_bound( d.begin()->first ) == c.begin() ); + BOOST_CHECK( c.upper_bound( d.begin()->first ) == ++c.begin() ); +} + +template< class Container, class Data > +void test_pair_ordered_associative_container(Container & c, const Data & d) +{ + assert( d.size() > 2 ); + + c.clear(); + c.insert(d.begin(),d.end()); + + for( typename Container::const_iterator ci = c.begin(), ce = c.end(); + ci != ce; ++ci ) + { + typename Data::const_iterator di = d.find(ci->first); + BOOST_CHECK( di != d.end() ); + BOOST_CHECK( ! c.key_comp()(di->first,ci->first) ); + BOOST_CHECK( ! c.value_comp()(*ci,*di) ); + } + + test_pair_ordered_associative_container_equality(c, d); + + const Container & cr = c; + + test_pair_ordered_associative_container_equality(cr, d); + + BOOST_CHECK( c.range( c.begin()->first <= ::boost::lambda::_1, + ::boost::lambda::_1 <= (++c.begin())->first ). + first == c.begin() + ); +} + + +template< class Container, class Data > +void test_pair_unordered_associative_container(Container & c, const Data & d) +{ + c.clear(); + c.insert( d.begin(), d.end() ); + + BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() ); + BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() ); + + for( typename Data::const_iterator di = d.begin(), de = d.end() ; + di != de ; ++di ) + { + // non const + { + typename Container::size_type nb = + c.bucket(c.find(di->first)->first); + + BOOST_CHECK( c.begin(nb) != c.end(nb) ); + } + + // const + { + const Container & const_c = c; + + BOOST_CHECK( const_c.bucket_size(const_c.bucket(di->first)) == 1 ); + + typename Container::size_type nb = + const_c.bucket(const_c.find(di->first)->first); + + BOOST_CHECK( const_c.begin(nb) != const_c.end(nb) ); + } + } + + + BOOST_CHECK( c.load_factor() < c.max_load_factor() ); + + c.max_load_factor(0.75); + + BOOST_CHECK( c.max_load_factor() == 0.75 ); + + c.rehash(10); +} + + +template< class Container, class Data > +void test_unique_container(Container & c, Data & d) +{ + c.clear(); + c.insert(d.begin(),d.end()); + c.insert(*d.begin()); + BOOST_CHECK( c.size() == d.size() ); +} + +template< class Container, class Data > +void test_non_unique_container(Container & c, Data & d) +{ + c.clear(); + c.insert(d.begin(),d.end()); + c.insert(*d.begin()); + BOOST_CHECK( c.size() == (d.size()+1) ); +} + + + +template< class Bimap, class Data, class LeftData, class RightData > +void test_basic_bimap( Bimap & b, + const Data & d, + const LeftData & ld, const RightData & rd) +{ + using namespace boost::bimaps; + + test_container(b,d); + + BOOST_CHECK( & b.left == & b.template by<member_at::left >() ); + BOOST_CHECK( & b.right == & b.template by<member_at::right>() ); + + test_container(b.left , ld); + test_container(b.right, rd); +} + +template< class LeftTag, class RightTag, class Bimap, class Data > +void test_tagged_bimap(Bimap & b, + const Data & d) +{ + using namespace boost::bimaps; + + BOOST_CHECK( &b.left == & b.template by<LeftTag >() ); + BOOST_CHECK( &b.right == & b.template by<RightTag>() ); + + b.clear(); + b.insert( *d.begin() ); + + BOOST_CHECK( + b.begin()->template get<LeftTag>() == + b.template by<RightTag>().begin()->template get<LeftTag>() + ); + + BOOST_CHECK( + b.begin()->template get<RightTag>() == + b.template by<LeftTag>().begin()->template get<RightTag>() + ); + + // const test + { + + const Bimap & bc = b; + + BOOST_CHECK( &bc.left == & bc.template by<LeftTag>() ); + BOOST_CHECK( &bc.right == & bc.template by<RightTag>() ); + + BOOST_CHECK( bc.begin()->template get<LeftTag>() == + bc.template by<RightTag>().begin()->template get<LeftTag>() ); + + BOOST_CHECK( bc.begin()->template get<RightTag>() == + bc.template by<LeftTag>().begin()->template get<RightTag>() ); + } +} + + +template< class Bimap, class Data, class LeftData, class RightData > +void test_set_set_bimap(Bimap & b, + const Data & d, + const LeftData & ld, const RightData & rd) +{ + using namespace boost::bimaps; + + test_basic_bimap(b,d,ld,rd); + + test_associative_container(b,d); + test_simple_ordered_associative_container(b,d); + + test_pair_associative_container(b.left, ld); + test_pair_ordered_associative_container(b.left, ld); + test_unique_container(b.left, ld); + + test_pair_associative_container(b.right, rd); + test_pair_ordered_associative_container(b.right, rd); + test_unique_container(b.right, rd); + +} + + +template< class Bimap, class Data, class LeftData, class RightData > +void test_multiset_multiset_bimap(Bimap & b, + const Data & d, + const LeftData & ld, const RightData & rd) +{ + using namespace boost::bimaps; + + test_basic_bimap(b,d,ld,rd); + test_associative_container(b,d); + test_simple_ordered_associative_container(b,d); + + test_pair_associative_container(b.left, ld); + test_pair_ordered_associative_container(b.left, ld); + test_non_unique_container(b.left, ld); + + test_pair_associative_container(b.right, rd); + test_pair_ordered_associative_container(b.right, rd); + test_non_unique_container(b.right, rd); +} + +template< class Bimap, class Data, class LeftData, class RightData > +void test_unordered_set_unordered_multiset_bimap(Bimap & b, + const Data & d, + const LeftData & ld, + const RightData & rd) +{ + using namespace boost::bimaps; + + test_basic_bimap(b,d,ld,rd); + test_associative_container(b,d); + test_simple_unordered_associative_container(b,d); + + test_pair_associative_container(b.left, ld); + test_pair_unordered_associative_container(b.left, ld); + test_unique_container(b.left, ld); + + test_pair_associative_container(b.right, rd); + test_pair_unordered_associative_container(b.right, rd); + + // Caution, this side is a non unique container, but the other side is a + // unique container so, the overall bimap is a unique one. + test_unique_container(b.right, rd); +} + +#endif // LIBS_BIMAP_TEST_BIMAP_TEST_HPP + diff --git a/test/test_bimap_assign.cpp b/test/test_bimap_assign.cpp new file mode 100755 index 0000000..2d8f372 --- /dev/null +++ b/test/test_bimap_assign.cpp @@ -0,0 +1,89 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// std +#include <sstream> +#include <algorithm> +#include <set> + +// Boost +#include <boost/assign/list_of.hpp> +#include <boost/assign/list_inserter.hpp> + +// Boost.Bimap +#include <boost/bimap/list_of.hpp> +#include <boost/bimap/unordered_multiset_of.hpp> +#include <boost/bimap/vector_of.hpp> +#include <boost/bimap/bimap.hpp> + +namespace ba = boost::assign; + + +void test_bimap_assign() +{ + using namespace boost::bimaps; + + // test + { + typedef bimap< list_of<int>, double > bm_type; + bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3); + ba::push_back( bm )(4,0.4)(5,0.5); + ba::insert( bm.right )(0.5,5)(0.6,6); + ba::push_back( bm.left )(6,0.6)(7,0.7); + } + + // test + { + typedef bimap< unordered_multiset_of<int>, vector_of<double>, + list_of_relation > bm_type; + bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3); + ba::push_front( bm )(4,0.4)(5,0.5); + ba::push_back( bm.right )(0.6,6)(0.7,7); + ba::insert( bm.left )(8,0.8)(9,0.9); + } + + // test + { + typedef bimap< int, vector_of<double>, right_based > bm_type; + bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3); + ba::push_back( bm )(4,0.4)(5,0.5); + ba::push_back( bm.right )(0.6,6)(0.7,7); + ba::insert( bm.left )(8,0.8)(9,0.9); + } + + // test + { + typedef bimap< int, vector_of<double>, set_of_relation<> > bm_type; + bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3); + ba::insert( bm )(4,0.4)(5,0.5); + ba::push_back( bm.right )(0.6,6)(0.7,7); + ba::insert( bm.left )(8,0.8)(9,0.9); + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_assign(); + return 0; +} + diff --git a/test/test_bimap_convenience_header.cpp b/test/test_bimap_convenience_header.cpp new file mode 100755 index 0000000..b6667ab --- /dev/null +++ b/test/test_bimap_convenience_header.cpp @@ -0,0 +1,38 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/bimap.hpp> + +void test_bimap_convenience_header() +{ + typedef boost::bimap< int, double > bm_type; + bm_type bm; + bm.insert( bm_type::value_type(1,0.1) ); + BOOST_CHECK( bm.right.at(0.1) == 1 ); +} + +int test_main( int, char* [] ) +{ + test_bimap_convenience_header(); + return 0; +} + diff --git a/test/test_bimap_extra.cpp b/test/test_bimap_extra.cpp new file mode 100755 index 0000000..61492c7 --- /dev/null +++ b/test/test_bimap_extra.cpp @@ -0,0 +1,89 @@ + // 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +// Boost.Bimap +#include <boost/bimap/support/lambda.hpp> +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + +// Support metafunctions +#include <boost/bimap/support/data_type_by.hpp> +#include <boost/bimap/support/key_type_by.hpp> +#include <boost/bimap/support/map_type_by.hpp> +#include <boost/bimap/support/value_type_by.hpp> +#include <boost/bimap/support/iterator_type_by.hpp> + +using namespace boost::bimaps; +using namespace boost::bimaps::support; + +typedef bimap<int, unconstrained_set_of<double> > bm_type; + + +namespace support_metafunctions_test { + + typedef boost::is_same + < + data_type_by< member_at::left , bm_type >::type, + key_type_by < member_at::right, bm_type >::type + + >::type test_metafunction_1; + BOOST_STATIC_ASSERT(test_metafunction_1::value); + + typedef boost::is_same + < + data_type_by< member_at::right, bm_type >::type, + key_type_by < member_at::left , bm_type >::type + + >::type test_metafunction_2; + BOOST_STATIC_ASSERT(test_metafunction_2::value); + + typedef boost::is_same + < + map_type_by < member_at::left , bm_type >::type::value_type, + value_type_by< member_at::left , bm_type >::type + + >::type test_metafunction_3; + BOOST_STATIC_ASSERT(test_metafunction_3::value); + +} // namespace support_metafunctions_test + +void test_bimap_extra() +{ + // extra tests + // --------------------------------------------------------------- + // This section test small things... when a group of this checks + // can be related it is moved to a separate unit test file. + + + +} + + +int test_main( int, char* [] ) +{ + test_bimap_extra(); + return 0; +} + diff --git a/test/test_bimap_info.cpp b/test/test_bimap_info.cpp new file mode 100755 index 0000000..c1ef479 --- /dev/null +++ b/test/test_bimap_info.cpp @@ -0,0 +1,126 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/config.hpp> + +#include <string> + +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/unordered_set_of.hpp> + + +int test_bimap_info() +{ + using namespace boost::bimaps; + + typedef bimap< double, unordered_set_of<int>, with_info<std::string> > bm_type; + + bm_type bm; + const bm_type & cbm = bm; + + // Insertion with info + bm .insert( bm_type:: value_type(1.1 , 1, "one" ) ); + bm.left .insert( bm_type:: left_value_type(2.2 , 2, "two" ) ); + bm.right.insert( bm_type::right_value_type( 3 , 3.3, "three" ) ); + + bm.begin()->info = "1"; + BOOST_CHECK( bm.right.find(1)->info == "1" ); + + bm.left.find(2.2)->info = "2"; + BOOST_CHECK( bm.right.find(2)->info == "2" ); + + bm.right.find(3)->info = "3"; + BOOST_CHECK( bm.right.find(3)->info == "3" ); + + // Empty info insert + bm .insert( bm_type:: value_type(4.4 , 4) ); + bm. left.insert( bm_type:: left_value_type(5.5 , 5) ); + bm.right.insert( bm_type::right_value_type( 6 , 6.6) ); + + BOOST_CHECK( bm.right.find(4)->info == "" ); + + bm.left.info_at(4.4) = "4"; + BOOST_CHECK( bm.right.info_at(4) == "4" ); + BOOST_CHECK( cbm.right.info_at(4) == "4" ); + + bm.right.info_at(5) = "5"; + BOOST_CHECK( bm.left.info_at(5.5) == "5" ); + BOOST_CHECK( cbm.left.info_at(5.5) == "5" ); + + return 0; +} + + +struct left {}; +struct right {}; +struct info {}; + +int test_tagged_bimap_info() +{ + using namespace boost::bimaps; + + typedef bimap< tagged<int,left>, + tagged<int,right>, + with_info<tagged<int,info> > > bm_type; + + bm_type bm; + const bm_type & cbm = bm; + + bm .insert( bm_type:: value_type(1,1,1) ); + bm.left .insert( bm_type:: left_value_type(2,2,2) ); + bm.right.insert( bm_type::right_value_type(3,3,3) ); + + bm.begin()->get<info>() = 10; + BOOST_CHECK( bm.right.find(1)->get<info>() == 10 ); + BOOST_CHECK( cbm.right.find(1)->get<info>() == 10 ); + + bm.left.find(2)->get<info>() = 20; + BOOST_CHECK( bm.right.find(2)->get<info>() == 20 ); + BOOST_CHECK( cbm.right.find(2)->get<info>() == 20 ); + + bm.right.find(3)->get<info>() = 30; + BOOST_CHECK( bm.right.find(3)->get<info>() == 30 ); + BOOST_CHECK( cbm.right.find(3)->get<info>() == 30 ); + + // Empty info insert + bm .insert( bm_type:: value_type(4,4) ); + bm. left.insert( bm_type:: left_value_type(5,5) ); + bm.right.insert( bm_type::right_value_type(6,6) ); + + bm.left.info_at(4) = 4; + BOOST_CHECK( bm.right.info_at(4) == 4 ); + BOOST_CHECK( cbm.right.info_at(4) == 4 ); + + bm.right.info_at(5) = 5; + BOOST_CHECK( bm.left.info_at(5) == 5 ); + BOOST_CHECK( cbm.left.info_at(5) == 5 ); + + return 0; +} + +int test_main( int, char* [] ) +{ + test_bimap_info(); + test_tagged_bimap_info(); + return 0; +} + diff --git a/test/test_bimap_lambda.cpp b/test/test_bimap_lambda.cpp new file mode 100755 index 0000000..81b1e73 --- /dev/null +++ b/test/test_bimap_lambda.cpp @@ -0,0 +1,47 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/support/lambda.hpp> +#include <boost/bimap/bimap.hpp> + +void test_bimap_lambda() +{ + using namespace boost::bimaps; + + typedef bimap<int,double> bm; + + bm b; + b.insert( bm::value_type(1,0.1) ); + + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( b.left.modify_key ( b.left.begin(), _key = 2 ) ); + BOOST_CHECK( b.left.modify_data( b.left.begin(), _data = 0.2 ) ); + BOOST_CHECK( b.left.range( _key >= 1, _key < 3 ).first == b.left.begin() ); +} + +int test_main( int, char* [] ) +{ + test_bimap_lambda(); + return 0; +} + diff --git a/test/test_bimap_list_of.cpp b/test/test_bimap_list_of.cpp new file mode 100755 index 0000000..e01569a --- /dev/null +++ b/test/test_bimap_list_of.cpp @@ -0,0 +1,32 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/bimap/list_of.hpp> + +int test_main( int, char* [] ) +{ + typedef boost::bimaps::list_of<int> set_type; + typedef boost::bimaps::list_of_relation set_type_of_relation; + + return 0; +} + diff --git a/test/test_bimap_modify.cpp b/test/test_bimap_modify.cpp new file mode 100755 index 0000000..ed0d15e --- /dev/null +++ b/test/test_bimap_modify.cpp @@ -0,0 +1,183 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/support/lambda.hpp> +#include <boost/bimap/bimap.hpp> + +struct id{}; + +void test_bimap_modify() +{ + using namespace boost::bimaps; + + typedef bimap<int,long> bm; + + bm b; + b.insert( bm::value_type(2,200) ); + + BOOST_CHECK( b.left.at(2) == 200 ); + + bool result; + + // replace + //---------------------------------------------------------------------- + + // successful replace in left map view + { + bm::left_iterator i = b.left.begin(); + + result = b.left.replace( i, bm::left_value_type(1,100) ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->first == 1 && i->second == 100 ); + BOOST_CHECK( b.left.at(1) == 100 ); + + result = b.left.replace_key( i, 2 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->first == 2 && i->second == 100 ); + BOOST_CHECK( b.left.at(2) == 100 ); + + result = b.left.replace_data( i, 200 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->first == 2 && i->second == 200 ); + BOOST_CHECK( b.left.at(2) == 200 ); + } + + // successful replace in right map view + { + bm::right_iterator i = b.right.begin(); + + result = b.right.replace( i, bm::right_value_type(100,1) ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->first == 100 && i->second == 1 ); + BOOST_CHECK( b.right.at(100) == 1 ); + + result = b.right.replace_key( i, 200 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->first == 200 && i->second == 1 ); + BOOST_CHECK( b.right.at(200) == 1 ); + + result = b.right.replace_data( i, 2 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->first == 200 && i->second == 2 ); + BOOST_CHECK( b.right.at(200) == 2 ); + } + + // successful replace in set of relations view + { + bm::iterator i = b.begin(); + + result = b.replace( i, bm::value_type(1,100) ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->left == 1 && i->right == 100 ); + BOOST_CHECK( b.left.at(1) == 100 ); + + result = b.replace_left( i, 2 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->left == 2 && i->right == 100 ); + BOOST_CHECK( b.left.at(2) == 100 ); + + result = b.replace_right( b.begin(), 200 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( i->left == 2 && i->right == 200 ); + BOOST_CHECK( b.left.at(2) == 200 ); + + } + + b.clear(); + b.insert( bm::value_type(1,100) ); + b.insert( bm::value_type(2,200) ); + + // fail to replace in left map view + { + bm::left_iterator i = b.left.begin(); + + result = b.left.replace( i, bm::left_value_type(2,100) ); + + BOOST_CHECK( ! result ); + BOOST_CHECK( b.size() == 2 ); + BOOST_CHECK( i->first == 1 && i->second == 100 ); + BOOST_CHECK( b.left.at(1) == 100 ); + BOOST_CHECK( b.left.at(2) == 200 ); + + + // Add checks for replace_key and replace_data + } + + // Add checks for fail to replace in right map view + + // Add checks for fail to replace in set of relations view + + + // modify + // ---------------------------------------------------------------------- + + b.clear(); + b.insert( bm::value_type(1,100) ); + + // successful modify in left map view + { + result = b.left.modify_key( b.left.begin(), _key = 2 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( b.left.at(2) == 100 ); + + result = b.left.modify_data( b.left.begin() , _data = 200 ); + + BOOST_CHECK( result ); + BOOST_CHECK( b.size() == 1 ); + BOOST_CHECK( b.left.at(2) == 200 ); + } + + // Add checks for successful modify in right map view + + // Add checks for fails to modify in left map view + + +} + +int test_main( int, char* [] ) +{ + test_bimap_modify(); + + return 0; +} + diff --git a/test/test_bimap_multiset_of.cpp b/test/test_bimap_multiset_of.cpp new file mode 100755 index 0000000..5b86bd6 --- /dev/null +++ b/test/test_bimap_multiset_of.cpp @@ -0,0 +1,32 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/bimap/multiset_of.hpp> + +int test_main( int, char* [] ) +{ + typedef boost::bimaps::multiset_of<int> set_type; + typedef boost::bimaps::multiset_of_relation<> set_type_of_relation; + + return 0; +} + diff --git a/test/test_bimap_mutable.cpp b/test/test_bimap_mutable.cpp new file mode 100755 index 0000000..4a04f7b --- /dev/null +++ b/test/test_bimap_mutable.cpp @@ -0,0 +1,109 @@ + // 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> +#include <boost/bimap/vector_of.hpp> +#include <boost/bimap/unconstrained_set_of.hpp> + +using namespace boost::bimaps; + +template< class BimapType > +void test_bimap_mutable() +{ + typedef BimapType bm_type; + + bm_type bm; + bm.insert( BOOST_DEDUCED_TYPENAME bm_type::value_type(1,0.1) ); + + const bm_type & cbm = bm; + + // Map Mutable Iterator test + { + + BOOST_DEDUCED_TYPENAME bm_type::left_iterator iter = bm.left.begin(); + iter->second = 0.2; + BOOST_CHECK( iter->second == bm.left.begin()->second ); + + BOOST_DEDUCED_TYPENAME bm_type::left_const_iterator citer = bm.left.begin(); + BOOST_CHECK( citer->second == bm.left.begin()->second ); + + BOOST_DEDUCED_TYPENAME bm_type::left_const_iterator cciter = cbm.left.begin(); + BOOST_CHECK( cciter->second == cbm.left.begin()->second ); + + } + + // Set Mutable Iterator test + { + + BOOST_DEDUCED_TYPENAME bm_type::iterator iter = bm.begin(); + iter->right = 0.1; + BOOST_CHECK( iter->right == bm.begin()->right ); + + BOOST_DEDUCED_TYPENAME bm_type::const_iterator citer = bm.begin(); + BOOST_CHECK( citer->right == bm.begin()->right ); + + BOOST_DEDUCED_TYPENAME bm_type::const_iterator cciter = cbm.begin(); + BOOST_CHECK( cciter->left == cbm.begin()->left ); + + } + + // Map Assignable Reference test + { + + BOOST_DEDUCED_TYPENAME bm_type::left_reference r = *bm.left.begin(); + r.second = 0.2; + BOOST_CHECK( r == *bm.left.begin() ); + + BOOST_DEDUCED_TYPENAME bm_type::left_const_reference cr = *bm.left.begin(); + BOOST_CHECK( cr == *bm.left.begin() ); + + BOOST_DEDUCED_TYPENAME bm_type::left_const_reference ccr = *cbm.left.begin(); + BOOST_CHECK( ccr == *cbm.left.begin() ); + + } + + // Set Assignable Reference test + { + + BOOST_DEDUCED_TYPENAME bm_type::reference r = *bm.begin(); + r.right = 0.1; + BOOST_CHECK( r == *bm.begin() ); + + BOOST_DEDUCED_TYPENAME bm_type::const_reference cr = *bm.begin(); + BOOST_CHECK( cr == *bm.begin() ); + + BOOST_DEDUCED_TYPENAME bm_type::const_reference ccr = *cbm.begin(); + BOOST_CHECK( ccr == *bm.begin() ); + + } +} + +int test_main( int, char* [] ) +{ + test_bimap_mutable< bimap< int, list_of<double> > >(); + test_bimap_mutable< bimap< int, vector_of<double> > >(); + test_bimap_mutable< bimap< int, unconstrained_set_of<double> > >(); + return 0; +} + diff --git a/test/test_bimap_operator_bracket.cpp b/test/test_bimap_operator_bracket.cpp new file mode 100755 index 0000000..6a39d17 --- /dev/null +++ b/test/test_bimap_operator_bracket.cpp @@ -0,0 +1,193 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/support/lambda.hpp> +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/unordered_set_of.hpp> +#include <boost/bimap/list_of.hpp> +#include <boost/bimap/vector_of.hpp> +#include <boost/bimap/unconstrained_set_of.hpp> + + +void test_bimap_operator_bracket() +{ + using namespace boost::bimaps; + + // Simple test + { + typedef bimap< int, std::string > bm; + + bm b; + b.insert( bm::value_type(0,"0") ); + b.insert( bm::value_type(1,"1") ); + b.insert( bm::value_type(2,"2") ); + b.insert( bm::value_type(3,"3") ); + + BOOST_CHECK( b.left.at(1) == "1" ); + + // Out of range test + { + bool value_not_found_test_passed = false; + b.clear(); + try + { + bool comp; + comp = b.left.at(2) < "banana"; + } + catch( std::out_of_range & ) + { + value_not_found_test_passed = true; + } + + BOOST_CHECK( value_not_found_test_passed ); + } + } + + // Mutable data test (1) + { + typedef bimap<int, list_of<std::string> > bm; + bm b; + + // Out of range test + { + bool value_not_found_test_passed = false; + b.clear(); + try + { + bool comp; + comp = b.left.at(1) < "banana"; + } + catch( std::out_of_range & ) + { + value_not_found_test_passed = true; + } + + BOOST_CHECK( value_not_found_test_passed ); + + } + + // Out of range test (const version) + { + bool value_not_found_test_passed = false; + b.clear(); + try + { + const bm & cb(b); + bool comp; + comp = cb.left.at(1) < "banana"; + } + catch( std::out_of_range & ) + { + value_not_found_test_passed = true; + } + + BOOST_CHECK( value_not_found_test_passed ); + } + + BOOST_CHECK( b.left[1] == "" ); + BOOST_CHECK( b.left.at(1) == "" ); + b.left[2] = "two"; + BOOST_CHECK( b.left.at(2) == "two" ); + b.left[2] = "<<two>>"; + BOOST_CHECK( b.left.at(2) == "<<two>>" ); + b.left.at(2) = "two"; + BOOST_CHECK( b.left.at(2) == "two" ); + + } + + // Mutable data test (2) + { + typedef bimap< vector_of<int>, unordered_set_of<std::string> > bm; + bm b; + + // Out of range test + { + bool value_not_found_test_passed = false; + b.clear(); + try + { + bool comp; + comp = b.right.at("banana") < 1; + } + catch( std::out_of_range & ) + { + value_not_found_test_passed = true; + } + BOOST_CHECK( value_not_found_test_passed ); + } + + // Out of range test (const version) + { + bool value_not_found_test_passed = false; + b.clear(); + try + { + const bm & cb(b); + bool comp; + comp = cb.right.at("banana") < 1; + } + catch( std::out_of_range & ) + { + value_not_found_test_passed = true; + } + + BOOST_CHECK( value_not_found_test_passed ); + } + + b.right["one"]; + BOOST_CHECK( b.size() == 1 ); + b.right["two"] = 2; + BOOST_CHECK( b.right.at("two") == 2 ); + b.right["two"] = -2; + BOOST_CHECK( b.right.at("two") == -2 ); + b.right.at("two") = 2; + BOOST_CHECK( b.right.at("two") == 2 ); + } + + // Mutable data test (3) + { + typedef bimap< unconstrained_set_of<int>, + unordered_set_of<std::string>, + right_based > bm; + + bm b; + + b.right["one"]; + BOOST_CHECK( b.size() == 1 ); + b.right["two"] = 2; + BOOST_CHECK( b.right.at("two") == 2 ); + b.right["two"] = -2; + BOOST_CHECK( b.right.at("two") == -2 ); + b.right.at("two") = 2; + BOOST_CHECK( b.right.at("two") == 2 ); + } + +} + +int test_main( int, char* [] ) +{ + test_bimap_operator_bracket(); + + return 0; +} + diff --git a/test/test_bimap_ordered.cpp b/test/test_bimap_ordered.cpp new file mode 100755 index 0000000..4b8fb82 --- /dev/null +++ b/test/test_bimap_ordered.cpp @@ -0,0 +1,176 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +#define BOOST_BIMAP_DISABLE_SERIALIZATION + +// Boost.Test +#include <boost/test/minimal.hpp> + +// std +#include <set> +#include <map> +#include <string> +#include <functional> + +// Set type specifications +#include <boost/bimap/set_of.hpp> +#include <boost/bimap/multiset_of.hpp> + +// bimap container +#include <boost/bimap/bimap.hpp> + +#include <libs/bimap/test/test_bimap.hpp> + +struct left_tag {}; +struct right_tag {}; + +void test_bimap() +{ + using namespace boost::bimaps; + + typedef std::map<int,double> left_data_type; + left_data_type left_data; + left_data.insert( left_data_type::value_type(1,0.1) ); + left_data.insert( left_data_type::value_type(2,0.2) ); + left_data.insert( left_data_type::value_type(3,0.3) ); + left_data.insert( left_data_type::value_type(4,0.4) ); + + typedef std::map<double,int> right_data_type; + right_data_type right_data; + right_data.insert( right_data_type::value_type(0.1,1) ); + right_data.insert( right_data_type::value_type(0.2,2) ); + right_data.insert( right_data_type::value_type(0.3,3) ); + right_data.insert( right_data_type::value_type(0.4,4) ); + + + //-------------------------------------------------------------------- + { + typedef bimap< int, double > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type(1,0.1) ); + data.insert( bm_type::value_type(2,0.2) ); + data.insert( bm_type::value_type(3,0.3) ); + data.insert( bm_type::value_type(4,0.4) ); + + bm_type bm; + test_set_set_bimap(bm,data,left_data,right_data); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap + < + multiset_of< tagged<int, left_tag > >, + multiset_of< tagged<double, right_tag > >, + multiset_of_relation< std::less< _relation > > + + > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type(1,0.1) ); + data.insert( bm_type::value_type(2,0.2) ); + data.insert( bm_type::value_type(3,0.3) ); + data.insert( bm_type::value_type(4,0.4) ); + + bm_type bm; + + test_multiset_multiset_bimap(bm,data,left_data,right_data); + test_tagged_bimap<left_tag,right_tag>(bm,data); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap<int,double,right_based> bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type(1,0.1) ); + data.insert( bm_type::value_type(2,0.2) ); + data.insert( bm_type::value_type(3,0.3) ); + data.insert( bm_type::value_type(4,0.4) ); + + bm_type bm; + + test_set_set_bimap(bm,data,left_data,right_data); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap + < + multiset_of< int, std::greater<int> >, set_of<std::string> , + multiset_of_relation< std::greater< _relation > > + + > bimap_type; + + bimap_type b1; + + b1.insert( bimap_type::value_type(1,"one") ); + + bimap_type b2( b1 ); + + BOOST_CHECK( b1 == b2 ); + BOOST_CHECK( ! ( b1 != b2 ) ); + BOOST_CHECK( b1 <= b2 ); + BOOST_CHECK( b1 >= b2 ); + BOOST_CHECK( ! ( b1 < b2 ) ); + BOOST_CHECK( ! ( b1 > b2 ) ); + + b1.insert( bimap_type::value_type(2,"two") ); + + b2 = b1; + BOOST_CHECK( b2 == b1 ); + + b1.insert( bimap_type::value_type(3,"three") ); + + b2.left = b1.left; + BOOST_CHECK( b2 == b1 ); + + b1.insert( bimap_type::value_type(4,"four") ); + + b2.right = b1.right; + BOOST_CHECK( b2 == b1 ); + + b1.clear(); + b2.swap(b1); + BOOST_CHECK( b2.empty() && !b1.empty() ); + + b1.left.swap( b2.left ); + BOOST_CHECK( b1.empty() && !b2.empty() ); + + b1.right.swap( b2.right ); + BOOST_CHECK( b2.empty() && !b1.empty() ); + } + //-------------------------------------------------------------------- + +} + + +int test_main( int, char* [] ) +{ + test_bimap(); + return 0; +} + diff --git a/test/test_bimap_project.cpp b/test/test_bimap_project.cpp new file mode 100755 index 0000000..0f7e767 --- /dev/null +++ b/test/test_bimap_project.cpp @@ -0,0 +1,143 @@ + // 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <string> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/list_of.hpp> + +using namespace boost::bimaps; + +struct left_tag {}; +struct right_tag {}; + +void test_bimap_project() +{ + typedef bimap + < + tagged< int , left_tag >, + list_of< tagged< std::string, right_tag > > + + > bm_type; + + bm_type bm; + + bm.insert( bm_type::value_type(1,"1") ); + bm.insert( bm_type::value_type(2,"2") ); + + bm_type:: iterator iter = bm.begin(); + bm_type:: left_iterator left_iter = bm.left.find(1); + bm_type::right_iterator right_iter = bm.right.begin(); + + const bm_type & cbm = bm; + + bm_type:: const_iterator citer = cbm.begin(); + bm_type:: left_const_iterator left_citer = cbm.left.find(1); + bm_type::right_const_iterator right_citer = cbm.right.begin(); + + // non const projection + + BOOST_CHECK( bm.project_up (bm.end()) == bm.end() ); + BOOST_CHECK( bm.project_left (bm.end()) == bm.left.end() ); + BOOST_CHECK( bm.project_right(bm.end()) == bm.right.end() ); + + BOOST_CHECK( bm.project_up (iter) == iter ); + BOOST_CHECK( bm.project_left (iter) == left_iter ); + BOOST_CHECK( bm.project_right(iter) == right_iter ); + + BOOST_CHECK( bm.project_up (left_iter) == iter ); + BOOST_CHECK( bm.project_left (left_iter) == left_iter ); + BOOST_CHECK( bm.project_right(left_iter) == right_iter ); + + BOOST_CHECK( bm.project_up (right_iter) == iter ); + BOOST_CHECK( bm.project_left (right_iter) == left_iter ); + BOOST_CHECK( bm.project_right(right_iter) == right_iter ); + + bm.project_up ( left_iter)->right = "u"; + bm.project_left (right_iter)->second = "l"; + bm.project_right( iter)->first = "r"; + + // const projection + + BOOST_CHECK( cbm.project_up (cbm.end()) == cbm.end() ); + BOOST_CHECK( cbm.project_left (cbm.end()) == cbm.left.end() ); + BOOST_CHECK( cbm.project_right(cbm.end()) == cbm.right.end() ); + + BOOST_CHECK( cbm.project_up (citer) == citer ); + BOOST_CHECK( cbm.project_left (citer) == left_citer ); + BOOST_CHECK( cbm.project_right(citer) == right_citer ); + + BOOST_CHECK( cbm.project_up (left_citer) == citer ); + BOOST_CHECK( cbm.project_left (left_citer) == left_citer ); + BOOST_CHECK( cbm.project_right(left_citer) == right_citer ); + + BOOST_CHECK( cbm.project_up (right_citer) == citer ); + BOOST_CHECK( cbm.project_left (right_citer) == left_citer ); + BOOST_CHECK( cbm.project_right(right_citer) == right_citer ); + + // mixed projection + + BOOST_CHECK( bm.project_up (left_citer) == iter ); + BOOST_CHECK( bm.project_left (left_citer) == left_iter ); + BOOST_CHECK( bm.project_right(left_citer) == right_iter ); + + BOOST_CHECK( cbm.project_up (right_iter) == citer ); + BOOST_CHECK( cbm.project_left (right_iter) == left_citer ); + BOOST_CHECK( cbm.project_right(right_iter) == right_citer ); + + bm.project_up ( left_citer)->right = "u"; + bm.project_left (right_citer)->second = "l"; + bm.project_right( citer)->first = "r"; + + // Support for tags + + BOOST_CHECK( bm.project< left_tag>(iter) == left_iter ); + BOOST_CHECK( bm.project<right_tag>(iter) == right_iter ); + + BOOST_CHECK( bm.project< left_tag>(left_iter) == left_iter ); + BOOST_CHECK( bm.project<right_tag>(left_iter) == right_iter ); + + BOOST_CHECK( bm.project< left_tag>(right_iter) == left_iter ); + BOOST_CHECK( bm.project<right_tag>(right_iter) == right_iter ); + + BOOST_CHECK( cbm.project< left_tag>(citer) == left_citer ); + BOOST_CHECK( cbm.project<right_tag>(citer) == right_citer ); + + BOOST_CHECK( cbm.project< left_tag>(left_citer) == left_citer ); + BOOST_CHECK( cbm.project<right_tag>(left_citer) == right_citer ); + + BOOST_CHECK( cbm.project< left_tag>(right_citer) == left_citer ); + BOOST_CHECK( cbm.project<right_tag>(right_citer) == right_citer ); + + bm.project< left_tag>(right_citer)->second = "l"; + bm.project<right_tag>( left_citer)->first = "r"; + +} + + +int test_main( int, char* [] ) +{ + test_bimap_project(); + return 0; +} + diff --git a/test/test_bimap_property_map.cpp b/test/test_bimap_property_map.cpp new file mode 100755 index 0000000..9a2b422 --- /dev/null +++ b/test/test_bimap_property_map.cpp @@ -0,0 +1,76 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// std +#include <set> +#include <map> +#include <cstddef> +#include <cassert> +#include <algorithm> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap + +#include <boost/bimap/set_of.hpp> +#include <boost/bimap/property_map/set_support.hpp> + +#include <boost/bimap/unordered_set_of.hpp> +#include <boost/bimap/property_map/unordered_set_support.hpp> + +#include <boost/bimap/bimap.hpp> + + +template <class Map> +void test_readable_property_map( + Map m, + typename boost::property_traits<Map>:: key_type const & key, + typename boost::property_traits<Map>::value_type const & value +) +{ + // TODO Add STATIC_ASSERT( + // boost::property_traits<Map>::category is readable ) + + BOOST_CHECK( get(m,key) == value ); + //BOOST_CHECK( m[key] == value ); +} + + +void test_bimap_property_map() +{ + using namespace boost::bimaps; + + typedef bimap< set_of<int>, unordered_set_of<double> > bm; + + bm b; + b.insert( bm::value_type(1,0.1) ); + b.insert( bm::value_type(2,0.2) ); + b.insert( bm::value_type(3,0.3) ); + + test_readable_property_map(b.left , 1,0.1); + test_readable_property_map(b.right,0.1, 1); +} + +int test_main( int, char* [] ) +{ + test_bimap_property_map(); + return 0; +} + diff --git a/test/test_bimap_range.cpp b/test/test_bimap_range.cpp new file mode 100755 index 0000000..d005cd8 --- /dev/null +++ b/test/test_bimap_range.cpp @@ -0,0 +1,134 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/config.hpp> + +#include <algorithm> + +#include <boost/range/functions.hpp> +#include <boost/range/metafunctions.hpp> + +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/multiset_of.hpp> +#include <boost/bimap/support/lambda.hpp> + + +template< class ForwardReadableRange, class UnaryFunctor > +UnaryFunctor for_each(const ForwardReadableRange & r, UnaryFunctor func) +{ + typedef typename + boost::range_const_iterator<ForwardReadableRange>::type const_iterator; + + for(const_iterator i= boost::begin(r), iend= boost::end(r); i!=iend; ++i ) + { + func(*i); + } + + return func; +} + +struct do_something_with_a_pair +{ + template< class Pair > + void operator()(const Pair & p) + { + BOOST_CHECK( p.first && p.second ); + } +}; + +int test_bimap_range() +{ + using namespace boost::bimaps; + + typedef bimap< double, multiset_of<int> > bm_type; + + + bm_type bm; + bm.insert( bm_type::value_type(1.1 , 1) ); + bm.insert( bm_type::value_type(2.2 , 2) ); + bm.insert( bm_type::value_type(3.3 , 3) ); + bm.insert( bm_type::value_type(4.4 , 4) ); + + + for_each( bm.left.range( 1.0 < _key, _key < 5.0 ), + do_something_with_a_pair() ); + + for_each( bm.right.range( unbounded, _key <= 2 ), + do_something_with_a_pair() ); + + + // left range + { + + bm_type::left_range_type r = bm.left.range( 2.0 < _key, _key < 4.0 ); + BOOST_CHECK( ! boost::empty(r) ); + BOOST_CHECK( boost::begin(r) == bm.left.upper_bound(2.0) ); + BOOST_CHECK( boost::end(r) == bm.left.lower_bound(4.0) ); + + } + + // right range + { + + bm_type::right_range_type r = bm.right.range( 2 <= _key, _key <= 3 ); + BOOST_CHECK( ! boost::empty(r) ); + BOOST_CHECK( boost::begin(r) == bm.right.lower_bound(2) ); + BOOST_CHECK( boost::end(r) == bm.right.upper_bound(3) ); + + } + + // const range from range + { + + bm_type:: left_const_range_type lr = bm. left.range( unbounded, _key < 4.0 ); + bm_type::right_const_range_type rr = bm.right.range( 2 < _key , unbounded ); + + } + + const bm_type & cbm = bm; + + // left const range + { + bm_type:: left_const_range_type r = cbm.left.range( unbounded, unbounded ); + BOOST_CHECK( ! boost::empty(r) ); + BOOST_CHECK( boost::begin(r) == cbm.left.begin() ); + + } + + // right const range + { + + bm_type::right_const_range_type r = cbm.right.range( 1 < _key, _key < 1 ); + BOOST_CHECK( boost::empty(r) ); + + } + + return 0; +} +//] + +int test_main( int, char* [] ) +{ + test_bimap_range(); + return 0; +} + diff --git a/test/test_bimap_sequenced.cpp b/test/test_bimap_sequenced.cpp new file mode 100755 index 0000000..ad4c46f --- /dev/null +++ b/test/test_bimap_sequenced.cpp @@ -0,0 +1,297 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +#define BOOST_BIMAP_DISABLE_SERIALIZATION + +// Boost.Test +#include <boost/test/minimal.hpp> + +// std +#include <set> +#include <map> +#include <algorithm> +#include <string> +#include <functional> + + +// Set type specifications +#include <boost/bimap/list_of.hpp> +#include <boost/bimap/vector_of.hpp> + +// bimap container +#include <boost/bimap/bimap.hpp> +#include <boost/bimap/support/lambda.hpp> + +#include <libs/bimap/test/test_bimap.hpp> + +struct left_tag {}; +struct right_tag {}; + +void test_bimap() +{ + using namespace boost::bimaps; + + typedef std::map<std::string,long> left_data_type; + left_data_type left_data; + left_data.insert( left_data_type::value_type("1",1) ); + left_data.insert( left_data_type::value_type("2",2) ); + left_data.insert( left_data_type::value_type("3",3) ); + left_data.insert( left_data_type::value_type("4",4) ); + + typedef std::map<long,std::string> right_data_type; + right_data_type right_data; + right_data.insert( right_data_type::value_type(1,"1") ); + right_data.insert( right_data_type::value_type(2,"2") ); + right_data.insert( right_data_type::value_type(3,"3") ); + right_data.insert( right_data_type::value_type(4,"4") ); + + + //-------------------------------------------------------------------- + { + typedef bimap< + list_of< std::string >, vector_of< long > + + > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type("1",1) ); + data.insert( bm_type::value_type("2",2) ); + data.insert( bm_type::value_type("3",3) ); + data.insert( bm_type::value_type("4",4) ); + + bm_type b; + + test_sequence_container(b,data); + test_sequence_container(b.left , left_data); + test_sequence_container(b.right,right_data); + + bm_type c; + + // Test assign + + b.clear(); + BOOST_CHECK( b.empty() ); + + b.left.assign(left_data.begin(),left_data.end()); + BOOST_CHECK( b.size() == left_data.size() ); + + b.right.assign(right_data.begin(),right_data.end()); + BOOST_CHECK( b.size() == right_data.size() ); + + b.assign(data.begin(),data.end()); + BOOST_CHECK( b.size() == data.size() ); + + // Test splice and merge + + b.clear(); + + c.left.insert(c.left.begin(),left_data.begin(),left_data.end()); + b.left.splice(b.left.begin(),c.left); + + BOOST_CHECK( c.size() == 0 ); + BOOST_CHECK( b.size() == 4 ); + + c.left.splice(c.left.begin(),b.left,++b.left.begin()); + + BOOST_CHECK( c.size() == 1 ); + + c.splice(c.begin(),b,b.begin(),b.end()); + + BOOST_CHECK( b.size() == 0 ); + + b.left.merge(c.left); + c.left.merge(b.left,std::less<std::string>()); + + b.left.sort(); + b.left.sort(std::less<std::string>()); + + b.left.unique(); + b.left.unique(std::equal_to<std::string>()); + + b.assign( data.begin(), data.end() ); + + BOOST_CHECK( std::equal( b.begin(), b.end(), data.begin() ) ); + b.reverse(); + BOOST_CHECK( std::equal( b.rbegin(), b.rend(), data.begin() ) ); + + b.sort(); + + BOOST_CHECK( std::equal( b.begin(), b.end(), data.begin() ) ); + + b.push_back( bm_type::value_type("4",4) ); + BOOST_CHECK( b.size() == 5 ); + b.unique(); + BOOST_CHECK( b.size() == 4 ); + b.remove_if( _key < bm_type::value_type("2",2) ); + BOOST_CHECK( b.size() == 3 ); + + b.merge(c); + + b.left.remove_if( _key < "3" ); + + // Test splice and merge + + b.clear(); c.clear(); + + c.left.insert(c.left.begin(),left_data.begin(),left_data.end()); + b.right.splice(b.right.begin(),c.right); + + BOOST_CHECK( c.size() == 0 ); + BOOST_CHECK( b.size() == 4 ); + + c.right.splice(c.right.begin(),b.right,++b.right.begin()); + + b.right.merge(c.right); + c.right.merge(b.right,std::less<long>()); + + b.right.sort(); + b.right.sort(std::less<long>()); + + b.right.unique(); + b.right.unique(std::equal_to<long>()); + + b.right.remove_if( _key < 3 ); + + b.clear(); + b.left.insert(b.left.begin(),left_data.begin(),left_data.end()); + + b.left.relocate(b.left.begin(), ++b.left.begin() ); + b.left.relocate(b.left.end(), b.left.begin(), ++b.left.begin() ); + + b.right.relocate(b.right.begin(), ++b.right.begin() ); + b.right.relocate(b.right.end(), b.right.begin(), ++b.right.begin() ); + + b.relocate(b.begin(), ++b.begin() ); + b.relocate(b.end(), b.begin(), ++b.begin() ); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap + < + list_of<std::string>, list_of<long>, + vector_of_relation + + > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type("1",1) ); + data.insert( bm_type::value_type("2",2) ); + data.insert( bm_type::value_type("3",3) ); + data.insert( bm_type::value_type("4",4) ); + + bm_type b; + b.push_back( bm_type::value_type("1",1) ); + b.push_back( bm_type::value_type("2",2) ); + b.push_back( bm_type::value_type("3",3) ); + b.push_back( bm_type::value_type("4",4) ); + + BOOST_CHECK( std::equal( b.begin(), b.end(), data.begin() ) ); + b.reverse(); + BOOST_CHECK( std::equal( b.rbegin(), b.rend(), data.begin() ) ); + + b.sort(); + + BOOST_CHECK( std::equal( b.begin(), b.end(), data.begin() ) ); + + b.push_back( bm_type::value_type("4",4) ); + BOOST_CHECK( b.size() == 5 ); + b.unique(); + BOOST_CHECK( b.size() == 4 ); + b.remove_if( _key < bm_type::value_type("2",2) ); + BOOST_CHECK( b.size() == 3 ); + + b.relocate( b.begin(), ++b.begin() ); + b.relocate( b.end(), b.begin(), ++b.begin() ); + + b.clear(); + BOOST_CHECK( b.empty() ); + + b.left.assign(left_data.begin(),left_data.end()); + BOOST_CHECK( b.size() == left_data.size() ); + + b.right.assign(right_data.begin(),right_data.end()); + BOOST_CHECK( b.size() == right_data.size() ); + + b.assign(data.begin(),data.end()); + BOOST_CHECK( b.size() == data.size() ); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap + < + vector_of< short >, list_of< short >, + vector_of_relation + + > bimap_type; + + bimap_type b1; + + b1.push_back( bimap_type::value_type(1,2) ); + + bimap_type b2( b1 ); + + BOOST_CHECK( b1 == b2 ); + BOOST_CHECK( ! ( b1 != b2 ) ); + BOOST_CHECK( b1 <= b2 ); + BOOST_CHECK( b1 >= b2 ); + BOOST_CHECK( ! ( b1 < b2 ) ); + BOOST_CHECK( ! ( b1 > b2 ) ); + + b1.push_back( bimap_type::value_type(2,3) ); + + b2 = b1; + BOOST_CHECK( b2 == b1 ); + + b1.push_back( bimap_type::value_type(3,4) ); + + b2.left = b1.left; + BOOST_CHECK( b2 == b1 ); + + b1.push_back( bimap_type::value_type(4,5) ); + + b2.right = b1.right; + BOOST_CHECK( b2 == b1 ); + + b1.clear(); + b2.swap(b1); + BOOST_CHECK( b2.empty() && !b1.empty() ); + + b1.left.swap( b2.left ); + BOOST_CHECK( b1.empty() && !b2.empty() ); + + b1.right.swap( b2.right ); + BOOST_CHECK( b2.empty() && !b1.empty() ); + } + //-------------------------------------------------------------------- + +} + + +int test_main( int, char* [] ) +{ + test_bimap(); + return 0; +} + diff --git a/test/test_bimap_serialization.cpp b/test/test_bimap_serialization.cpp new file mode 100755 index 0000000..dafa6e4 --- /dev/null +++ b/test/test_bimap_serialization.cpp @@ -0,0 +1,114 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// std +#include <set> +#include <map> +#include <cstddef> +#include <cassert> +#include <algorithm> +#include <sstream> +#include <algorithm> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost +#include <boost/archive/text_oarchive.hpp> +#include <boost/archive/text_iarchive.hpp> + +// Boost.Bimap +#include <boost/bimap/bimap.hpp> + + +template< class Bimap, class Archive > +void save_bimap(const Bimap & b, Archive & ar) +{ + using namespace boost::bimaps; + + ar << b; + + const typename Bimap::left_const_iterator left_iter = b.left.begin(); + ar << left_iter; + + const typename Bimap::const_iterator iter = ++b.begin(); + ar << iter; +} + + + + +void test_bimap_serialization() +{ + using namespace boost::bimaps; + + typedef bimap<int,double> bm; + + std::set< bm::value_type > data; + data.insert( bm::value_type(1,0.1) ); + data.insert( bm::value_type(2,0.2) ); + data.insert( bm::value_type(3,0.3) ); + data.insert( bm::value_type(4,0.4) ); + + std::ostringstream oss; + + // Save it + { + bm b; + + b.insert(data.begin(),data.end()); + + boost::archive::text_oarchive oa(oss); + + save_bimap(b,oa); + } + + // Reload it + { + bm b; + + std::istringstream iss(oss.str()); + boost::archive::text_iarchive ia(iss); + + ia >> b; + + BOOST_CHECK( std::equal( b.begin(), b.end(), data.begin() ) ); + + bm::left_const_iterator left_iter; + + ia >> left_iter; + + BOOST_CHECK( left_iter == b.left.begin() ); + + bm::const_iterator iter; + + ia >> iter; + + BOOST_CHECK( iter == ++b.begin() ); + } + +} + + +int test_main( int, char* [] ) +{ + test_bimap_serialization(); + return 0; +} + diff --git a/test/test_bimap_set_of.cpp b/test/test_bimap_set_of.cpp new file mode 100755 index 0000000..c51eef8 --- /dev/null +++ b/test/test_bimap_set_of.cpp @@ -0,0 +1,32 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/bimap/set_of.hpp> + +int test_main( int, char* [] ) +{ + typedef boost::bimaps::set_of<int> set_type; + typedef boost::bimaps::set_of_relation<> set_type_of_relation; + + return 0; +} + diff --git a/test/test_bimap_unconstrained.cpp b/test/test_bimap_unconstrained.cpp new file mode 100755 index 0000000..fd086d9 --- /dev/null +++ b/test/test_bimap_unconstrained.cpp @@ -0,0 +1,109 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.Bimap +#include <boost/bimap/support/lambda.hpp> +#include <boost/bimap/bimap.hpp> + + +void test_bimap_unconstrained() +{ + using namespace boost::bimaps; + + { + typedef bimap<int,double,unconstrained_set_of_relation> bm; + bm b; + b.left.insert( bm::left_value_type(2,34.4) ); + b.right.insert( bm::right_value_type(2.2,3) ); + } + + { + typedef bimap<int,unconstrained_set_of<double> > bm; + bm b; + b.insert( bm::value_type(2,34.4) ); + BOOST_CHECK( b.size() == 1 ); + } + + { + typedef bimap<unconstrained_set_of<int>, double > bm; + bm b; + b.right[2.4] = 34; + BOOST_CHECK( b.right.size() == 1 ); + } + + { + typedef bimap<unconstrained_set_of<int>, double, right_based > bm; + bm b; + b.right[2.4] = 34; + BOOST_CHECK( b.right.size() == 1 ); + } + + { + typedef bimap + < + int, + unconstrained_set_of<double>, + unconstrained_set_of_relation + + > bm; + + bm b; + b.left[2] = 34.4; + BOOST_CHECK( b.left.size() == 1 ); + } + + { + typedef bimap + < + unconstrained_set_of<int>, + double, + unconstrained_set_of_relation + + > bm; + + bm b; + b.right[2.4] = 34; + BOOST_CHECK( b.right.size() == 1 ); + } + + { + typedef bimap + < + unconstrained_set_of<int>, + unconstrained_set_of<double>, + set_of_relation<> + + > bm; + + bm b; + b.insert( bm::value_type(1,2.3) ); + BOOST_CHECK( b.size() == 1 ); + } +} + + +int test_main( int, char* [] ) +{ + test_bimap_unconstrained(); + return 0; +} + diff --git a/test/test_bimap_unordered.cpp b/test/test_bimap_unordered.cpp new file mode 100755 index 0000000..6cba88b --- /dev/null +++ b/test/test_bimap_unordered.cpp @@ -0,0 +1,167 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +#define BOOST_BIMAP_DISABLE_SERIALIZATION + +// Boost.Test +#include <boost/test/minimal.hpp> + +// std +#include <set> +#include <map> +#include <string> +#include <functional> + +// Set type specifications +#include <boost/bimap/unordered_set_of.hpp> +#include <boost/bimap/unordered_multiset_of.hpp> + +// bimap container +#include <boost/bimap/bimap.hpp> + +#include <libs/bimap/test/test_bimap.hpp> + +struct left_tag {}; +struct right_tag {}; + +void test_bimap() +{ + using namespace boost::bimaps; + + + typedef std::map<char,std::string> left_data_type; + left_data_type left_data; + left_data.insert( left_data_type::value_type('a',"a") ); + left_data.insert( left_data_type::value_type('b',"b") ); + left_data.insert( left_data_type::value_type('c',"c") ); + left_data.insert( left_data_type::value_type('d',"e") ); + + typedef std::map<std::string,char> right_data_type; + right_data_type right_data; + right_data.insert( right_data_type::value_type("a",'a') ); + right_data.insert( right_data_type::value_type("b",'b') ); + right_data.insert( right_data_type::value_type("c",'c') ); + right_data.insert( right_data_type::value_type("d",'e') ); + + + + //-------------------------------------------------------------------- + { + typedef bimap< + unordered_set_of<char>, unordered_multiset_of<std::string> + + > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type('a',"a") ); + data.insert( bm_type::value_type('b',"b") ); + data.insert( bm_type::value_type('c',"c") ); + data.insert( bm_type::value_type('d',"d") ); + + bm_type bm; + + test_unordered_set_unordered_multiset_bimap( + bm,data,left_data,right_data + ); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap< + unordered_set_of< tagged< char , left_tag > >, + unordered_multiset_of< tagged< std::string, right_tag > > + + > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type('a',"a") ); + data.insert( bm_type::value_type('b',"b") ); + data.insert( bm_type::value_type('c',"c") ); + data.insert( bm_type::value_type('d',"d") ); + + bm_type bm; + + test_unordered_set_unordered_multiset_bimap( + bm,data,left_data,right_data + ); + test_tagged_bimap<left_tag,right_tag>(bm,data); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap + < + set_of< char, std::greater<char> >, + unordered_multiset_of<std::string>, + unordered_set_of_relation<> + + > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type('a',"a") ); + data.insert( bm_type::value_type('b',"b") ); + data.insert( bm_type::value_type('c',"c") ); + data.insert( bm_type::value_type('d',"d") ); + + bm_type bm; + + test_basic_bimap(bm,data,left_data,right_data); + test_associative_container(bm,data); + test_simple_unordered_associative_container(bm,data); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + { + typedef bimap + < + unordered_multiset_of< char >, + unordered_multiset_of< std::string >, + unordered_multiset_of_relation<> + + > bm_type; + + std::set< bm_type::value_type > data; + data.insert( bm_type::value_type('a',"a") ); + data.insert( bm_type::value_type('b',"b") ); + data.insert( bm_type::value_type('c',"c") ); + data.insert( bm_type::value_type('d',"d") ); + + bm_type bm; + + test_basic_bimap(bm,data,left_data,right_data); + test_associative_container(bm,data); + test_simple_unordered_associative_container(bm,data); + + } + //-------------------------------------------------------------------- +} + + +int test_main( int, char* [] ) +{ + test_bimap(); + return 0; +} + diff --git a/test/test_bimap_unordered_multiset_of.cpp b/test/test_bimap_unordered_multiset_of.cpp new file mode 100755 index 0000000..27a0764 --- /dev/null +++ b/test/test_bimap_unordered_multiset_of.cpp @@ -0,0 +1,34 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/bimap/unordered_multiset_of.hpp> + +int test_main( int, char* [] ) +{ + typedef boost::bimaps::unordered_multiset_of<int> set_type; + + typedef boost::bimaps:: + unordered_multiset_of_relation<> set_type_of_relation; + + return 0; +} + diff --git a/test/test_bimap_unordered_set_of.cpp b/test/test_bimap_unordered_set_of.cpp new file mode 100755 index 0000000..f3aafe8 --- /dev/null +++ b/test/test_bimap_unordered_set_of.cpp @@ -0,0 +1,32 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/bimap/unordered_set_of.hpp> + +int test_main( int, char* [] ) +{ + typedef boost::bimaps::unordered_set_of<int> set_type; + typedef boost::bimaps::unordered_set_of_relation<> set_type_of_relation; + + return 0; +} + diff --git a/test/test_bimap_vector_of.cpp b/test/test_bimap_vector_of.cpp new file mode 100755 index 0000000..01da850 --- /dev/null +++ b/test/test_bimap_vector_of.cpp @@ -0,0 +1,32 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/bimap/vector_of.hpp> + +int test_main( int, char* [] ) +{ + typedef boost::bimaps::vector_of<int> set_type; + typedef boost::bimaps::vector_of_relation set_type_of_relation; + + return 0; +} + diff --git a/test/test_mutant.cpp b/test/test_mutant.cpp new file mode 100755 index 0000000..f422d57 --- /dev/null +++ b/test/test_mutant.cpp @@ -0,0 +1,103 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.MPL +#include <boost/mpl/list.hpp> +#include <boost/type_traits/is_same.hpp> + +// Boost.Bimap +#include <boost/bimap/relation/detail/mutant.hpp> + +using namespace boost::bimaps::relation::detail; + +// The mutant idiom is standard if only POD types are used. + +typedef double type_a; +typedef int type_b; + +const type_a value_a = 1.4; +const type_b value_b = 3; + +struct Data +{ + type_a a; + type_b b; +}; + +struct StdPairView +{ + typedef type_a first_type; + typedef type_b second_type; + type_a first; + type_b second; +}; + +struct ReverseStdPairView +{ + typedef type_a second_type; + typedef type_b first_type; + type_a second; + type_b first; +}; + + +struct MutantData +{ + typedef boost::mpl::list< StdPairView, ReverseStdPairView > mutant_views; + + MutantData(type_a ap, type_b bp) : a(ap), b(bp) {} + type_a a; + type_b b; +}; + + +void test_mutant_basic() +{ + + // mutant test + { + MutantData m(value_a,value_b); + + BOOST_CHECK( sizeof( MutantData ) == sizeof( StdPairView ) ); + + BOOST_CHECK( mutate<StdPairView>(m).first == value_a ); + BOOST_CHECK( mutate<StdPairView>(m).second == value_b ); + BOOST_CHECK( mutate<ReverseStdPairView>(m).first == value_b ); + BOOST_CHECK( mutate<ReverseStdPairView>(m).second == value_a ); + + ReverseStdPairView & rpair = mutate<ReverseStdPairView>(m); + rpair.first = value_b; + rpair.second = value_a; + + BOOST_CHECK( mutate<StdPairView>(m).first == value_a ); + BOOST_CHECK( mutate<StdPairView>(m).second == value_b ); + + BOOST_CHECK( &mutate<StdPairView>(m).first == &m.a ); + BOOST_CHECK( &mutate<StdPairView>(m).second == &m.b ); + } +} + +int test_main( int, char* [] ) +{ + test_mutant_basic(); + return 0; +} diff --git a/test/test_mutant_relation.cpp b/test/test_mutant_relation.cpp new file mode 100755 index 0000000..8e7c8f8 --- /dev/null +++ b/test/test_mutant_relation.cpp @@ -0,0 +1,241 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// std +#include <string> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.MPL +#include <boost/mpl/assert.hpp> +#include <boost/type_traits/is_same.hpp> + +// Boost.Bimap +#include <boost/bimap/detail/test/check_metadata.hpp> +#include <boost/bimap/tags/tagged.hpp> + +// Boost.Bimap.Relation +#include <boost/bimap/relation/mutant_relation.hpp> +#include <boost/bimap/relation/member_at.hpp> +#include <boost/bimap/relation/support/get.hpp> +#include <boost/bimap/relation/support/pair_by.hpp> +#include <boost/bimap/relation/support/pair_type_by.hpp> +#include <boost/bimap/relation/support/value_type_of.hpp> +#include <boost/bimap/relation/support/member_with_tag.hpp> +#include <boost/bimap/relation/support/is_tag_of_member_at.hpp> + +// Bimap Test Utilities +#include "test_relation.hpp" + +BOOST_BIMAP_TEST_STATIC_FUNCTION( untagged_static_test ) +{ + using namespace boost::bimaps::relation::member_at; + using namespace boost::bimaps::relation; + using namespace boost::bimaps::tags; + + struct left_data {}; + struct right_data {}; + + typedef mutant_relation< left_data, right_data > rel; + + BOOST_BIMAP_CHECK_METADATA(rel,left_value_type ,left_data); + BOOST_BIMAP_CHECK_METADATA(rel,right_value_type,right_data); + + BOOST_BIMAP_CHECK_METADATA(rel,left_tag ,left ); + BOOST_BIMAP_CHECK_METADATA(rel,right_tag,right); + + typedef tagged<left_data ,left > desired_tagged_left_type; + BOOST_BIMAP_CHECK_METADATA(rel,tagged_left_type,desired_tagged_left_type); + + typedef tagged<right_data,right> desired_tagged_right_type; + BOOST_BIMAP_CHECK_METADATA(rel,tagged_right_type,desired_tagged_right_type); + +} + +BOOST_BIMAP_TEST_STATIC_FUNCTION( tagged_static_test) +{ + using namespace boost::bimaps::relation::member_at; + using namespace boost::bimaps::relation; + using namespace boost::bimaps::tags; + + struct left_data {}; + struct right_data {}; + + struct left_tag {}; + struct right_tag {}; + + typedef mutant_relation< + tagged<left_data,left_tag>, tagged<right_data,right_tag> > rel; + + BOOST_BIMAP_CHECK_METADATA(rel,left_value_type ,left_data); + BOOST_BIMAP_CHECK_METADATA(rel,right_value_type,right_data); + + BOOST_BIMAP_CHECK_METADATA(rel,left_tag ,left_tag ); + BOOST_BIMAP_CHECK_METADATA(rel,right_tag,right_tag ); + + typedef tagged<left_data ,left_tag > desired_tagged_left_type; + BOOST_BIMAP_CHECK_METADATA(rel,tagged_left_type,desired_tagged_left_type); + + typedef tagged<right_data,right_tag> desired_tagged_right_type; + BOOST_BIMAP_CHECK_METADATA(rel,tagged_right_type,desired_tagged_right_type); +} + +struct mutant_relation_builder +{ + template< class LeftType, class RightType > + struct build + { + typedef boost::bimaps::relation:: + mutant_relation<LeftType,RightType,::boost::mpl::na,true> type; + }; +}; + +// Complex classes + +class cc1 +{ + public: + cc1(int s = 0) : a(s+100), b(s+101) {} + static int sd; + int a; + const int b; +}; + +bool operator==(const cc1 & da, const cc1 & db) +{ + return da.a == db.a && da.b == db.b; +} + +int cc1::sd = 102; + +class cc2_base +{ + public: + cc2_base(int s) : a(s+200) {} + int a; +}; + +class cc2 : public cc2_base +{ + public: + cc2(int s = 0) : cc2_base(s), b(s+201) {} + int b; +}; + +bool operator==(const cc2 & da, const cc2 & db) +{ + return da.a == db.a && da.b == db.b; +} + +class cc3_base +{ + public: + cc3_base(int s = 0) : a(s+300) {} + const int a; +}; + +class cc3 : virtual public cc3_base +{ + public: + cc3(int s = 0) : cc3_base(s), b(s+301) {} + int b; +}; + +bool operator==(const cc3 & da, const cc3 & db) +{ + return da.a == db.a && da.b == db.b; +} + +class cc4_base +{ + public: + cc4_base(int s) : a(s+400) {} + virtual ~cc4_base() {} + const int a; +}; + +class cc4 : public cc4_base +{ + public: + cc4(int s = 0) : cc4_base(s), b(s+401) {} + int b; +}; + +bool operator==(const cc4 & da, const cc4 & db) +{ + return da.a == db.a && da.b == db.b; +} + +class cc5 : public cc1, public cc3, public cc4 +{ + public: + cc5(int s = 0) : cc1(s), cc3(s), cc4(s) {} +}; + +bool operator==(const cc5 & da, const cc5 & db) +{ + return da.cc1::a == db.cc1::a && da.cc1::b == db.cc1::b && + da.cc3::a == db.cc3::a && da.cc3::b == db.cc3::b && + da.cc4::a == db.cc4::a && da.cc4::b == db.cc4::b; +} + +class cc6 +{ + public: + cc6(int s = 0) : a(s+600), b(a) {} + int a; + int & b; +}; + +bool operator==(const cc6 & da, const cc6 & db) +{ + return da.a == db.a && da.b == db.b; +} + +void test_mutant_relation() +{ + test_relation< mutant_relation_builder, char , double >( 'l', 2.5 ); + test_relation< mutant_relation_builder, double, char >( 2.5, 'r' ); + + test_relation<mutant_relation_builder, int , int >( 1 , 2 ); + + test_relation<mutant_relation_builder, std::string, int* >("left value",0); + + test_relation<mutant_relation_builder, cc1, cc2>(0,0); + test_relation<mutant_relation_builder, cc2, cc3>(0,0); + test_relation<mutant_relation_builder, cc3, cc4>(0,0); + test_relation<mutant_relation_builder, cc4, cc5>(0,0); +} + +int test_main( int, char* [] ) +{ + + // Test metadata correctness with untagged relation version + BOOST_BIMAP_CALL_TEST_STATIC_FUNCTION( tagged_static_test ); + + // Test metadata correctness with tagged relation version + BOOST_BIMAP_CALL_TEST_STATIC_FUNCTION( untagged_static_test ); + + // Test basic + test_mutant_relation(); + + return 0; +} + diff --git a/test/test_relation.hpp b/test/test_relation.hpp new file mode 100755 index 0000000..65da6b9 --- /dev/null +++ b/test/test_relation.hpp @@ -0,0 +1,191 @@ +// 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) + +#ifndef BOOST_BIMAP_TEST_TEST_RELATION_HPP +#define BOOST_BIMAP_TEST_TEST_RELATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// Boost.MPL +#include <boost/mpl/assert.hpp> +#include <boost/type_traits/is_same.hpp> + +// Boost.Bimap +#include <boost/bimap/detail/test/check_metadata.hpp> +#include <boost/bimap/tags/tagged.hpp> + +// Boost.Bimap.Relation +#include <boost/bimap/relation/member_at.hpp> +#include <boost/bimap/relation/support/get.hpp> +#include <boost/bimap/relation/support/pair_by.hpp> +#include <boost/bimap/relation/support/pair_type_by.hpp> +#include <boost/bimap/relation/support/value_type_of.hpp> +#include <boost/bimap/relation/support/member_with_tag.hpp> +#include <boost/bimap/relation/support/is_tag_of_member_at.hpp> + + + +template< class Relation > +void test_relation_with_default_tags(Relation & rel, + const typename Relation::left_value_type & lv, + const typename Relation::right_value_type & rv) +{ + + using namespace boost::bimaps::relation::support; + using namespace boost::bimaps::relation; + using namespace boost::bimaps::tags; + + // It must work with normal tags + + BOOST_CHECK( pair_by<member_at::left >(rel).first == lv ); + BOOST_CHECK( pair_by<member_at::left >(rel).second == rv ); + + BOOST_CHECK( pair_by<member_at::right>(rel).first == rv ); + BOOST_CHECK( pair_by<member_at::right>(rel).second == lv ); + + BOOST_CHECK( get<member_at::left >(rel) == rel.left ); + BOOST_CHECK( get<member_at::right>(rel) == rel.right ); + + BOOST_CHECK( + get<member_at::left >(pair_by<member_at::left >(rel)) == rel.left + ); + + BOOST_CHECK( + get<member_at::right>(pair_by<member_at::left >(rel)) == rel.right + ); + + BOOST_CHECK( + get<member_at::left >(pair_by<member_at::right>(rel)) == rel.left + ); + + BOOST_CHECK( + get<member_at::right>(pair_by<member_at::right>(rel)) == rel.right + ); + +} + +template< class Relation, class LeftTag, class RightTag > +void test_relation_with_user_tags(Relation & rel, + const typename Relation::left_value_type & lv, + const typename Relation::right_value_type & rv) +{ + + using namespace boost::bimaps::relation::support; + using namespace boost::bimaps::relation; + using namespace boost::bimaps::tags; + + // And with users ones + + BOOST_CHECK( pair_by<LeftTag >(rel).first == lv ); + BOOST_CHECK( pair_by<LeftTag >(rel).second == rv ); + + BOOST_CHECK( pair_by<RightTag>(rel).first == rv ); + BOOST_CHECK( pair_by<RightTag>(rel).second == lv ); + + BOOST_CHECK( get<LeftTag >(rel) == rel.left ); + BOOST_CHECK( get<RightTag>(rel) == rel.right ); + + BOOST_CHECK( get<LeftTag >(pair_by<LeftTag >(rel)) == rel.left ); + BOOST_CHECK( get<RightTag>(pair_by<LeftTag >(rel)) == rel.right ); + + BOOST_CHECK( get<LeftTag >(pair_by<RightTag>(rel)) == rel.left ); + BOOST_CHECK( get<RightTag>(pair_by<RightTag>(rel)) == rel.right ); + + //---------------------------------------------------------------- + + BOOST_CHECK( rel.template get<LeftTag >() == rel.left ); + BOOST_CHECK( rel.template get<RightTag>() == rel.right ); + + BOOST_CHECK( pair_by<LeftTag >(rel).template get<LeftTag >()== rel.left ); + BOOST_CHECK( pair_by<LeftTag >(rel).template get<RightTag>()== rel.right); + + BOOST_CHECK( pair_by<RightTag>(rel).template get<LeftTag >()== rel.left ); + BOOST_CHECK( pair_by<RightTag>(rel).template get<RightTag>()== rel.right); +} + +struct left_user_tag {}; +struct right_user_tag {}; + +template< class RelationBuilder, class LeftData, class RightData > +void test_relation(const LeftData & lv, const RightData & rv) +{ + using namespace boost::bimaps::relation::support; + using namespace boost::bimaps::relation; + using boost::bimaps::tags::tagged; + + // Untagged test + { + typedef typename RelationBuilder::template build + < + LeftData, + RightData + + >::type rel_type; + + rel_type rel( lv, rv ); + + test_relation_with_default_tags( rel, lv, rv); + } + + // Tagged test + { + typedef typename RelationBuilder::template build + < + tagged<LeftData , left_user_tag >, + tagged<RightData, right_user_tag > + + >::type rel_type; + + rel_type rel( lv, rv ); + + test_relation_with_default_tags(rel, lv, rv ); + test_relation_with_user_tags + < + rel_type, + left_user_tag,right_user_tag + + >(rel,lv,rv); + } + + // Default Constructor, Constructor from views and some operators + { +/* + typedef typename RelationBuilder::template build + < + tagged<LeftData , left_user_tag >, + tagged<RightData, right_user_tag > + + >::type rel_type; + + typedef typename pair_type_by< left_user_tag,rel_type>::type left_pair; + typedef typename pair_type_by<right_user_tag,rel_type>::type right_pair; + + rel_type rel_from_left ( left_pair(lv,rv) ); + rel_type rel_from_right( right_pair(rv,lv) ); + + BOOST_CHECK( rel_from_left == rel_from_right ); + BOOST_CHECK( rel_from_left == rel_type(lv,rv) ); + + rel_type rel; + + rel = rel_from_left; + + BOOST_CHECK( rel == rel_from_left ); +*/ + } + +} + +#endif // BOOST_BIMAP_TEST_TEST_RELATION_HPP diff --git a/test/test_structured_pair.cpp b/test/test_structured_pair.cpp new file mode 100755 index 0000000..776661c --- /dev/null +++ b/test/test_structured_pair.cpp @@ -0,0 +1,98 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +// std +#include <utility> +#include <cstddef> + +// Boost.Static_assert +#include <boost/static_assert.hpp> + +// Boost.Bimap +#include <boost/bimap/detail/test/check_metadata.hpp> + +#include <boost/bimap/relation/structured_pair.hpp> + + +BOOST_BIMAP_TEST_STATIC_FUNCTION( static_metadata_test ) +{ + using namespace boost::bimaps::relation; + + struct data_a { char data; }; + struct data_b { double data; }; + + typedef structured_pair + < + data_a, + data_b, + normal_layout + + > sp_ab; + + typedef structured_pair + < + data_b, + data_a, + mirror_layout + + > sp_ba; + + BOOST_BIMAP_CHECK_METADATA(sp_ab, first_type , data_a); + BOOST_BIMAP_CHECK_METADATA(sp_ab, second_type, data_b); + + BOOST_BIMAP_CHECK_METADATA(sp_ba, first_type , data_b); + BOOST_BIMAP_CHECK_METADATA(sp_ba, second_type, data_a); + +} + + +void test_basic() +{ + + using namespace boost::bimaps::relation; + + // Instanciate two pairs and test the storage alignmentDataData + + typedef structured_pair< short, double, normal_layout > pair_type; + typedef structured_pair< double, short, mirror_layout > mirror_type; + + pair_type pa( 2, 3.1416 ); + mirror_type pb( 3.1416, 2 ); + + BOOST_CHECK( pa.first == pb.second ); + BOOST_CHECK( pa.second == pb.first ); + +} + + +int test_main( int, char* [] ) +{ + + BOOST_BIMAP_CALL_TEST_STATIC_FUNCTION( static_are_storage_compatible_test ); + + BOOST_BIMAP_CALL_TEST_STATIC_FUNCTION( static_metadata_test ); + + test_basic(); + + return 0; +} + diff --git a/test/test_tagged.cpp b/test/test_tagged.cpp new file mode 100755 index 0000000..334fac8 --- /dev/null +++ b/test/test_tagged.cpp @@ -0,0 +1,108 @@ +// 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) + +// 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. So turn off the warnings. +#define _CRT_SECURE_NO_DEPRECATE +#define _SCL_SECURE_NO_DEPRECATE + +#include <boost/config.hpp> + +// Boost.Test +#include <boost/test/minimal.hpp> + +#include <boost/static_assert.hpp> + +// Boost.MPL +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/type_traits/add_const.hpp> + +// Boost.Bimap +#include <boost/bimap/detail/test/check_metadata.hpp> + +// Boost.Bimap.Tags +#include <boost/bimap/tags/tagged.hpp> +#include <boost/bimap/tags/support/default_tagged.hpp> +#include <boost/bimap/tags/support/is_tagged.hpp> +#include <boost/bimap/tags/support/overwrite_tagged.hpp> +#include <boost/bimap/tags/support/tag_of.hpp> +#include <boost/bimap/tags/support/value_type_of.hpp> +#include <boost/bimap/tags/support/apply_to_value_type.hpp> + + + + +BOOST_BIMAP_TEST_STATIC_FUNCTION( test_metafunctions ) +{ + using namespace boost::bimaps::tags::support; + using namespace boost::bimaps::tags; + using namespace boost::mpl::placeholders; + using namespace boost; + + struct tag {}; + struct value {}; + + // Test apply_to_value_type metafunction + // tagged<value,tag> ----(add_const<_>)----> tagged<value const,tag> + typedef tagged< value, tag > ttype; + typedef apply_to_value_type< add_const<_>,ttype>::type result; + typedef is_same<tagged<value const,tag>,result> compare; + BOOST_MPL_ASSERT_MSG(compare::value,tag,(result)); +} + +struct tag_a {}; +struct tag_b {}; +struct data {}; + +void test_function() +{ + + using namespace boost::bimaps::tags::support; + using namespace boost::bimaps::tags; + using boost::is_same; + + typedef tagged< data, tag_a > data_a; + typedef tagged< data, tag_b > data_b; + + BOOST_CHECK(( is_same< data_a::value_type , data >::value )); + BOOST_CHECK(( is_same< data_a::tag , tag_a >::value )); + + BOOST_CHECK(( + is_same< overwrite_tagged < data_a, tag_b >::type, data_b >::value + )); + BOOST_CHECK(( + is_same< default_tagged < data_a, tag_b >::type, data_a >::value + )); + BOOST_CHECK(( + is_same< default_tagged < data , tag_b >::type, data_b >::value + )); + + BOOST_CHECK(( is_tagged< data >::value == false )); + BOOST_CHECK(( is_tagged< data_a >::value == true )); + + BOOST_CHECK(( is_same< value_type_of<data_a>::type, data >::value )); + BOOST_CHECK(( is_same< tag_of <data_a>::type, tag_a >::value )); + +} + +int test_main( int, char* [] ) +{ + test_function(); + + // Test metanfunctions + BOOST_BIMAP_CALL_TEST_STATIC_FUNCTION( test_metafunctions ); + + return 0; +} +